【问题标题】:How to emit a comma-separated list?如何发出逗号分隔的列表?
【发布时间】:2011-07-12 14:04:18
【问题描述】:

这非常简单,但我已经看到了很多变体,而且我在其他地方看不到我自己的练习。给定:

Iterable<String> strings;

创建一个包含所有字符串的字符串,用逗号分隔。

【问题讨论】:

    标签: java


    【解决方案1】:

    Java-8 版本

    幸运的是,Java 8 终于有了一个标准的方法来做到这一点:

    String string = StreamSupport.stream(strings.spliterator(), false)
                                 .collect(Collectors.joining(", "));
    

    不幸的是,没有比Iterable to a Stream (yet) 更简单的方法了

    Pre Java-8 版本

    使用

    org.apache.commons.lang.StringUtils.join(Iterator iterator, String separator)
    

    来自

    http://commons.apache.org/lang/

    如果你想自己做,我有时会做

    StringBuilder sb = new StringBuilder();
    String separator = "";
    for (String string : iterable) {
      sb.append(separator);
      sb.append(string);
      separator = ", ";
    }
    

    【讨论】:

      【解决方案2】:
      final StringBuilder sb = new StringBuilder();
      final Iterator<String> it = iterable.iterator();
      if(it.hasNext()){
        sb.append(it.next());
        while(it.hasNext()){
          sb.append(',').append(it.next());
        }
      }
      return sb.toString();
      

      当然我更喜欢使用Guava的版本

      String joined = Joiner.on(',').join(iterable);
      

      (说句公道话:我之前问过a very similar question

      【讨论】:

      • +1,用于使用像 StringBuilder 这样的简单构造,并且不依赖于实现。
      • FWIW,我更喜欢 Lukas 更简单的手工实现,因为它很简单(这是我使用的),但更喜欢 Guava 的 Joiner 而不是 Apache StringUtils。
      • @Ed 我只是不喜欢重新分配变量。我尽可能将它们设为最终版本(现在添加最终版本)。
      • @Sean - 为什么 - 为了清楚起见?如果您最终确定其他所有内容,并且在中间有一个非最终的String separator = "";,它强烈暗示它将从非最终值和空字符串值发生变化。还是您只是想尽可能“实用”?
      • @Ed。 Guava 有一些不错的功能。我也可能会切换,因为 commons 有点生疏,还有泛型......
      【解决方案3】:

      只是为了好玩,递归实现:

      public static void main(String[] args) {
          System.out.println(buildCsv(Arrays.asList(new String[] {"one", "two", "three"}).iterator()));
      }
      
      private static String buildCsv(Iterator<String> iterator) {
          return iterator.hasNext() ? iterator.next() + (iterator.hasNext() ? "," : "") + buildCsv(iterator) : "";
      }
      

      【讨论】:

        【解决方案4】:

        这是我在大多数项目中包含的 join 函数:

        public static String join(Iterable<? extends Object> iterable, String delimiter) {
            return join(iterable, delimiter, "", "");
        }
        
        public static String join(Iterable<? extends Object> iterable, String delimiter,
                String prepend, String append) {
        
            StringBuilder buffer = new StringBuilder();
            Iterator<?> iterator = iterable.iterator();
            boolean hasNext = iterator.hasNext();
        
            while (hasNext) {
        
                buffer.append(prepend);
                buffer.append(String.valueOf(iterator.next()));
                buffer.append(append);
        
                if (iterator.hasNext()) {
                    buffer.append(delimiter);
                } else {
                    hasNext = false;
                }
            }
        
            return buffer.toString();
        }
        

        一些例子:

        String[] list = { "hello", "mellow", "jello" };
        
        Util.join(list, ",");                    // "hello,mellow,jello"
        Util.join(list, ", and ");               // "hello, and mellow, and jello"
        Util.join(list, "&", "x=", "1");         // "x=hello1&x=mellow1&x=jello1"
        Util.join(list, " OR ", "(Title:", ")"); // "(Title:hello) OR (Title:mellow) OR (Title:jello)"
        

        【讨论】:

        • 为什么不使用各种org.apache.commons.lang.StringUtils.join()之一
        • @Lukas,我认为这是因为一些开发人员更喜欢推出自己的实用方法,而不是依赖第三方库。
        • @Lukas,我考虑过,但 StringUtils.join 没有(现在仍然没有)我需要的前置/附加功能。
        • @epalm:好的,是的。我没有注意到你的第三个和第四个例子。这是有道理的
        • @Sean,或者你在四个项目前自己写的那个!
        【解决方案5】:

        如果您使用 Java 8 或更高版本,则可以使用String.join

        Iterable<String> strings = Arrays.asList("a", "b", "c");
        String result = String.join(",", strings);
        Assert.assertEquals("a,b,c", result);
        

        如果您使用Eclipse Collections,您可以使用Iterate 实用程序类,它适用于任何Iterable

        Iterable<String> strings = Arrays.asList("a", "b", "c");
        String result = Iterate.makeString(strings, ",");
        Assert.assertEquals("a,b,c", result);
        

        Eclipse Collections 7.x 适用于 Java 5 或更高版本。 Eclipse Collections 8.x-9.x 适用于 Java 8 或更高版本。

        注意:我是 Eclipse Collections 的提交者。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-07-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-31
          • 2021-07-20
          相关资源
          最近更新 更多