146

有没有办法确定循环是否最后一次迭代。我的代码看起来像这样:

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();

for(int i : array)
{
    builder.append("" + i);
    if(!lastiteration)
        builder.append(",");
}

现在问题是我不想在最后一次迭代中附加逗号。现在有办法确定它是最后一次迭代,还是我坚持使用 for 循环或使用外部计数器来跟踪。

4

22 回答 22

224

另一种选择是在附加 i 之前附加逗号,而不是在第一次迭代中。(顺便说一下,请不要使用"" + i- 你真的不想在这里连接,而且 StringBuilder 有一个非常好的 append(int) 重载。)

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();

for (int i : array) {
    if (builder.length() != 0) {
        builder.append(",");
    }
    builder.append(i);
}

这样做的好处是它可以与任何东西一起使用Iterable——你不能总是索引东西。(当您真正使用 StringBuilder 时,“添加逗号然后在末尾删除它”是一个不错的建议 - 但它不适用于写入流之类的事情。不过,这可能是解决这个确切问题的最佳方法。 )

于 2008-11-12T22:06:01.480 回答
147

另一种方法:

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

更新:对于 Java 8,您现在拥有收集器

于 2008-11-12T22:30:04.957 回答
39

总是追加可能更容易。然后,当您完成循环后,只需删除最后一个字符。这样也少了很多条件。

您可以将StringBuilder'sdeleteCharAt(int index)与索引一起使用length() - 1

于 2008-11-12T22:01:49.273 回答
33

也许您为工作使用了错误的工具。

这比你正在做的更手动,但它在某种程度上更优雅,如果不是有点“老派”

 StringBuffer buffer = new StringBuffer();
 Iterator iter = s.iterator();
 while (iter.hasNext()) {
      buffer.append(iter.next());
      if (iter.hasNext()) {
            buffer.append(delimiter);
      }
 }
于 2008-11-12T22:13:29.623 回答
15

这几乎是这个 StackOverflow 问题的重复。你想要的是StringUtils,并调用join方法。

StringUtils.join(strArr, ',');
于 2009-03-21T12:35:06.300 回答
14

另一种解决方案(也许是最有效的)

    int[] array = {1, 2, 3};
    StringBuilder builder = new StringBuilder();

    if (array.length != 0) {
        builder.append(array[0]);
        for (int i = 1; i < array.length; i++ )
        {
            builder.append(",");
            builder.append(array[i]);
        }
    }
于 2008-11-12T22:20:05.040 回答
7

保持简单并使用标准 for 循环:

for(int i = 0 ; i < array.length ; i ++ ){
    builder.append(array[i]);
    if( i != array.length - 1 ){
        builder.append(',');
    }
}

或者只使用 apache commons-lang StringUtils.join()

于 2008-11-12T22:04:06.133 回答
6

显式循环总是比隐式循环更好。

builder.append( "" + array[0] );
for( int i = 1; i != array.length; i += 1 ) {
   builder.append( ", " + array[i] );
}

您应该将整个内容包装在一个 if 语句中,以防万一您正在处理一个零长度数组。

于 2008-11-12T22:05:33.320 回答
4

如果将其转换为经典的索引循环,是的。

或者您可以在完成后删除最后一个逗号。像这样:

int[] array = {1, 2, 3...};
StringBuilder

builder = new StringBuilder();

for(int i : array)
{
    builder.append(i + ",");
}

if(builder.charAt((builder.length() - 1) == ','))
    builder.deleteCharAt(builder.length() - 1);

我,我只是使用StringUtils.join()commons -lang

于 2008-11-12T22:03:45.510 回答
4

正如工具包所提到的,在 Java 8 中,我们现在有了Collectors。下面是代码的样子:

String joined = array.stream().map(Object::toString).collect(Collectors.joining(", "));

我认为这正是您正在寻找的,这是一种您可以用于许多其他事情的模式。

于 2016-11-11T01:24:50.937 回答
3

你需要类分隔符

Separator s = new Separator(", ");
for(int i : array)
{
     builder.append(s).append(i);
}

类的实现Separator是直截了当的。它包装了一个字符串,该字符串在每次调用时都返回,toString()但第一次调用除外,第一次调用返回一个空字符串。

于 2008-11-14T10:00:00.410 回答
3

基于 java.util.AbstractCollection.toString(),它提前退出以避免分隔符。

StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
for (;;) {
  buffer.append(iter.next());
  if (! iter.hasNext())
    break;
  buffer.append(delimiter);
}

它高效而优雅,但不像其他一些答案那样不言而喻。

于 2009-03-21T12:13:06.120 回答
3

这是一个解决方案:

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
bool firstiteration=true;

for(int i : array)
{
    if(!firstiteration)
        builder.append(",");

    builder.append("" + i);
    firstiteration=false;
}

寻找第一次迭代:)  

于 2008-11-12T22:06:54.643 回答
1

恕我直言,这里描述的许多解决方案都有些过头了,尤其是那些依赖外部库的解决方案。有一个很好的干净、清晰的习惯用法来实现我一直使用的逗号分隔列表。它依赖于条件 (?) 运算符:

