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

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

我知道这样做的几种方法,但我想知道什么是最好的方法(哪里“最好”意味着最清楚和/或最短,而不是最有效的。

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

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

样品溶液1:

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

示例解决scheme2 – 创build一个子列表:

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

样品溶液3:

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

这些专门处理第一个项目; 人们可以改为专门处理最后一个。

顺便提一句,下面是在Java 1.6中如何实现List toString(它从AbstractCollectioninheritance):

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

它会尽早退出循环,以避免最后一项之后的逗号。 顺便说一句:这是我第一次回忆看到“(这个collections)”; 这里的代码来挑起它:

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

我欢迎任何解决scheme,即使他们使用意外的库(regexp?); 以及除了Java以外的其他语言的解决scheme(例如我认为Python / Ruby有散布function – 这是如何实现的?)。

澄清 :按照库,我的意思是标准的Java库。 对于其他图书馆,我认为他们与其他语言,并有兴趣知道如何实施。

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

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

对于Java-8之前的版本:

另见#285523

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

自Java 8以来的更新:

使用StringJoiner :

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

使用stream和收集器 :

 return list.stream(). map(Object::toString). collect(Collectors.joining(",")).toString(); 
 org.apache.commons.lang3.StringUtils.join(list,","); 

Java 8提供了几种新的方法来做到这一点。

  • String上的join方法。
  • 收集Collectors类的streamjoining收集Collectors
  • StringJoiner类。

例:

 // Util method for strings and other char sequences List<String> strs = Arrays.asList("1", "2", "3"); String listStr1 = String.join(",", strs); // For any type using streams and collectors List<Object> objs = Arrays.asList(1, 2, 3); String listStr2 = objs.stream().map(i -> i.toString()).collect(joining(",", "[", "]")); // Using the new StringJoiner class StringJoiner joiner = new StringJoiner(", ", "[", "]"); joiner.setEmptyValue("<empty>"); for (Integer i : objs) { joiner.add(i.toString()); } String listStr3 = joiner.toString(); 

使用stream的方法假定import static java.util.stream.Collectors.joining;

 Joiner.on(",").join(myList) 

细木工

基于Java的List toString实现:

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

它使用这样的语法:

 List --> (Item , )* Item 

通过基于最后位置而不是基于第一位,可以使用相同的testing来检查跳转逗号以检查列表结束。 我觉得这个很漂亮,但是我不清楚。

如果你使用Spring框架,你可以用StringUtils来实现 :

 public static String arrayToDelimitedString(Object[] arr) public static String arrayToDelimitedString(Object[] arr, String delim) public static String collectionToCommaDelimitedString(Collection coll) public static String collectionToCommaDelimitedString(Collection coll, String delim) 
 String delimiter = ","; StringBuilder sb = new StringBuilder(); for (Item i : list) { sb.append(delimiter).append(i); } sb.toString().replaceFirst(delimiter, ""); 
 for(int i=0, length=list.size(); i<length; i++) result+=(i==0?"":", ") + list.get(i); 

foreach循环的一个选项是:

 StringBuilder sb = new StringBuilder(); for(String s:list){ if (sb.length()>0) sb.append(","); sb.append(s); } 

有一个很好的方法来实现这个使用Java 8:

 List<String> list = Arrays.asList(array); String joinedString = String.join(",", list); 
 StringBuffer result = new StringBuffer(); for(Iterator it=list.iterator; it.hasNext(); ) { if (result.length()>0) result.append(", "); result.append(it.next()); } 

更新 :如注释中提到的Dave Webb,如果列表中的第一项是空string,则可能不会产生正确的结果。

我通常这样做:

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

虽然我认为从现在开始,我会按照Java的实现来进行这个检查;)

如果您可以使用Groovy(在JVM上运行):

 def list = ['a', 'b', 'c', 'd'] println list.join(',') 

(从我这里复制粘贴我自己的答案。) 这里描述的许多解决scheme是有点超过,恕我直言,尤其是那些依赖外部库。 为了实现我一直使用的逗号分隔列表,有一个非常干净清晰的成语。 它依赖于条件(?)运算符:

编辑 :原始解决scheme正确,但不是最佳的根据意见。 尝试第二次:

 int[] array = {1, 2, 3}; StringBuilder builder = new StringBuilder(); for (int i = 0 ; i < array.length; i++) builder.append(i == 0 ? "" : ",").append(array[i]); 

在这里你可以看到4行代码,包括数组和StringBuilder的声明。

第二编辑 :如果你正在处理一个迭代器:

  List<Integer> list = Arrays.asList(1, 2, 3); StringBuilder builder = new StringBuilder(); for (Iterator it = list.iterator(); it.hasNext();) builder.append(it.next()).append(it.hasNext() ? "," : ""); 

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

