Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 增强的循环开始部分通过列表_Java_List_For Loop - Fatal编程技术网

Java 增强的循环开始部分通过列表

Java 增强的循环开始部分通过列表,java,list,for-loop,Java,List,For Loop,我是Java的初学者,我有这个疑问。是否可以在ArrayList上使用Java中增强的for循环,但从指定的点开始,而不是从ArrayList[0]开始 For eg. ArrayList<Integer> calc = new ArrayList<Integer>; // calc contains {0,1,2,3,4,5,6,7} 例如,ArrayList calc=新的ArrayList; //计算包含{0,1,2,3,4,5,6,7} 我可以使

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

For eg. ArrayList<Integer> calc = new ArrayList<Integer>;
       // calc contains {0,1,2,3,4,5,6,7}
例如,ArrayList calc=新的ArrayList;
//计算包含{0,1,2,3,4,5,6,7}
我可以使用增强for循环并从calc[2]而不是calc[0]开始迭代吗??如果可能的话,我怎么做?
在我的特殊情况下,使用增强的for循环比使用普通的for循环更好

您在这里使用的是传统的循环

for(Item e : list.subList(1, list.size())) {
    // ...
}
for (int i = 2; i < calc.size(); i++) {
    Integer x = calc.get(i);
}

Java中最好的方法如下:

for (Integer i : calc.subList(start, calc.size()) {
  ... 
}
子列表
是原始列表的有效视图,因此它几乎正是您所需要的

更新 好的,受Mikera评论的启发,我在
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;
  }
}
结论:
  • 主列表上的增强for与索引迭代一样快,一旦超过初始化成本

  • 子列表的遍历比主列表的遍历慢一些,迭代比索引遍历慢一些

  • 所有这些差异在实际应用中都可以忽略不计


  • 您可以遍历,如下所示:

    for (Integer integerMember : calc.subList(2, calc.size()) {
        // operation here
    }
    

    应该注意的是,增强的for循环对于
    ArrayList
    的效率低于标准索引。这是因为我们必须创建一个
    迭代器
    对象,并在循环的每个步骤上调用
    hasNext
    next
    ,从而导致不必要的开销


    出于这个原因,我建议以传统的方式建立索引,而不是使用
    子列表
    方法。

    当我需要索引时,不管是什么原因,我从不使用增强For循环。增强的for与c#中的foreach完全相同:它循环列表中包含的每个对象并对其进行处理。为什么您认为增强的for循环会更好?@duffymo我基本上想迭代ArrayList…而增强的for循环是最好的方法…但我想从不同的点开始,而不是ArrayList[0]…所以我想知道是否可以修改增强for循环以满足我的目的?不需要“基本上”。我知道你想要什么。我不同意你坚持认为增强循环是“最好的”。不,不能修改。使用传统的for循环并完成它。顺便说一句,建议尽可能使用收集接口,而不是实际实现,因此不要使用ArrayList calc=new ArrayList();我建议使用List calc=new ArrayList();从列表的一个实现切换到另一个实现是一个位置变化的问题(以及考虑后果的时间,特别是时间复杂性)。我认为应该是
    list.size()
    ,而不是
    list.size()-1
    ,因为
    subList()
    toIndex
    的第二个参数是独占的,不是这样的。已更新,以防万一。:-)我相信,“最好”取决于你是在乎简洁还是注重表现。与传统的索引循环相比,子列表增加了少量开销。不,“最佳”取决于问题是什么:使用增强的for。但是,在性能页面上,只有在静态类型的
    ArrayList
    上进行索引迭代时,才可以接受索引迭代;否则你就有O(n2)崩溃的风险。如果你想学究的话,List.subList()可能比O(n^2)更糟糕-你无法保证它是如何实现的:-)问题确实指定了ArrayList,所以我们都是安全的。既然你提到了规范,我正在阅读它。。。这句话很有趣,因为它表明
    子列表
    在用例中特别有用,就像我们的一样:“这种方法不需要显式的范围操作(数组中通常存在的那种类型)。任何需要列表的操作都可以通过传递子列表视图而不是整个列表来用作范围操作。“这更强烈地意味着任何正常的实现都可以廉价地完成此操作。+1不错;-)小心那些总是返回相同结果的东西。它经常被优化掉。我通常使用一个随机生成器,也使用一个基线方法,它只是随机生成一个比较点。
    Benchmark        ops/msec
    -------------------------
    Indexed          1860.982
    IndexedSublist   1642.059
    Iterator         1818.657
    SublistIterator  1496.994
    
    for (Integer integerMember : calc.subList(2, calc.size()) {
        // operation here
    }