迭代器删除元素
在使用Iterator的时候,迭代器会新建一个线程,把原来的线程中的对象重新拷贝一份,在进行删除,修改等操作时,原来的线程只负责迭代,而Iterator负责迭代和删除操作,Iterator每次迭代都会检查迭代器里的对象和原线程中的对象个数是否一致,不一致则抛出:ConcurrentModificationException。
Iterator中的remove
default void remove()
从基础集合中移除这个迭代器返回的最后一个元素(可选操作)。两个线程中都删除,保证线程的同步。
-
在需要的删除等操作时,不能使用简单的foreach,因为其底层依然用的是Iterator,但是调用的是集合中的remove方法。
-
使用迭代器对象调用其中的remove方法,以保证线程同步。
当然为了避免删除,可以使用新建一个对象等,但是这样会浪费内存,如果数据量大的话。
使用迭代器删除意味着多线程操作,当有其他操作对这个元素做修改时,会发生不同步的现象,最好在iterator时不要其他线程操作或者对对象进行修改
for不同循环速度问题
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
//for循环遍历
for (int i = 0, size = list.size(); i < size; i++) {
System.out.println(list.get(i));
}
//iterator迭代器遍历
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
//foreach循环
for (Integer i : list) {
System.out.println(i);
}
}
}
ArrayList以相邻储存的方式 /LinkedList 链式存储,顺序储存
for each 底层为iterator, for底层是计数器
java各种List循环:for、forEach、lambda forEach、stream forEach、iterator性能效率对比
x4: loop size:100000000
y4: classical for loop waste millisecond:132
y4: classical forEach loop waste millisecond:70
y4: lambda forEach loop waste millisecond:56
y4: lambda not parallel stream forEach loop waste millisecond:76
y4: lambda parallel stream forEach loop waste millisecond:17
y4: classical iterator loop waste millisecond:86
性能顺序:lambda parallelStream().forEach()>lambda stream().forEach()≈lambda forEach()>classical iterator≈classical forEach>classical for
https://blog.csdn.net/mygirle/article/details/80021882
数据量的遍历用parallelStream可以比普通遍历节省一半的时间,这个亲测过。
在使用stream.foreach时这个遍历没有线程安全问题,但是使用parallelStream就会有线程安全问题,所有在parallelStream里面使用的外部变量,比如集合一定要使用线程安全集合,不然就会引发多线程安全问题。
MAP和list对比