Java 用逗号分隔列表的最简单方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/668952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:40:15  来源:igfitidea点击:

The simplest way to comma-delimit a list?

javapretty-print

提问by 13ren

What is the clearest way to comma-delimit a list in Java?

在 Java 中用逗号分隔列表的最清晰方法是什么?

I know several ways of doing it, but I'm wondering what the best way is (where "best" means clearest and/or shortest, not the most efficient.

我知道几种方法,但我想知道最好的方法是什么(“最好”的意思是最清晰和/或最短的,而不是最有效的。

I have a list and I want to loop over it, printing each value. I want to print a comma between each item, but not after the last one (nor before the first one).

我有一个列表,我想遍历它,打印每个值。我想在每个项目之间打印一个逗号,但不是在最后一个之后(也不在第一个之前)。

List --> Item ( , Item ) *
List --> ( Item , ) * Item

Sample solution 1:

示例解决方案 1:

boolean isFirst = true;
for (Item i : list) {
  if (isFirst) {
    System.out.print(i);        // no comma
    isFirst = false;
  } else {
    System.out.print(", "+i);   // comma
  }
}

Sample solution 2 - create a sublist:

示例解决方案 2 - 创建子列表:

if (list.size()>0) {
  System.out.print(list.get(0));   // no comma
  List theRest = list.subList(1, list.size());
  for (Item i : theRest) {
    System.out.print(", "+i);   // comma
  }
}

Sample solution 3:

示例解决方案 3:

  Iterator<Item> i = list.iterator();
  if (i.hasNext()) {
    System.out.print(i.next());
    while (i.hasNext())
      System.out.print(", "+i.next());
  }

These treat the first item specially; one could instead treat the last one specially.

这些特别对待第一项;可以改为特别对待最后一个。

Incidentally, here is how ListtoStringisimplemented (it's inherited from AbstractCollection), in Java 1.6:

顺便说一句,这里是如何ListtoString实现的(它是从继承AbstractCollection),在Java 1.6:

public String toString() {
    Iterator<E> i = iterator();
    if (! i.hasNext())
        return "[]";

    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = i.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! i.hasNext())
            return sb.append(']').toString();
        sb.append(", ");
    }
}

It exits the loop early to avoid the comma after the last item. BTW: this is the first time I recall seeing "(this Collection)"; here's code to provoke it:

它提前退出循环以避免在最后一项之后出现逗号。BTW:这是我第一次记得看到“(this Collection)”;这是激发它的代码:

List l = new LinkedList();
l.add(l);
System.out.println(l);

I welcome any solution, even if they use unexpected libraries (regexp?); and also solutions in languages other than Java (e.g. I think Python/Ruby have an interspersefunction - how is thatimplemented?).

我欢迎任何解决方案,即使他们使用了意外的库(regexp?);在Java以外的语言也解决方案(例如,我认为Python / Ruby的有点缀作用-怎么?实现)。

Clarification: by libraries, I mean the standard Java libraries. For other libraries, I consider them with other languages, and interested to know how they're implemented.

说明:通过库,我指的是标准 Java 库。对于其他库,我考虑将它们与其他语言一起使用,并且很想知道它们是如何实现的。

EDITtoolkit mentioned a similar question: Last iteration of enhanced for loop in java

编辑工具包提到了一个类似的问题:Java 中增强的 for 循环的最后一次迭代

And another: Does the last element in a loop deserve a separate treatment?

另一个: 循环中的最后一个元素是否值得单独处理?

采纳答案by toolkit

Java 8 and later

Java 8 及更高版本

Using StringJoinerclass :

使用StringJoiner类:

StringJoiner joiner = new StringJoiner(",");
for (Item item : list) {
    joiner.add(item.toString());
}
return joiner.toString();

Using Stream, and Collectors:

使用Stream, 和Collectors

return list.stream().
       map(Object::toString).
       collect(Collectors.joining(",")).toString();

