增强了循环开始部分通过List

use*_*330 7 java for-loop list

我是Java的初学者,我有这个疑问.是否可以在ArrayList上使用Java中的Enhanced for循环,但是从指定的点而不是ArrayList [0]开始.

For eg. ArrayList<Integer> calc = new ArrayList<Integer>;
       // calc contains {0,1,2,3,4,5,6,7}
Run Code Online (Sandbox Code Playgroud)

我可以使用增强的for循环并从calc [2]而不是calc [0]开始迭代吗?如果可能的话,我该怎么做?在我的特定情况下,使用增强的for循环会更好,而不是正常的for循环.

Mar*_*nik 16

Java中最好的方法是这样的:

for (Integer i : calc.subList(start, calc.size()) {
  ... 
}
Run Code Online (Sandbox Code Playgroud)

subList是原始列表的有效视图,因此它几乎正是您所需要的.

UPDATE

好的,在迈克拉的评论的推动下,我对它进行了基准测试jmh.这是基准代码:

import org.openjdk.jmh.annotations.GenerateMicroBenchmark;

public class Benchmark1
{
  static final List<Integer> list = new ArrayList(asList(1,2,3,4,5,6,7,8,9,10));
  static { for (int i = 0; i < 5; i++) list.addAll(list); }

  @GenerateMicroBenchmark
  public long testIterator() {
    long sum = 0;
    for (int i : list) sum += i;
    return sum;
  }
  @GenerateMicroBenchmark
  public long testIndexed() {
    long sum = 0;
    for (int i = 0; i < list.size(); i++) sum += list.get(i);
    return sum;
  }
  @GenerateMicroBenchmark
  public long testSublistIterator() {
    long sum = 0;
    for (int i : list.subList(1, list.size())) sum += i;
    return sum;
  }
  @GenerateMicroBenchmark
  public long testIndexedSublist() {
    long sum = 0;
    final List<Integer> l = list.subList(1, list.size());
    for (int i = 0; i < l.size(); i++) sum += l.get(i);
    return sum;
  }
}
Run Code Online (Sandbox Code Playgroud)

这些是结果:

Benchmark        ops/msec
-------------------------
Indexed          1860.982
IndexedSublist   1642.059
Iterator         1818.657
SublistIterator  1496.994
Run Code Online (Sandbox Code Playgroud)

结论:

  1. 主列表上的增强与索引迭代一样快,一旦超过初始化成本;

  2. 子列表的遍历是稍微比主列表的慢,和迭代是稍微大于索引遍历慢;

  3. 对于所有实际目的,所有差异都可以忽略不计.

  • 不,"最好"取决于问题所在:使用增强版.但是,在性能页面上,只有在静态类型的"ArrayList"上完成索引迭代才是可接受的.否则你会冒O(n2)崩溃的风险. (2认同)

Ósc*_*pez 5

你在这里使用传统的循环...

for (int i = 2; i < calc.size(); i++) {
    Integer x = calc.get(i);
}
Run Code Online (Sandbox Code Playgroud)

好吧,除非你愿意为了使用增强的for循环而创建一个临时的subList,这很好,因为子列表是原始列表的视图而不创建新的列表对象:

for (Integer x : calc.subList(2, calc.size())) {

}
Run Code Online (Sandbox Code Playgroud)