Java 迭代器.remove()不删除
我在使用迭代器的remove方法时遇到了一个问题,没有抛出异常,但该方法根本无法按预期工作 有一张地图包含:Java 迭代器.remove()不删除,java,java-8,hashmap,iterator,Java,Java 8,Hashmap,Iterator,我在使用迭代器的remove方法时遇到了一个问题,没有抛出异常,但该方法根本无法按预期工作 有一张地图包含: {[1, 2]=3, [2, -1]=1, [-4]=-4, [-1, 0, 1]=0, [-1, -4]=-5, [0, 1, -1]=0} 容易出现故障的线路是: map.entrySet.removiefe->e.getKey.sizee.getKey.size-1]=0}我制作了地图并运行了这条线。entrySet.removiee.getKey.size
{[1, 2]=3, [2, -1]=1, [-4]=-4, [-1, 0, 1]=0, [-1, -4]=-5, [0, 1, -1]=0}
容易出现故障的线路是:
map.entrySet.removiefe->e.getKey.size<3 | | e.getValue!=0;
我在谷歌上搜索了很多,但还是没找到答案
完整代码如下:
公共班机{
公共静态无效字符串[]args{
int[]nums={-1,0,1,2,-1,-4};
溶液溶胶=新溶液;
Map Map=sol.threeSumnums;
迭代器it=map.entrySet.Iterator;
当它有下一个{
Map.Entry m=it.next;
System.out.printlnm.getKey.size;
}
map.entrySet.removiefe->e.getKey.size<3 | | e.getValue!=0;
System.out.printlnmap;
}
}
类解决方案{
公共地图3SUMINT[]nums{
HashMap=新的HashMap;
对于int num:nums{
迭代器it=map.entrySet.Iterator;
当它有下一个{
Map.Entry e=it.next;
如果e.getKey.size==2{
如果e.getKey.get0+e.getKey.get1+num!=0{
它。移除;
}否则{
e、 getKey.addnum;
e、 setValue0;
}
}如果e.getKey.size==1,则为else{
e、 getKey.addnum;
e、 setValuee.getKey.get0+num;
}
}
List li=新阵列列表;
li.addnum;
map.putli,num;
}
System.out.printlnmap;
返回图;
}
}
很高兴被纠正- JDK 8在行为上存在一些问题和差异。在JDK 8中,如果集合的大小大于1,则remove函数似乎无法按预期工作 JDK 11相同的代码按预期工作 我将代码缩减为更小的函数
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MapRemove2 {
public static void main(String[] args) {
testRemove(1);
testRemove(2);
}
private static void testRemove(int limit) {
System.out.println("LIMIT = " + limit + "\n---------");
Map<List<Integer>, Integer> map = new HashMap<List<Integer>, Integer>();
for (int i = 0; i < 5; i++) {
map.entrySet().removeIf(e -> e.getKey().size() == limit);
System.out.println(String.format("LOOP %2d - map after remove = %s", i, map));
int finalI = i;
map.entrySet().forEach(e -> {
e.getKey().add(finalI);
e.setValue(e.getValue() + finalI);
});
List<Integer> li = new ArrayList<Integer>();
li.add(i);
map.put(li, i);
System.out.println(String.format("LOOP %2d - map after add = %s", i, map));
}
System.out.println("Final MAP " + map + "\n----------\n\n");
}
}
在JDK11中编译并运行
任务:MapRemove2.main
感谢@PrasadU,我比较了HashMap的remove方法,发现问题是由于在java8中重新计算哈希值造成的,当我在列表中添加新元素时,该节点的哈希值发生了变化,但位置保持不变,因此通过重新计算哈希,我们找不到该节点,而在Java11中,它不会重新计算 爪哇8 公众最终作废{ 节点p=电流; 如果p==null 抛出新的非法状态异常; 如果modCount!=预期modCount 抛出新的ConcurrentModificationException; 电流=零; K键=p键; removeNodehashkey,key,null,false,false; expectedModCount=modCount; } 爪哇11 公众最终作废{ 节点p=电流; 如果p==null 抛出新的非法状态异常; 如果modCount!=预期modCount 抛出新的ConcurrentModificationException; 电流=零; removeNodep.hash,p.key,null,false,false; expectedModCount=modCount; }
您说过错误出现在迭代器的remove方法中,并且易出问题的行中没有使用迭代器。你能澄清一下吗?@harmandepsingkalsi lambda表达式的性能与使用迭代器完全相同。我刚刚尝试了与你相同的方法,它对我非常有效。它给出的输出只包含一个条目{[-1,0,1]=0}@harmandepsingkalsi您刚才复制了代码并运行了吗?对我来说,输出像{[1,2]=3,[2,-1]=1,[-4]=4,[-1,0,1]=0,[-1,-4]=5,[0,1,-1]=0}2,1,3{[1,2]=3,[2,-1]=1,[-1,0,1]=0,[-4]=-5,[0,1->-1]=0}我制作了地图并运行了这条线。entrySet.removiee.getKey.size<3| value0; 然后打印地图,它只给出一个条目[-1,0,1]=0}。我没有运行完整的代码。
> Task :MapRemove2.main()
LIMIT = 1
---------
LOOP 0 - map after remove = {}
LOOP 0 - map after add = {[0]=0}
LOOP 1 - map after remove = {}
LOOP 1 - map after add = {[1]=1}
LOOP 2 - map after remove = {}
LOOP 2 - map after add = {[2]=2}
LOOP 3 - map after remove = {}
LOOP 3 - map after add = {[3]=3}
LOOP 4 - map after remove = {}
LOOP 4 - map after add = {[4]=4}
Final MAP {[4]=4}
----------
LIMIT = 2
---------
LOOP 0 - map after remove = {}
LOOP 0 - map after add = {[0]=0}
LOOP 1 - map after remove = {[0]=0}
LOOP 1 - map after add = {[1]=1, [0, 1]=1}
LOOP 2 - map after remove = {[1]=1, [0, 1]=1}
LOOP 2 - map after add = {[1, 2]=3, [2]=2, [0, 1, 2]=3}
LOOP 3 - map after remove = {[1, 2]=3, [2]=2, [0, 1, 2]=3}
LOOP 3 - map after add = {[1, 2, 3]=6, [2, 3]=5, [3]=3, [0, 1, 2, 3]=6}
LOOP 4 - map after remove = {[1, 2, 3]=6, [2, 3]=5, [3]=3, [0, 1, 2, 3]=6}
LOOP 4 - map after add = {[1, 2, 3, 4]=10, [2, 3, 4]=9, [3, 4]=7, [4]=4, [0, 1, 2, 3, 4]=10}
Final MAP {[1, 2, 3, 4]=10, [2, 3, 4]=9, [3, 4]=7, [4]=4, [0, 1, 2, 3, 4]=10}
----------
LIMIT = 1
---------
LOOP 0 - map after remove = {}
LOOP 0 - map after add = {[0]=0}
LOOP 1 - map after remove = {}
LOOP 1 - map after add = {[1]=1}
LOOP 2 - map after remove = {}
LOOP 2 - map after add = {[2]=2}
LOOP 3 - map after remove = {}
LOOP 3 - map after add = {[3]=3}
LOOP 4 - map after remove = {}
LOOP 4 - map after add = {[4]=4}
Final MAP {[4]=4}
----------
LIMIT = 2
---------
LOOP 0 - map after remove = {}
LOOP 0 - map after add = {[0]=0}
LOOP 1 - map after remove = {[0]=0}
LOOP 1 - map after add = {[1]=1, [0, 1]=1}
LOOP 2 - map after remove = {[1]=1}
LOOP 2 - map after add = {[1, 2]=3, [2]=2}
LOOP 3 - map after remove = {[2]=2}
LOOP 3 - map after add = {[2, 3]=5, [3]=3}
LOOP 4 - map after remove = {[3]=3}
LOOP 4 - map after add = {[3, 4]=7, [4]=4}
Final MAP {[3, 4]=7, [4]=4}
----------