在java中增强for循环的最后一次迭代

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

int[] array = {1, 2, 3...}; StringBuilder builder = new StringBuilder(); for(int i : array) { builder.append("" + i); if(!lastiteration) builder.append(","); } 

现在的事情是我不想在最后一次迭代中追加逗号。 现在有一种方法来确定它是否是最后一次迭代,或者我是否用for循环或使用外部计数器来跟踪。

另一种方法是在追加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是,它可以与任何Iterable一起工作 – 你不能总是索引的东西。 (当你真正使用StringBuilder的时候,“添加逗号然后在最后删除它”是一个很好的build议,但是它不适用于写入stream的事情,但这可能是最好的方法。 )

另一种方法来做到这一点:

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

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

始终追加可能更容易。 然后,当你完成你的循环,只要删除最后的字符。 通过这种方式减less条件。

你可以使用StringBuilderdeleteCharAt(int index) ,索引是length() - 1

也许你正在为作业使用错误的工具。

这比你所做的更手工,但如果不是一个“老派”,它会更加优雅

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

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

 StringUtils.join(strArr, ','); 

另一个解决scheme(也许是最有效的)

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

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

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

你应该把整个东西包装在一个if语句中,以防万一你处理一个零长度的数组。

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

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

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

如果你把它转换成经典的索引循环,是的。

或者你可以删除最后一个逗号。 像这样:

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

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

你需要类分隔符 。

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

Separator的实现是直接的。 它包装了每次调用toString()返回的string,除了第一个调用,它返回一个空string。

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

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

这是高效和优雅的,但不像其他答案那样不言自明。

这是一个解决scheme:

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

寻找第一次迭代:)

还有一个select。

 StringBuilder builder = new StringBuilder(); for(int i : array) builder.append(',').append(i); String text = builder.toString(); if (text.startsWith(",")) text=text.substring(1); 

这里描述的许多解决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的声明。

这是我运行的SSCCE基准(与我必须执行的内容有关):

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

至less在我的例子中,跳过每次迭代的检查并不明显更快,尤其是对于理智的数据量,但速度更快。

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

作为工具箱提到,在Java 8中,我们现在有收集器 。 代码如下所示:

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

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

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

编辑:另一个考虑是衡量删除最后一个字符(这可能会导致一个string副本)的性能成本,而不是在每次迭代中检查条件。

如果只将数组转换为逗号分隔的数组,许多语言都有一个连接函数。 它将数组转换为每个元素之间带有分隔符的string。

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

 String del = null; for(int i : array) { if (del != null) builder.append(del); else del = ","; builder.append(i); } 

这里有两条备用path:

1: Apache Commons String Utils

2:保持一个布尔值first调用,设置为true。 在每次迭代中,如果first是假的,请附上您的逗号; 之后, first设置为false。

因为它是一个固定的数组,所以简单地避免增强…更容易。如果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(","); } } 
Interesting Posts