user13111868
user13111868

Reputation:

How to compare two enums?

I have two enums:

public enum UserType {
    USER,
    EMPLOYER

}
public enum UserDetails {
    USER,
    EMPLOYER
}

I try to compare this by this:

if(UserType.USER.equals(UserDetails.USER)){
    return true;
}

but i can't because, my equals() throw me this:

equals() between objects of inconvertible types 'UserType' and 'UserDetails'

so, how can I compare two values from two diffrent enums?

Upvotes: 4

Views: 8095

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 340350

Different types

The enum in Java is a class, albeit a slightly special kind of class. A class defines a type.

Unless related by inheritance or by interface, different types cannot be compared for equality. A String cannot be equal to a LocalDate which cannot be equal to a DataSource.

Likewise, an object of enum UserType cannot be equal to an object of enum UserDetails. Apples to oranges, not equal by definition. So, your Question is senseless, technically.

The fact that some enum classes happen to share names on some of their constants has no meaning, it is just coincidence that your two enums share the name USER or EMPLOYER. The enum Month bundled with Java defines a constant named APRIL. I might define another enum with an object also named APRIL. But that does not make them equal.

Asking this question suggests that you have a problem with your design. Perhaps you should post another Question on that design issue if it has but already been addressed on Stack Overflow. As commented by Kayaman, your Question seems like an XY Problem.

The other Answers suggesting you:

  • Compare the strings of the names of the enum constants.
  • Compare the ordinal position of the constants within the enum definition.

…are misguided. Those approaches violate the purpose of enums in Java, which is to provide a type-safe identity of certain values known at compile-time.

  • If you are comparing the names of the constants, then you might as well be using mere String objects rather than enums.
  • If you are comparing ordinal numbers, then you might as well be using mere integer numbers rather than enums.

Both cases are fragile, resulting in runtime failures if you make a change to one enum without matching the other. And in both cases you have lost the usefulness of the enum, transmogrifying the enum into a confusing level of indirection for a string or int.

Upvotes: 6

Alex
Alex

Reputation: 866

Try to compare their names

if(UserType.USER.name().equals(UserDetails.USER.name())){
    return true;
}

Reading other answers i've decided to give more extended answer. I have to agree thats such solution is not good enough, cause it's not about enums - it's about string comparing. Enums may be changed and everythig will not work properly. Ok. I think that there could be better solutions - of course:

  • Use only one type of enum - it's perfect i think(but author has different enums)
  • Compare names of enums - well it's working but realy not "clever" use of enum
  • Make some mapping - why not - but its hard linking of two different enums and it is not good enough
enum UserType {
   USER,
   EMPLOYER;

   public boolean isLike(UserDetails details) {
       switch (this) {
           case USER:
               return details == UserDetails.USER;
           case EMPLOYER:
               return details == UserDetails.EMPLOYER;
       }
       return false;
   }
}

enum UserDetails {
   USER,
   EMPLOYER;
}

if(UserType.USER.isLike(UserDetails.USER)){
           // do something
}

So we see that's there is no better decision than rewrite the code and make only one enum. But everything depends on the issue:

  • We don't know why there are two enums - perhaps author supporting legacy code
  • We don't know why author has to compare these different enums
  • Does proposed decision solve this concrete problem - yes. Is it good - no

Upvotes: 5

Related Questions