Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid duplicate enum values in java?

Tags:

java

enums

I have enum which corresponds to encodings.I need to check that enum don't have repeating number values for encodings.

public enum EncodingsEnum
{

ISO8859_1("ISO-8859-1",0), ISO8859_2("ISO-8859-2",1),
    ISO8859_3("ISO-8859-3",2), ISO8859_4("ISO-8859-4",3),
    ISO8859_5("ISO-8859-5",4), ISO8859_6("ISO-8859-6",5),
    ISO8859_7("ISO-8859-7",6), ISO8859_8("ISO-8859-8",7),
    ISO8859_9("ISO-8859-9",8), ISO8859_11("ISO-8859-11",9),
    ISO8859_13("ISO-8859-13",10),ISO8859_15("ISO-8859-15",11),
    UTF_8("UTF-8",11);

    public static final int ENCODINGS_COUNT = EncodingsEnum.values().length;
    private final String encodingName;
    private final int encodingNumber;

    EncodingsEnum(final String encodingName,int encodingNumber)
    {
        ReferenceChecker.checkReferenceNotNull(encodingName);

        this.encodingName = encodingName;
        this.encodingNumber = encodingNumber;
    }

    public static String getEncodingNameByNumber(int number)
    {
        for(EncodingsEnum encoding : EncodingsEnum.values())
        {
            if(encoding.encodingNumber == number)
            {
                return encoding.getEncodingName();
            }
        }
        throw new RuntimeException("Encoding with this number isn't supported:" + number);

    }

    public static int getEncodingNumberByName(final String name)
    {
        for(EncodingsEnum encoding : EncodingsEnum.values())
        {
            if(encoding.encodingName.equals(name))
            {
                return encoding.getEncodingNumber();
            }
        }
        throw new RuntimeException("Encoding with this name isn't supported:" + name);
    }

    public String getEncodingName()
    {
        return this.encodingName;
    }

    public int getEncodingNumber()
    {
        return this.encodingNumber;
    }
}

There is a problem that I can create encoding with the same number as one of the existing encodings,so I need to check that enum contains element with this number and throw exception.But I dont know how to do that.Any idea?Thanks.

like image 286
Avershin Dmitry Avatar asked Jul 13 '12 09:07

Avershin Dmitry


People also ask

How to get enum value by label in Java?

Java provides a valueOf (String) method for all enum types. Thus, we can always get an enum value based on the declared name: However, we may want to look up an enum value by our label field as well. To do that, we can add a static method: The static valueOfLabel () method iterates the Element values until it finds a match.

Should enums have duplicate values (code analysis)?

CA1069: Enums should not have duplicate values (code analysis) - .NET | Microsoft Docs Skip to main content This browser is no longer supported. Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support. Download Microsoft Edge More info Table of contents Exit focus mode

What can we do with enums in Java?

Although the enum type has special behavior in Java, we can add constructors, fields and methods as we do with other classes. Because of this, we can enhance our enum to include the values we need.

How can I avoid duplicate values in HashMap in Java?

How can I avoid duplicate values in HashMap in Java? 1.) You can use Set<> as a value. 2.) You can use containsKeys (key) & containValues (value) methods 3.) You can override equals () & hashcode () method for value. Put your own logic in program, if can’t then I’ll share you code. But try first, start from 3rd. Was this worth your time?


2 Answers

This shouldn't be checked at runtime: it would be too late. Add a unit test that iterates through the enum values, and check that they all have a different number. And make sure to always execute the unit tests, and check that they pass, before generating a new version of your application/library.

@Test
public void encodingNumbersMustBeUnique() {
    Set<Integer> numbers = new HashSet<Integer>();
    for (EncodingsEnum e : EncodingsEnum.values()) {
        assertFalse(numbers.contains(e.getEncodingNumber()));
        numbers.add(e.getEncodingNumber());
    }
}
like image 198
JB Nizet Avatar answered Sep 27 '22 18:09

JB Nizet


In the constructor you can iterate through the encodingNumbers of the enum and throw an exception if you find a duplicate. Something like this:

public boolean isPresent(String type){
            ClassType[] typeArray = ClassType.values();
            for(ClassType cType: typeArray){
                if(cType.absoluteName/*this is some private field of the class*/.equalsIgnoreCase(type)){
                    return true;
                }
            }
            return false;
        }

Put the above check just before you are assigning number and name in your constructor. If the check returns true, throw an exception else not.

like image 37
Shankhoneer Chakrovarty Avatar answered Sep 27 '22 16:09

Shankhoneer Chakrovarty