关于java:将Enum值转换为逗号分隔String的最有效方法

Most efficient way to convert Enum values into comma seperated String

我有一个Java类,我在这个枚举中存储一个枚举(在这个问题的底部显示),我有一个名为toCaseSePrPrimeString()的方法,它返回枚举值的逗号分隔字符串。在阅读了关于这个问题的性能的一些信息之后,我使用了一个StringBuilder。

我将此枚举的值转换为commaseperatedString的方式是最有效的方式吗?如果是,删除字符串最后一个字符处多余逗号的最有效方式是什么?

例如,我的方法返回123, 456,,但是我更喜欢123, 456。如果我想返回PROPERTY1, PROPERTY2,我可以很容易地使用apache commons library stringutils.join(),但是,当我遍历字符串数组时,我需要通过调用getValue方法来降低一个级别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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();
        }
    }
}


我不太担心效率。这样做很简单,只要你不疯狂,它就会很快完成。如果这是代码中最重要的性能瓶颈,我会惊讶的。

我会这样做:

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

如果你想的话,把它存起来;但这可能不会有什么大的区别。


我看到的尾随逗号问题的一个常见模式是

1
2
3
4
5
6
7
8
9
10
11
12
13
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());

结果是

1
A,B,C

结合使用静态块初始化静态最终字段的答案,可能会获得最佳性能。


如果您必须在短时间内调用这个静态方法一千次,那么您可能会担心性能问题,应该首先检查它是否具有性能成本。JVM在运行时执行许多优化。最后,您可以编写更复杂的代码而不需要附加值。

无论如何,您应该做的实际事情是存储由toCommaSeperatedString返回的String,并返回相同的实例。枚举是常量值。所以缓存它们不是问题。

可以使用静态初始值设定项来为静态字符串字段赋值。关于,字符,只需在循环后删除它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}

最有效的代码是不运行的代码。这个答案永远不会改变,所以在创建枚举时,请按您拥有的代码运行一次。打一次,每隔一次有人要求的时候就返回计算出的答案。从长远来看,这样做的节省要比担心如何具体地构造字符串大得多,所以使用您最清楚的东西(编写代码供人类阅读)。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
    }
}