【问题标题】:Detecting the first iteration through a for-each loop in Java通过Java中的for-each循环检测第一次迭代
【发布时间】:2012-05-17 03:59:33
【问题描述】:

我正在开发一个将字符分隔列表返回给其客户端的服务器。 为了构建这些列表,我必须通过 for-each 循环检测第一次迭代:

    StringBuilder builder = new StringBuilder() ;
    boolean firstIterationFlag = true ;

    for ( String s : list ){
        if ( firstIterationFlag) {
            firstIterationFlag = false ;
        } else {
            builder.append(separator);
        }
        builder.append(s) ;         
   }
   return builder.toString() ;

有没有办法在没有标志的情况下做到这一点?

【问题讨论】:

  • 为什么一定要检测循环的第一次迭代?
  • 代替forEach循环,您可以手动执行正常的for循环,从索引1开始而不是0。
  • 看看这个 SO 问题:stackoverflow.com/questions/63150/… - 这可能是你的更好的解决方案。
  • ...或用户 list.indexOf(s) 获取索引...
  • @vilo:这可能是对每次迭代的线性时间命中,因此对例程的 O(n^2) 命中只是为了将一些文本粘合在一起。

标签: java foreach


【解决方案1】:

对于这种情况,一种更简单的方法是注意您始终可以附加一个空字符串:

// For the first iteration, use a no-op separator
String currentSeparator = "";
for (String s : list) {
    builder.append(currentSeparator);
    builder.append(s);
    // From the second iteration onwards, use this
    currentSeparator = separator;
}

或者(最好)使用 Guava 的 Joiner 类开始:)

这种“加入者”场景几乎总是为此要求给出的场景 - 所以只需使用Joiner。对于其他情况,请使用常规 for 循环或根据您的代码使用条件。

【讨论】:

  • if 被淘汰,但更难掌握
  • 我使用来自 Apache commons-lang 的 StringUtils.join。
  • @raviWallau 我也是,在我知道 Guava 的木匠之前 :-)
【解决方案2】:

不使用 foreach,而是手动使用迭代器:

Iterator<String> it = list.iterator();
if(it.hasNext()){
    doSomeThingForTheFirstTime(it.next());
    while(it.hasNext()){
        doSomethingElse(it.next);
    }
}

(顺便说一句,这几乎是 Guava 的 Joiner 类在内部所做的,虽然在更高级别)

【讨论】:

    【解决方案3】:

    Java 8 解决方案

    如果你有 Java 8,你可以简单地使用String#join,不需要 Guava:

    String.join(", ", list)
    

    【讨论】:

      【解决方案4】:

      在您引用的特定情况下,使用 Guava 的 Joiner 而不是自己滚动...

      使用分隔符连接文本片段(指定为数组、Iterable、可变参数或什至 Map)的对象。它要么将结果附加到 Appendable,要么将它们作为字符串返回。示例:

      Joiner joiner = Joiner.on(separator).skipNulls();
      return joiner.join(list);
      

      【讨论】:

      • +1(Guava 的 Joiner 远远优于 apache commons 中的任何东西)
      【解决方案5】:

      为了好玩,这里有一个不同的选择。

          StringBuilder builder = new StringBuilder();
          for (String s : list) {
              builder.append(separator);
              builder.append(s);
          }
          builder.deleteCharAt(0);
          return builder.toString();
      

      【讨论】:

        【解决方案6】:

        你可以试试这个:)

        int i = 0;
        for (something : manythings) {
            i++;
        }
        

        【讨论】:

          【解决方案7】:

          我会使用 commons.lang StringUtils.join 函数(参见http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/StringUtils.html)。我强烈建议您熟悉这个和其他帮助库,以避免重新发明轮子。

          【讨论】:

            【解决方案8】:

            您也可以使用以下方法:

            public static String toString(List<?> list, String separator) {
                StringBuilder sb = new StringBuilder();
                Iterator<?> it = list.iterator();
                while (it.hasNext()) {
                    Object next = it.next();
                    sb.append(next);
                    if (it.hasNext()) {
                        sb.append(separator);
                    }
                }
                return sb.toString();
            }
            

            增强的for 语句等效于基本for 语句的形式:

            for (I #i = Expression.iterator(); #i.hasNext(); ) {
                VariableModifiersopt TargetType Identifier =
                    (TargetType) #i.next();
                Statement
            }
            

            #i 是自动生成的标识符

            【讨论】:

              【解决方案9】:

              好吧,这不会检测循环中的第一次迭代,但可以解决问题。只需在每个字符串的末尾附加分隔符并切断最后一个分隔符即可。

              StringBuilder builder = new StringBuilder() ;
              
              for ( String s : list ) {
                  builder.append(s) ;         
                  builder.append(separator);
              }
              builder.setLength(builder.length() - separator.length());
              return builder.toString() ;
              

              【讨论】:

                猜你喜欢
                • 2010-12-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多