是否为每个“循环”计算循环条件;至于;Java中的句子?
这是我的Java代码:是否为每个“循环”计算循环条件;至于;Java中的句子?,java,optimization,loops,Java,Optimization,Loops,这是我的Java代码: List<Object> objects = new ArrayList(); // Assign values to objects ... for (int i = 0; i < objects.size(); i++) { Object object = objects.get(i); ... } List objects=new ArrayList(); //为对象指定值 ... 对于(int i=0;i
List<Object> objects = new ArrayList();
// Assign values to objects
...
for (int i = 0; i < objects.size(); i++) {
Object object = objects.get(i);
...
}
List objects=new ArrayList();
//为对象指定值
...
对于(int i=0;i
我有两个问题:
objects.size()
是只计算一次,还是每个循环都计算一次objects.size()
,那么如果其他线程在没有多线程保护的情况下同时更改它,代码可能会崩溃李>
我说的对吗?是的,每次都计算。如果有另一个线程更改对象列表的大小,则循环条件将不断更改。当您在每次计算的循环条件内使用
objects.size()
时,是。更好的方法是在进入循环之前将其保存在变量中;
像int
limit=objects.size();
for (int i = 0; i < limit; i++) {
Object object = objects.get(i);
...
}
limit=objects.size();
对于(int i=0;i
如果您有另一个线程,它可能会更改它,但使用上述选项,它不会影响或使您的程序崩溃。答案:
objects.size()
在每个循环中都被调用(是否计算取决于ArrayList实现,您不应该关心它)foreach
语法,这意味着您不必使用索引等-这已经为您完成了:是的,每次都会计算 如果查看for循环语句,它将在第一个语句中设置计数器初始值 然后它将检查最大值,然后它将执行循环体,然后它将增加计数器的值,然后再次检查最大值。每次检查最大值时,它都会调用size方法
ConcurrentModificationException
,并且没有任何合理的方法来处理它
请注意,即使缓存了对象.size()
,也可能会发生这种情况,但现在.get()
将失败,因为您试图获取一个不再存在的索引objects.size()
由于从容器中删除或添加了某些内容而发生更改
在迭代集合时不要修改它们。从概念上讲,可以对每个循环计算objects.size()。但是,由于该方法很短,因此可以将其内联并缓存为非易失变量。i、 e.另一个线程可以改变它,但不能保证如果它改变了,你会看到改变 保存大小的一个简单方法是使用以下命令
for (int i = 0, size = objects.size(); i < size; i++) {
Object object = objects.get(i);
...
}
for(int i=0,size=objects.size();i
但是,如果您担心另一个线程可能会更改大小,则此方法仅在添加对象时保护您。如果删除了某个对象,当您尝试访问现在超出列表末尾的值时,仍然会出现异常
使用CopyOnWriteArrayList可以避免这些问题(如果您使用迭代器),但会使写入变得更昂贵。这当然假设对象的大小不变,这完全忽略了第二个问题,因此您可以使用Bohemian提供的选项。对于大多数类,您可能不会得到
ConcurrentModificationException
,因为您尚未打开迭代器。CME通常只有在打开迭代器,然后修改集合(迭代器提供的方法除外),然后再次尝试使用相同的迭代器时才会出现。例如,如果这个ArrayList
被包装在一个Collections.synchronizedList
中,那么这个代码就可以正常工作了——只不过你会遇到一个竞争条件,在这个条件下,你可能会以一个IndexOutOfBoundsException结束。呃,是的。抱歉,我习惯于看到人们以现代的方式进行迭代,而通常使用Python:)@KarlKnectel Java也有这些现代的方式!:)for(objectobj:objects){…}
这是打开并使用迭代器的语法糖,因此可以肯定地抛出CME。我在数组列表中为每个循环添加了一个新项&它不会因为CME而崩溃。不是每个人都在内部使用迭代器吗?
for (int i = 0, size = objects.size(); i < size; i++) {
Object object = objects.get(i);
...
}