1

I have the following enums, which can fill an ArrayList:

public enum RewardType {
    POINTS, MONEY, TOKENS, RANDOM;
}

and

public enum OfferType {
    GIFT, DISCOUNT, LOTTERY;
}

To convert the ArrayList to String I use this method:

public static String arrayListToString(ArrayList<Enum> arrayList) {
    String finalString = "";
    for (int i = 0; i < arrayList.size(); i++) {
        if (TextUtils.isEmpty(finalString)) {
            finalString = arrayList.get(i).name();
        } else {
            finalString = finalString + ", " + arrayList.get(i).name();
        }
    }
    return finalString;
}

and then I call it like this:

String rewardType = arrayListToString(mainModel.getRewardTypes()); 
//getRewardTypes returns an ArrayList<RewardType>

The problem is, that arrayListToString is called with ArrayList<Enum> and cannot be called with ArrayList<enum> parameter (which is the type of my classes). I also cannot create a class with type Enum. Since enum != Enum, how do I make arrayListToString method work with my enum classes?

2
  • 1
    Note that enum values are effectively constants, and according to the Java Naming Conventions, they should be written in UPPER_SNAKE_CASE. Also, you can leave out those empty constructors, since they're automatically created when you specify no other constructor. Commented Oct 17, 2018 at 20:43
  • Thank you. I didn't know that about the empty constructors. I am familiar with the naming conventions of Java, it's just that in my case, my server will expect Pascal Cased parameters. That's why the enums are named like that. Commented Oct 18, 2018 at 9:50

3 Answers 3

4

Since an enum X is implicitly a subclass of Enum<X>, change method declaration to:

public static String arrayListToString(ArrayList<? extends Enum> arrayList)

However, why do that?

The toString() of a enum returns the name() by default, so you don't need to call name(), which means you don't really care what's in the list anymore, so this much more generally useful method will work too:

public static String listToString(List<?> list) {
    StringBuilder buf = new StringBuilder();
    boolean first = true;
    for (Object value : list) {
        if (first)
            first = false;
        else
            buf.append(", ");
        buf.append(value);
    }
    return buf.toString();
}

It can be even simpler than that:

public static String toString(Iterable<?> iterable) {
    StringJoiner joiner = new StringJoiner(", ");
    for (Object value : iterable)
        joiner.add(String.valueOf(value));
    return joiner.toString();
}

Or with Java 8+ streams:

public static String toString(Collection<?> coll) {
    return coll.stream().map(Object::toString).collect(Collectors.joining(", "));
}
Sign up to request clarification or add additional context in comments.

Comments

3

Change the signature of arrayListToString() from this:

public static String arrayListToString(ArrayList<Enum> arrayList)

to this:

public static String arrayListToString(ArrayList<? extends Enum> arrayList)

The core concept at play is that a List<Integer> is not a List<Number>, even though an Integer is a Number. This makes sense, because you could put a Double into a List<Number> but you could not put a Double into a List<Integer>.

Similarly, a List<RewardType> is not a List<Enum>, even though a RewardType is an Enum.

A List<RewardType> is, though, a List<? extends Enum>. This is because we now are saying that the list is a list of some sort of enum, not a list of any enum ever.

2 Comments

Ben P. Better to use List< ? extends Enum<?> > arrayList since Enum is parametrized type.
I think if we want to be super technical, the best representation would be public static <E extends Enum<E>> String arrayListToString(ArrayList<E> arrayList), but I wanted to keep it simple.
1

As mentioned by Ben, You should use type generics to properly evaluate the type.

Aside from that, your method is slightly unoptimized. Consider using StringBuilder to prevent creation of garbage String objects, and remove redundant isEmpty check inside your loop:

public static <T extends Enum<?>> String enumListToString(List<T> list){
    if(list.size() < 1)
        return "";
    StringBuilder sb = new StringBuilder();
    sb.append(list.get(0).name());
    for (int i = 1; i < list.size(); i++) {
        sb.append(", ").append(list.get(i));
    }
    return sb.toString();
}

1 Comment

<T extends Enum<T>>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.