Java 增强的循环开始部分通过列表
我是Java的初学者,我有这个疑问。是否可以在ArrayList上使用Java中增强的for循环,但从指定的点开始,而不是从ArrayList[0]开始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} 我可以使
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 (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
}