Java 7 and earlier

Java 7 及更早版本

See also #285523

另见#285523

String delim = "";
for (Item i : list) {
    sb.append(delim).append(i);
    delim = ",";
}

回答by tarn

In Python its easy

在 Python 中很容易

",".join( yourlist )

",".join( yourlist )

In C# there is a static method on the String class

在 C# 中,String 类有一个静态方法

String.Join(",", yourlistofstrings)

String.Join(",", yourlistofstrings)

Sorry, not sure about Java but thought I'd pipe up as you asked about other languages. I'm sure there would be something similar in Java.

抱歉,不确定 Java,但我想我会在您询问其他语言时插嘴。我相信 Java 中也会有类似的东西。

回答by cherouvim

StringBuffer result = new StringBuffer();
for(Iterator it=list.iterator; it.hasNext(); ) {
  if (result.length()>0)
    result.append(", ");
  result.append(it.next());
}

Update: As Dave Webb mentioned in the comments this may not produce correct results if the first items in the list are empty strings.

更新:正如 Dave Webb 在评论中提到的,如果列表中的第一项是空字符串,这可能不会产生正确的结果。

回答by sfossen

I usually use something similar to version 3. It works well c/c++/bash/... :P

我通常使用类似于版本 3 的东西。它运行良好 c/c++/bash/... :P

回答by cherouvim

for(int i=0, length=list.size(); i<length; i++)
  result+=(i==0?"":", ") + list.get(i);

回答by trunkc

org.apache.commons.lang3.StringUtils.join(list,",");

回答by Thorbj?rn Ravn Andersen

You can also unconditionally add the delimiter string, and after the loop remove the extra delimiter at the end. Then an "if list is empty then return this string" at the beginning will allow you to avoid the check at the end (as you cannot remove characters from an empty list)

您也可以无条件地添加分隔符字符串,并在循环后删除末尾的额外分隔符。然后在开头的“如果列表为空则返回此字符串”将允许您避免在末尾进行检查(因为您无法从空列表中删除字符)

So the question really is:

所以问题真的是:

"Given a loop and an if, what do you think is the clearest way to have these together?"

“给定一个循环和一个 if,你认为将它们放在一起最清晰的方法是什么?”

回答by 13ren

Based on Java's List toString implementation:

基于 Java 的 List toString 实现:

Iterator i = list.iterator();
for (;;) {
  sb.append(i.next());
  if (! i.hasNext()) break;
  ab.append(", ");
}

It uses a grammar like this:

它使用这样的语法:

List --> (Item , )* Item

By being last-based instead of first-based, it can check for skip-comma with the same test to check for end-of-list. I think this one is very elegant, but I'm not sure about clarity.

通过基于最后而不是基于第一,它可以使用相同的测试检查跳过逗号以检查列表结尾。我认为这个非常优雅,但我不确定清晰度。

回答by Alex Marshall

I usually do this :

我通常这样做:

StringBuffer sb = new StringBuffer();
Iterator it = myList.iterator();
if (it.hasNext()) { sb.append(it.next().toString()); }
while (it.hasNext()) { sb.append(",").append(it.next().toString()); }

Though I think I'll to a this check from now on as per the Java implementation ;)

虽然我想我会从现在开始按照 Java 实现进行检查;)

回答by 13ren

This is very short, very clear, but gives my sensibilities the creeping horrors. It's also a bit awkward to adapt to different delimiters, especially if a String (not char).

这很短,很清楚,但给我的感觉带来了令人毛骨悚然的恐惧。适应不同的分隔符也有点尴尬,特别是如果是字符串(不是字符)。

for (Item i : list)
  sb.append(',').append(i);
if (sb.charAt(0)==',') sb.deleteCharAt(0);

Inspired by: Last iteration of enhanced for loop in java

灵感来源:Java 中增强的 for 循环的最后一次迭代