java循环删除集合数据_java中循环的⼏种⽅式以及删除集合中
的指定数据
⼀、for
//for循环中删除数据 -- ⽅法有漏洞
private static void deleteAtFor() {
ArrayList array = new ArrayList<>();
array.add(4);
array.add(5);
array.add(5);
array.add(6);
for(int i=0;i
(i).equals(5)){
}
}
System.out.println(array);
}
得到删除后的集合数据是:[4,5,6]
从结果可以看出,有⼀个等于5的数据没有呗被删除,
这是为什么呢?
当我们深究 for循环在集合中⼯作原理就可以理解,事实上,当删除⼀个元素时,后⾯元素的索引就会前进以为,如删除第⼀个索引为1的5的时候,此时下⼀个元素5的索引就变成了1,⽽此时for循环执⾏i++,对应索引的位置为2 ⽽新的1索引上的值就不会在读取了,所以集合结果为[4,5,6],要解决这个问
题很容易只需要在删除的同时把⾃增变量i减⼀,和改变后的索引对应上就好,即把 ve(i)改为ve(i--)即可;
如下:
//for循环中删除数据 -- 正确⽅法
private static void deleteAtFor() {
ArrayList array = new ArrayList<>();
array.add(4);
array.add(5);
array.add(5);
array.add(6);
for(int i=0;i
(i).equals(5)){
}
}
System.out.println(array);
}
结果为[4,6],正确!
⼆、forEach
//foreach中删除数据
private static void deleteAtForeach() {
ArrayList array = new ArrayList<>();
array.add(4);
array.add(5);
array.add(5);
array.add(6);
for (Integer a:array) {
if (4==a){
}
}
}
结果如下:
java线程池创建的四种
图⽚.png
意思是迭代器并发修改异常,出现这个原因是 当⽅法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
⾸先java的foreach循环其实就是根据list对象创建⼀个Iterator迭代对象,⽤这个迭代对象来遍历list,相当于list对象中元素的遍历托管给了Iterator,你如果要对list进⾏增删操作,都必须经过Iterator,否则Iterator遍历时会乱,所以直接对list进⾏删除时,Iterator会抛出ConcurrentModificationException异常
三、迭代器
//Iterator迭代器中删除数据
private static void deleteAtIterator() {
ArrayList array = new ArrayList<>();
array.add(4);
array.add(5);
array.add(5);
array.add(6);
Iteratoriterator = array.iterator();
while (iterator.hasNext()){
if (().equals(5)){
}
}
System.out.println(array);
}
结果是:[4, 6] ;注意点:while⾥只能出现⼀次(),不然结果会出错。
四、⽤流的⽅式
ArrayList array = new ArrayList<>();
array.add(4);
array.add(5);
array.add(5);
array.add(6);
array.stream().forEach(integer -> {
if(integer.equals(5)){
}
});
System.out.println(array);
结果:
图⽚.png
stream流forEach循环也不能进⾏删除。具体原因不做深究,哈哈!
五、结论:
在只是遍历情况下,我们四种都可以⽤,在修改集合的情况下,不能⽤foreach和stream流forEach;
番外:
如果只是单纯的遍历的话,
从效率⾓度来看:For Each的效率差,stream流forEach和迭代器的效率也没有很好。for循环最优,因为ArrayList通过数组来实现,数组通过索引来定位的时间复杂度是O(1),1次就能定位到,所以效率⾮常⾼;
从代码编写量来看:stream是最简洁的,for循环是量最多的;
但是,我最想推荐的遍历⽅式是:stream
stream().forEach⽤的多线程⽅式,其调⽤线程池的时候必然会耗费更多的时间。但如果你在循环内要处理的事情很多,或者要循环调⽤远程接⼝/数据库的时候,⽆疑极⼤的提升了效率。
回顾编程的发展历史,我们不难发现⼀个规律,那就是先是从最初的C/C++演变到Java/,这是编程界的⼀⼤进步,因为我们不再关注于指针操作,⽐如在java中JVM虚拟机已经帮我们完成了相应的操作,由于这⼀进步,这付出的代价是执⾏效率会降低,但是带来的好处就在于加快了编程开发的速度。
当编程由Java/演变到JavaScript/PHP/Kotlin,这⼜是编程界的另⼀⼤进步,这意味着我们在编写程序时没有必要再关注于数据类型,⽽该数据类型是由相应的语⾔在运⾏时确定,这样,这⼜⼀次降低了程序的运⾏速度,但是相应的⼜提升了代码编写的效率,因⽽通过回顾历史我们不难得出如下结论:
在编写代码时,⼀定要以最简洁为原则,毕竟运⾏程序的硬件成本会随着时间的推移在不断降低,⽽程序员的薪资则不会。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。