创建一个Map集合
Map<String,String> map=new HashMap<String,String>();
map.put("username", "qq");
map.put("passWord", "123");
map.put("userID", "1");
map.put("email", "[email protected]");
for ( Map.Entry<String, String> entry : map.entrySet() ){
System.out.println ( entry.getKey()+"--->"+entry.getValue() );
}
System.out.println("通过iterator遍历所有的value,但是不能遍历key");
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String, String> next = iterator.next();
System.out.println("key="+next.getKey()+"value="+next.getValue());
}
System.out.println("通过map.keyset进行遍历key和value");
for (String key:map.keySet()) {
System.out.println("key= "+key+" and value= "+map.get(key));
}
System.out.println("通过Map.entrySet;")
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String>entry:entries){
String value = entry.getValue();
String key = entry.getKey();
System.out.println("key="+key+"value="+value);
}
HashMap<String, Integer> map1 = new HashMap<>();
map1.put("小明", 1);
map1.put("小红", 2);
map1.put("小张", 3);
//stream流遍历
map1.entrySet().stream().forEach((Map.Entry<String, Integer> entry) -> {
System.out.print("key = " + entry.getKey());
System.out.println(", value = " + entry.getValue());
});
但是在idea编译器中,编译器会给出警告,提示说该写法可以简化,简化后的写法和lambda表达式一致:
map1.forEach((key, value) -> {
System.out.print("key = " + key);
System.out.println(", value = " + value);
});
可以使用迭代器来遍历HashMap并删除元素。以下是一个示例代码:
HashMap<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> entry = iterator.next();
if (entry.getValue() == 2) {
iterator.remove();
}
}
System.out.println(map);
通过使用迭代器的remove()方法,可以安全地从集合中删除元素。
hashmap不用迭代器遍历删除是不安全的,是因为在使用迭代器遍历一个集合时,如果直接调用集合的remove方法删除元素,会导致迭代器内部的modCount字段与实际集合的modCount字段不一致。modCount字段是用来记录集合被修改的次数,当两者不一致时,迭代器会检测到该集合被并发修改的情况,并抛出ConcurrentModificationException异常。而使用迭代器的remove方法删除元素,则会更新modCount字段,保证一致性。
其他的包括【ForEach 循环方式、Lambda 表达式、Stream 方式】都不能保证数据安全
(1)迭代器 Iterator 方式,在迭代器 Iterator 中循环删除数据是安全的
public class HashMapSevenTest {
public static void main(String[] args) {
Map<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "Java");
hashMap.put(2, "JDK");
hashMap.put(3, "Spring Framework");
hashMap.put(4, "MyBatis framework");
hashMap.put(5, "Java中文社群");
Iterator<Map.Entry<Integer, String>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = iterator.next();
if (entry.getKey() == 1) {
// 删除
System.out.println("删除掉的Key为:" + entry.getKey());
iterator.remove();
} else {
System.out.println("Map集合中剩余的Key为:" + entry.getKey());
}
}
}
}
(2)ForEach 循环方式,在 ForEach 循环中删除数据是不安全的
public class HashMapEightTest {
public static void main(String[] args) {
Map<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "Java");
hashMap.put(2, "JDK");
hashMap.put(3, "Spring Framework");
hashMap.put(4, "MyBatis framework");
hashMap.put(5, "Java中文社群");
for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
if (entry.getKey() == 1) {
// 删除
System.out.println("删除掉的Key为:" + entry.getKey());
hashMap.remove(entry.getKey());
} else {
System.out.println("Map集合中剩余的Key为:" + entry.getKey());
}
}
}
}
(3)Lambda 表达式,在 Lambda 表达式循环中删除数据是不安全的
public class HashMapNineTest {
public static void main(String[] args) {
Map<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "Java");
hashMap.put(2, "JDK");
hashMap.put(3, "Spring Framework");
hashMap.put(4, "MyBatis framework");
hashMap.put(5, "Java中文社群");
hashMap.keySet().removeIf(key -> key == 1);
hashMap.forEach((key, value) -> {
if (key == 1) {
System.out.println("删除掉的Key为:" + key);
} else {
System.out.println("Map集合中剩余的Key为:" + key);
}
});
}
}
(4)Stream 方式,在 Stream 循环中删除数据是不安全的
public class HashMapTenTest {
public static void main(String[] args) {
Map<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "Java");
hashMap.put(2, "JDK");
hashMap.put(3, "Spring Framework");
hashMap.put(4, "MyBatis framework");
hashMap.put(5, "Java中文社群");
hashMap.entrySet().stream().filter(m -> 1 != m.getKey()).forEach((entry) -> {
if (entry.getKey() == 1) {
System.out.println("删除掉的Key为:" + entry.getKey());
hashMap.remove(entry.getKey());
} else {
System.out.println("Map集合中剩余的Key为:" + entry.getKey());
}
});
}
}
(5)总结
1-不能在 ForEach 循环遍历中使用集合(List、Map) map.remove() 来删除数据,这是非安全的操作方式
2-可以使用迭代器 Iterator 的 iterator.remove() 的方法来删除数据,这是安全的删除集合的方式
3-可以使用 Lambda 中的 removeIf 来提前删除数据,或者是使用 Stream 中的 filter 过滤掉要删除的数据进行循环,这样都是安全的
foreach增强循环是依赖了 while 循环和 Iterator 实现的,起到和普通for循环一样的效果,但是在foreach遍历删除List或Map时,如果有重复的值【11,11,12,13】,遍历删除11的时候,只会删除第一个11,第二个11不会删除。
原因如下:
删除了第一个 11 后,集合里的元素个数减 1,后面的元素都往前移了 1 位,此时,第二个 11 已经移到了原索引下标 index = 1 的位置,而此时 i 马 上 i++ 了,list.get(i) 获得的是数据 12 。同时 list.size() 的值也在减小。
原数据: 11, 11, 12, 13, 14, 15, 16
原下标: 0 1 2 3 4 5 6
执行list.remove(0)删除第一个 11 后数据: 11, 12, 13, 14, 15, 16
执行list.remove(0)删除第一个 11 后下标: 0 1 2 3 4 5
当list.remove(0)执行完后,在执行i++,而此时list.get(i)=12