我没有编译它,但应该工作(或接近工作)。

 public static <T> String toString(final List<T> list, final String delim) { final StringBuilder builder; builder = new StringBuilder(); for(final T item : list) { builder.append(item); builder.append(delim); } // kill the last delim builder.setLength(builder.length() - delim.length()); return (builder.toString()); } 

这很短,非常清楚,但给我的感觉匍匐恐怖。 适应不同的分隔符也是有点尴尬,特别是如果一个string(不是字符)。

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

启发: 最后迭代的增强循环在Java中

 StringBuffer sb = new StringBuffer(); for (int i = 0; i < myList.size(); i++) { if (i > 0) { sb.append(", "); } sb.append(myList.get(i)); } 

我有点喜欢这种方法,我之前在博客上find了这个方法。 不幸的是,我不记得博客的名称/url。

您可以创build一个如下所示的实用程序/助手类:

 private class Delimiter { private final String delimiter; private boolean first = true; public Delimiter(String delimiter) { this.delimiter = delimiter; } @Override public String toString() { if (first) { first = false; return ""; } return delimiter; } } 

使用助手类很简单,如下所示:

 StringBuilder sb = new StringBuilder(); Delimiter delimiter = new Delimiter(", "); for (String item : list) { sb.append(delimiter); sb.append(item); } 

由于您的分隔符是“,”您可以使用以下任一项:

 public class StringDelim { public static void removeBrackets(String string) { System.out.println(string.substring(1, string.length() - 1)); } public static void main(String... args) { // Array.toString() example String [] arr = {"Hi" , "My", "name", "is", "br3nt"}; String string = Arrays.toString(arr); removeBrackets(string); // List#toString() example List<String> list = new ArrayList<String>(); list.add("Hi"); list.add("My"); list.add("name"); list.add("is"); list.add("br3nt"); string = list.toString(); removeBrackets(string); // Map#values().toString() example Map<String, String> map = new LinkedHashMap<String, String>(); map.put("1", "Hi"); map.put("2", "My"); map.put("3", "name"); map.put("4", "is"); map.put("5", "br3nt"); System.out.println(map.values().toString()); removeBrackets(string); // Enum#toString() example EnumSet<Days> set = EnumSet.allOf(Days.class); string = set.toString(); removeBrackets(string); } public enum Days { MON("Monday"), TUE("Tuesday"), WED("Wednesday"), THU("Thursday"), FRI("Friday"), SAT("Saturday"), SUN("Sunday"); private final String day; Days(String day) {this.day = day;} public String toString() {return this.day;} } } 

如果你的分隔符是任何其他的,那么这是不会为你工作的。

我喜欢这个解决scheme:

 String delim = " - ", string = ""; for (String item : myCollection) string += delim + item; string = string.substring(delim.length()); 

我认为它也可以使用StringBuilder。

在Python中它很容易

“”,“join(yourlist)

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

String.Join(“,”,yourlistofstrings)

对不起,对Java不太确定,但是当我问你关于其他语言的时候,我就想起来了。 我相信在Java中会有类似的东西。

您也可以无条件添加分隔符string,并在循环后删除最后的额外分隔符。 然后,“如果列表是空的,然后返回这个string”在开始将允许您避免在最后的检查(因为您不能从空列表中删除字符)

所以问题是:

“给定一个循环和一个if,你认为将这些结合在一起最清楚的方法是什么?

 public static String join (List<String> list, String separator) { String listToString = ""; if (list == null || list.isEmpty()) { return listToString; } for (String element : list) { listToString += element + separator; } listToString = listToString.substring(0, separator.length()); return listToString; } 
 if (array.length>0) // edited in response Joachim's comment sb.append(array[i]); for (int i=1; i<array.length; i++) sb.append(",").append(array[i]); 

基于最清晰的方式来逗号分隔列表(爪哇)?

使用这个想法: 循环中的最后一个元素是否应该单独处理?

 public String toString(List<Item> items) { StringBuilder sb = new StringBuilder("["); for (Item item : items) { sb.append(item).append(", "); } if (sb.length() >= 2) { //looks cleaner in C# sb.Length -= 2; sb.setLength(sb.length() - 2); } sb.append("]"); return sb.toString(); } 

到目前为止,没有任何答案使用recursion…

 public class Main { public static String toString(List<String> list, char d) { int n = list.size(); if(n==0) return ""; return n > 1 ? Main.toString(list.subList(0, n - 1), d) + d + list.get(n - 1) : list.get(0); } public static void main(String[] args) { List<String> list = Arrays.asList(new String[]{"1","2","3"}); System.out.println(Main.toString(list, ',')); } } 

在我看来,这是最简单的阅读和理解:

 StringBuilder sb = new StringBuilder(); for(String string : strings) { sb.append(string).append(','); } sb.setLength(sb.length() - 1); String result = sb.toString(); 
 private String betweenComma(ArrayList<String> strings) { String united = ""; for (String string : strings) { united = united + "," + string; } return united.replaceFirst(",", ""); } 

方法

 String join(List<Object> collection, String delimiter){ StringBuilder stringBuilder = new StringBuilder(); int size = collection.size(); for (Object value : collection) { size --; if(size > 0){ stringBuilder.append(value).append(delimiter); } } return stringBuilder.toString(); } 

用法

给定[1,2,3]

 join(myArray, ",") // 1,2,3