简体   繁体   中英

Map 2 enums in java

I have 2 enums like below.

enum enum1 {
    TEST_1("name_1","name 1"),  
    TEST_2("name_2","name 2");  

    private String name;  
    private String description;  

    public String getName() {  
        return name;  
    }  

    public String getDescription() {  
        return description;  
    }  
}  

enum enum2 {
    TEST_ENUM_1("name_1",1),  
    TEST_ENUM_2("name_2",2);  

    private String name;  
    private int code;  

    public String getCode(){  
        return code;  
    }  

    public int getName(){  
        return name;  
    }
}

How can I map the same names in 2 enums and get message from enum 1 and code from enum 2?

enum enum3 {
private enum1 e1;
private enum2 e2;
...
}

perhaps?

You can create method in enum to take name and return enum itself. Below is sample for enum2, you can do same for enum1.

 public static enum2 get( String name )
        {
            for ( enum2  sp : values() )
            {
                if ( sp.getName() .equals( name) )
                {
                    return sp;
                }
            }
            throw new AssertionError( "Invalid name " + name );
        }

and then

String enum1Message = enum1.get("name_1").getDescription();
String enum2Code = enum2.get("name_1").getCode();

Offcourse, you can see the problem with duplication here.

I don't think you really want to define two enums if they have a dependency on their name value. If you still want to do it though, you could put pairs of enum-instances in a Map with the key being their name:

public static void main() {
    Map<String, Tuple<enum1, enum2>> map = new HashMap<>();
    map.put("name_1", new Tuple<>(enum1.TEST_1, enum2.TEST_ENUM_1));
    map.put("name_2", new Tuple<>(enum1.TEST_2, enum2.TEST_ENUM_2));
}

Where Tuple is a simple tuple:

class Tuple<T1, T2> {
    T1 _1;
    T2 _2;
    public Tuple(T1 first, T2 second){
        this._1 = first;
        this._2 = second;
    }
}

Don't completely understand what you are trying to do, but my understanding is that you want to get the description and code from enum1 and enum2 for all matching names. In which case you could do something like this.

for(enum1 e1 :enum1.values())
{
    for(enum2 e2 : enum2.values())
    {
        if(e1.getName().equals(e2.getName()))
        {
            //Do what you will with description and code (prints out in this case)
            System.out.println(e1.getDescription() + " " + e2.getCode());
        }
    }
}

Definitely more efficient ways of doing this however.

So... It is very ugly but looks like probably solution:

enum FirstEnum {

    FIRST("name_1", "name 1"),
    SECOND("name_2", "name 2");

    FirstEnum(String name, String description) {
        replaceName(name);
        this.name = name;
        this.description = description;
    }
    private String name;
    private String description;

    private void replaceName(String newName) {
        try {
            Field fieldName = getClass().getSuperclass().getDeclaredField("name");
            fieldName.setAccessible(true);
            fieldName.set(this, newName);
            fieldName.setAccessible(false);
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    @Override
    public String toString() {
        return getName();
    }
}

enum SecondEnum {

    FIRST("name_1", 1),
    SECOND("name_2", 2);

    SecondEnum(String name, Integer code) {
        replaceName(name);
        this.name = name;
        this.code = code;
    }
    private String name;
    private Integer code;

    private void replaceName(String newName) {
        try {
            Field fieldName = getClass().getSuperclass().getDeclaredField("name");
            fieldName.setAccessible(true);
            fieldName.set(this, newName);
            fieldName.setAccessible(false);
        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public Integer getCode() {
        return code;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return getName();
    }
}

In code above "private void replaceName(String newName)" replaces FIRST and SECOND in enums with name value. Then you can construct map with required data. But... Are you really neeed it?)

Map<String, Integer> result = new HashMap<String, Integer>();
for (Object key : FirstEnum.values()) {
    String keyString = String.valueOf(key);
    result.put(keyString, SecondEnum.valueOf(keyString).getCode());
}

Why not just do this?

enum enum1 {
    TEST_1(enum2.TEST_ENUM_1, "name 1"),
    TEST_2(enum2.TEST_ENUM_2, "name 2");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM