【问题标题】:Most efficient way to convert Enum values into comma seperated String将枚举值转换为逗号分隔字符串的最有效方法
【发布时间】:2017-08-10 19:19:13
【问题描述】:

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

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

例如,我的方法返回123, 456,,但我更喜欢123, 456。如果我想返回 PROPERTY1, PROPERTY2,我可以轻松使用 Apache Commons 库 StringUtils.join(),但是,当我遍历 String 数组时,我需要通过调用 getValue 方法来降低一层。

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();
        }
    }
}

【问题讨论】:

  • 您应该使用.append(msgType.getValue()).append(", ") 而不是.append(msgType.getValue() + ", "),但我认为这实际上是题外话,因为我同意您应该只使用一次String 的答案,例如private static final 字段。
  • @Radiodef 这不是我的代码,对于更长的故事,我无法添加字符串字段,但我同意如果我能够修改那部分静态字符串将是执行此操作的最简单方法的枚举。

标签: java string enums


【解决方案1】:

我不会太担心效率。这样做很简单,只要您不以疯狂的方式进行操作,它就会很快。如果这是您代码中最重要的性能瓶颈,我会感到惊讶。

我会这样做:

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

如果你想缓存它;但这可能不会有很大的不同。

【讨论】:

  • 这是我觉得最好的东西,无所谓效率
  • 我完全理解这绝不是我的代码中的瓶颈,但我确实想确保我没有编写太多逻辑来确定这部分数组是否需要逗号与否。这个答案正是我想要的。
  • 您也可以直接从枚举值创建流:Arrays.stream(TypeEnum.values()).map(t -> t.value).collect(Collectors.joining(','))
  • @rzueger 是的,不知道我为什么不这样做 :) 已编辑。
【解决方案2】:

我看到的尾随逗号问题的常见模式类似于

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());

导致

A,B,C

将此与有关使用静态块初始化静态最终字段的答案结合起来可能会提供最佳性能。

【讨论】:

    【解决方案3】:

    最有效的代码是不运行的代码。这个答案永远不会改变,所以在创建枚举时运行你曾经拥有的代码。击中一次,每隔一次有人要求时返回计算的答案。从长远来看,这样做所节省的成本会大大超过担心如何具体构建字符串,因此请使用对您来说最清晰的任何内容(编写代码供人类阅读)。

    例如:

    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;
        }
    }
    

    【讨论】:

      【解决方案4】:

      如果你不得不在短时间内调用这个静态方法成千上万次,你可能会担心性能问题,你应该首先检查它是否有性能成本。
      JVM 在运行时执行许多优化。
      所以最后你可以编写更复杂的代码而没有附加价值。


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

      您可以使用一个静态初始化器来为静态字符串字段赋值。
      关于,这个字符,循环后去掉就好了。

      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;
      }
      

      【讨论】:

        【解决方案5】:

        我通常在枚举类本身上添加一个静态方法:

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

        所以我可以像String possibleValues = Animal.possibleValues();一样使用它

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-17
          • 1970-01-01
          • 1970-01-01
          • 2015-07-13
          • 2010-09-20
          • 2016-02-08
          • 2019-11-18
          • 2018-08-16
          相关资源
          最近更新 更多