【问题标题】:Java enhanced enhanced for loopJava 增强增强 for 循环
【发布时间】:2010-11-29 21:45:39
【问题描述】:

目前(从 Java 6 开始),使用 Java 的增强型 for 循环,除了恢复到旧的索引 for 循环或使用外部计数器之外,我不知道有任何方法可以直接访问迭代器索引。

是否有计划(或者可能是当前的方式)来实现这种“增强的增强型”for 循环,以便能够访问循环的索引(甚至可能操纵它)?

作为可能需要的示例,请考虑(这是来自实际生产代码):

int i = 1;
for (final String action : actions) {
  parameters.set(String.valueOf(i++), action);
}

【问题讨论】:

  • 是的,我一直不明白他们为什么称它为“增强”。将其称为“简化的 for 循环”会更好。
  • 如果在 Python 中有类似 enumerate() 之类的东西会很不错,它可以让你遍历索引和元素:for i, element in enumerate(list): print i, element跨度>
  • 好的,那么看来答案在这两个方面都是“否”(已知的实施计划/jsr,或者当前的执行方式)。那些说它违背了它的介绍的“哲学”的人——我肯定明白你来自哪里——我只是发现自己处于我想要这种能力而不必求助于冗长的替代方案的情况下。
  • Java 5.0 中引入了增强的 for 循环。 ;)
  • 如回答所问,什么情况下需要索引?你能提出这个问题吗?

标签: java for-loop foreach


【解决方案1】:

好吧,就像你说的,如果你必须有一个索引,只需使用标准的 for 循环,或者手动更新一个计数器。

但请重新考虑您的问题。为什么在for (Object o : list) 循环中需要索引?

使用增强循环的全部意义是抽象出使用索引或迭代器的讨厌部分。

今天的大多数语言都没有在循环中提供这种功能。举个例子,Pythonic 的做法是:

for index, val in enumerate(someList):
    # ....

【讨论】:

    【解决方案2】:

    没有。使用外部变量。

    【讨论】:

    • +1 简单明了。此外,由于 Collection.get(i) 的实现特定时间复杂性的各种原因,将计数器添加到增强的 for 循环体可能是最好的选择。与之前建议的恢复到传统的 for(statement;condition;statement) 循环结构相反。
    【解决方案3】:

    为什么他们需要提供另一种按索引访问元素的方式?

    当您不需要元素的索引时,增强的 for 循环是作为快捷方式创建的。它简化了事情。

    如果您仍然需要索引,请回退到常规 for 循环。这就是他们在那里的原因之一。

    【讨论】:

    • 不妨考虑使用泛型遍历集合。直接使用迭代器时,它非常长且难以阅读。在我看来,保留增强的 for 循环的抽象同时能够访问索引(如果需要)会很好。
    【解决方案4】:

    最好保留一个外部计数器来获取索引,但你可以做这样的事情(对于一个简单的任务来说有点矫枉过正)

    class Enum<T> implements Iterable<Indexer<T>> {
        private int indx;
        private Iterator<T> itr;
        private Indexer<T> indxr = new Indexer<T>();
    
        private Enum(Iterable<T> iter) {
            this.itr = iter.iterator();
        }
    
        public static <T> Enum<T> iterate(Iterable<T> iter) {
            return new Enum<T>(iter);
        }
    
        @Override
        public Iterator<Indexer<T>> iterator() {
            return new AbstractIterator<Indexer<T>>() {
                @Override
                protected Indexer<T> computeNext() {
                    if (itr.hasNext()) {
                        indxr.index = indx++;
                        indxr.val = itr.next();
                        return indxr;
                    }
                    return endOfData();
                }
    
            };
        }
    
    }
    
    class Indexer<T> {
        public int index;
        public T val;
    
        @Override
        public String toString() {
            return String.format("[ %d : %s ]", index, val);
        }
    

    在迭代时获取索引:

        List<Integer> list = new ArrayList<Integer>() ;
        list.addAll(Arrays.asList(1, 2, 3, 4, 5,6,55,23,12,24,16));
        for (Indexer<Integer> en : Enum.iterate(list)) 
          System.out.println(en.index+" "+en.val);
    

    注意:以上代码对Guava'sAbstractIterator有依赖关系

    【讨论】:

      【解决方案5】:

      现在没有办法,除非你有一个柜台!我知道这很难看,但 java 7 会更好。我不知道为什么其他人说我们不需要它。有时我们需要知道什么是最后一个成员或奇数成员等。

      【讨论】:

      • Java 7 解决了这个问题吗?
      • @SamuelEdwinWard No.
      猜你喜欢
      • 2011-01-20
      • 1970-01-01
      • 2013-06-14
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-23
      相关资源
      最近更新 更多