编辑:原始解决方案正确,但根据评论不是最佳的。第二次尝试:

    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。

于 2009-03-21T19:23:01.467 回答
1

又一个选择。

StringBuilder builder = new StringBuilder();
for(int i : array)
    builder.append(',').append(i);
String text = builder.toString();
if (text.startsWith(",")) text=text.substring(1);
于 2009-03-21T12:25:45.027 回答
1

这是我运行的 SSCCE 基准测试(与我必须实施的相关),结果如下:

elapsed time with checks at every iteration: 12055(ms)
elapsed time with deletion at the end: 11977(ms)

至少在我的示例中,在每次迭代时跳过检查并没有明显更快,特别是对于正常的数据量,但它更快

import java.util.ArrayList;
import java.util.List;


public class TestCommas {

  public static String GetUrlsIn(int aProjectID, List<String> aUrls, boolean aPreferChecks)
  {

    if (aPreferChecks) {

      StringBuffer sql = new StringBuffer("select * from mytable_" + aProjectID + " WHERE hash IN ");

      StringBuffer inHashes = new StringBuffer("(");
      StringBuffer inURLs = new StringBuffer("(");

      if (aUrls.size() > 0)
      {

      for (String url : aUrls)
      {

        if (inHashes.length() > 0) {
        inHashes.append(",");
        inURLs.append(",");
        }

        inHashes.append(url.hashCode());

        inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"");//.append(",");

      }

      }

      inHashes.append(")");
      inURLs.append(")");

      return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString();
    }

    else {

      StringBuffer sql = new StringBuffer("select * from mytable" + aProjectID + " WHERE hash IN ");

      StringBuffer inHashes = new StringBuffer("(");
      StringBuffer inURLs = new StringBuffer("(");

      if (aUrls.size() > 0)
      {

      for (String url : aUrls)
      {
        inHashes.append(url.hashCode()).append(","); 

        inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"").append(",");
      }

      }

      inHashes.deleteCharAt(inHashes.length()-1);
      inURLs.deleteCharAt(inURLs.length()-1);

      inHashes.append(")");
      inURLs.append(")");

      return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString();
    }

  }

  public static void main(String[] args) { 
        List<String> urls = new ArrayList<String>();

    for (int i = 0; i < 10000; i++) {
      urls.add("http://www.google.com/" + System.currentTimeMillis());
      urls.add("http://www.yahoo.com/" + System.currentTimeMillis());
      urls.add("http://www.bing.com/" + System.currentTimeMillis());
    }


    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 300; i++) {
      GetUrlsIn(5, urls, true);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("elapsed time with checks at every iteration: " + (endTime-startTime) + "(ms)");

    startTime = System.currentTimeMillis();
    for (int i = 0; i < 300; i++) {
      GetUrlsIn(5, urls, false);
    }
    endTime = System.currentTimeMillis();
    System.out.println("elapsed time with deletion at the end: " + (endTime-startTime) + "(ms)");
  }
}
于 2014-08-01T14:58:26.127 回答
0

另一种方法是将数组的长度(如果可用)存储在一个单独的变量中(比每次重新检查长度更有效)。然后,您可以将索引与该长度进行比较,以确定是否添加最后一个逗号。

编辑:另一个考虑因素是权衡删除最终字符(可能导致字符串复制)与在每次迭代中检查条件的性能成本。

于 2008-11-12T22:06:10.030 回答
0

这里有两条替代路径:

1:Apache Commons 字符串实用程序

2:保持一个名为 的布尔值first,设置为真。在每次迭代中,如果first为假,请附加逗号;之后,设置first为假。

于 2008-11-12T22:08:03.113 回答
0

如果您只是将数组转换为逗号分隔的数组,那么许多语言都有专门的连接函数。它将一个数组变成一个字符串,每个元素之间都有一个分隔符。

于 2008-11-12T22:44:58.983 回答
0

在这种情况下,真的不需要知道它是否是最后一次重复。我们有很多方法可以解决这个问题。一种方法是:

String del = null;
for(int i : array)
{
    if (del != null)
       builder.append(del);
    else
       del = ",";
    builder.append(i);
}
于 2011-05-24T06:58:48.717 回答
0

由于它是一个固定数组,因此更容易避免增强 for... 如果 Object 是一个集合,则迭代器会更容易。

int nums[] = getNumbersArray();
StringBuilder builder = new StringBuilder();

// non enhanced version
for(int i = 0; i < nums.length; i++){
   builder.append(nums[i]);
   if(i < nums.length - 1){
       builder.append(",");
   }   
}

//using iterator
Iterator<int> numIter = Arrays.asList(nums).iterator();

while(numIter.hasNext()){
   int num = numIter.next();
   builder.append(num);
   if(numIter.hasNext()){
      builder.append(",");
   }
}
于 2017-06-15T02:55:50.353 回答
0

您可以使用StringJoiner

int[] array = { 1, 2, 3 };
StringJoiner stringJoiner = new StringJoiner(",");

for (int i : array) {
    stringJoiner.add(String.valueOf(i));
}

System.out.println(stringJoiner);
于 2021-11-10T10:50:53.767 回答