2

I have several enums that implement the interface Word. I want to generate a list of all of the values of these enums.

The way I am currently doing this is:

 public Set<Word> allWords() { Set<Word> dictionary = new HashSet<>(); dictionary.addAll(Arrays.asList(Article.values())); dictionary.addAll(Arrays.asList(Conjunction.values())); dictionary.addAll(Arrays.asList(Verb.values())); // And so on... return dictionary; } 

Is there a way to iterate over these enums? I imagine it would involve creating a list of Class objects, but I'm not sure how to convert that back the the actual values.

In case it's relevant, Word and each of the enums are in the same package (lexicon).

7
  • Why do you ask how iterate? You have code that built a set of Word. Just loop that set. Commented Dec 9, 2021 at 20:27
  • @roccobaroccoSC The interface contains a method (getWord) that each enum implements, which allows the retrieval of the string literal it represents, as some of them include illegal characters for an enum (such as "and/or"). The question is about whether I can use reflection to get a list of all the words of every type. I could simply move all of the enums to one "Word" class, and have an attribute representing whether it is a particular type, but I would much rather keep the logical groups separate. Commented Dec 9, 2021 at 20:27
  • Your question and comment is confusing. Perhaps you should describe your overall goal. Commented Dec 9, 2021 at 20:32
  • 1
    Small suggestion: Instead of using Arrays.asList(Article.values()), use EnumSet.allOf(Article.class). Commented Dec 10, 2021 at 6:33
  • 1
    If you want to look up a Word by string, just build a Map<String,Word>. It’s not clear why you claim you had “to check against each of the separate enum classes” when the code you’ve posted yourself proves that you don’t have to. Commented Dec 10, 2021 at 10:29

2 Answers 2

2

Reflection only makes sense if you do not already know the enums (i.e. you have to discover the enums in a package).

If you already know the enums, then a variation of your code is reasonable.

For example:

public List<Word> allWords() { List<Word> returnValue = new LinkedList<>(); returnValue.addAll(Arrays.asList(Article.values())); returnValue.addAll(Arrays.asList(Conjunction.values())); returnValue.addAll(Arrays.asList(Verb.values())); // And so on... return returnValue; } 

I suggest a List. because the Set will remove duplicates by name.

Edit: My List suggestion now seems unnecessary.

Edit2: Per comment, set is not as bad as I want to believe it. Still, you are using the collection as a "list of junk", I suggest List is the better choice.

Sign up to request clarification or add additional context in comments.

2 Comments

That's fair, I was just hoping for a simpler way to iterate over known class methods.
A Set rejects duplicates by equality, not “by name”. All enum constants have an equality defined by their distinct identity, regardless of their name.
1

You can iterate through the values using Stream API or plain for-loop

allWords() .stream() .forEach(System.out::println); // or Stream.of(Article.values()) .map(Article::text) // .text is a method from your interface Word .forEach(System.out::println); 

but honestly, you are trying to do something strange with these enums.

What is your task? Why you are trying to solve it via enums at all?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.