DevelopingDeveloper
DevelopingDeveloper

Reputation: 913

Most efficient way to convert Enum values into comma seperated String

I have a java class in which I store an Enum.(shown at the bottom of this question) In this enum, I have a method named toCommaSeperatedString() who returns a comma separated String of the enums values. I am using a StringBuilder after reading some information on performance in this question here.

Is the way I am converting this enum's values into a commaSeperatedString the most efficient way of doing so, and if so, what would be the most efficient way to remove the extra comma at the last char of the String?

For example, my method returns 123, 456, however I would prefer 123, 456. If I wanted to return PROPERTY1, PROPERTY2 I could easily use Apache Commons library StringUtils.join(), however, I need to get one level lower by calling the getValue method when I am iterating through the String array.

public class TypeEnum {
    public enum validTypes {
        PROPERTY1("123"),
        PROPERTY2("456");

        private String value;

        validTypes(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public static boolean contains(String type) {
            for (validTypes msgType : validTypes.values()) {
                if (msgType.value.equals(type)) {
                    return true;
                }
            }
            return false;
        }

        public static String toCommaSeperatedString() {
            StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
            for(validTypes msgType : validTypes.values()) {
                commaSeperatedValidMsgTypes.append(msgType.getValue() + ", ");
            }
            return commaSeperatedValidMsgTypes.toString();
        }
    }
}

Upvotes: 3

Views: 12068

Answers (5)

Kent Munthe Caspersen
Kent Munthe Caspersen

Reputation: 6918

I usually add a static method on the enum class itself:

public enum Animal {
    CAT, DOG, LION;

    public static String possibleValues() {
        return Arrays.stream(Animal.values())
                .map(Enum::toString)
                .collect(Collectors.joining(","));
    }
}

So I can use it like String possibleValues = Animal.possibleValues();

Upvotes: 2

Andy Turner
Andy Turner

Reputation: 140318

I wouldn't worry much about efficiency. It's simple enough to do this that it will be fast, provided you don't do it in a crazy way. If this is the most significant performance bottleneck in your code, I would be amazed.

I'd do it something like this:

return Arrays.stream(TypeEnum.values())
      .map(t -> t.value)
      .collect(Collectors.joining(','));

Cache it if you want; but that's probably not going to make a huge difference.

Upvotes: 20

davidxxx
davidxxx

Reputation: 131356

If you have to call this static method thousand and thousand of times on a short period, you may worry about performance and you should first check that this has a performance cost.
The JVM performs at runtime many optimizations.
So finally you could write more complex code without added value.


Anyway, the actual thing that you should do is storing the String returned by toCommaSeperatedString and returned the same instance.
Enum are constant values. So caching them is not a problem.

You could use a static initializer that values a static String field.
About the , character, just remove it after the loop.

public enum validTypes {

PROPERTY1("123"), PROPERTY2("456");

private static String valueSeparatedByComma;

static {
    StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
    for (validTypes msgType : validTypes.values()) {
        commaSeperatedValidMsgTypes.append(msgType.getValue());
        commaSeperatedValidMsgTypes.append(",");
    }

    commaSeperatedValidMsgTypes.deleteCharAt
    (commaSeperatedValidMsgTypes.length()-1);
    valueSeparatedByComma = commaSeperatedValidMsgTypes.toString();
}

public static String getvalueSeparatedByComma() {
    return valueSeparatedByComma;
}

Upvotes: 2

Todd
Todd

Reputation: 31710

The most efficient code is code that doesn't run. This answer can't ever change, so run that code as you have it once when creating the enums. Take the hit once, return the calculated answer every other time somebody asks for it. The savings in doing that would be far greater in the long term over worrying about how specifically to construct the string, so use whatever is clearest to you (write code for humans to read).

For example:

public enum ValidTypes {

    PROPERTY1("123"),
    PROPERTY2("345");

    private final static String asString = calculateString();
    private final String value;

    private static String calculateString() {
        return // Do your work here.
    }

    ValidTypes(final String value) {
        this.value = value;
    }

    public static String toCommaSeparatedString() {
        return asString;
    }
}

Upvotes: 2

csunday95
csunday95

Reputation: 1319

A common pattern for the trailing comma problem I see is something like

String[] values = {"A", "B", "C"};
boolean is_first = true;
StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
for(String value : values){
    if(is_first){
        is_first = false;
    }
    else{
        commaSeperatedValidMsgTypes.append(',');
    }
    commaSeperatedValidMsgTypes.append(value);
}
System.out.println(commaSeperatedValidMsgTypes.toString());

which results in

A,B,C

Combining this with the answers about using a static block to initialize a static final field will probably give the best performance.

Upvotes: 2

Related Questions