Iterate over enums (the class objects) with shared interface in Java

Viewed 114

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).

2 Answers

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.

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?

Related