Java中HashMap,HashSet是线程安全的吗,ArrayList是线程不安全的那如何避免其出异常?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中HashMap,HashSet是线程安全的吗,ArrayList是线程不安全的那如何避免其出异常?相关的知识,希望对你有一定的参考价值。
HashMap,HashSet,ArrayList都不具备线程安全。
可以用
Set s=Collections.synchronizedSet(new Hashset<...>());Map m=Collections.synchronizedMap(new HashMap<...>());
List l=Collections.synchronizedList(new ArrayList<...>());
获得被同步后的版本。
也可以用ConcurrentHashMap等同步工具代替
参考技术A HashSet不是线程安全的,HashTable是线程安全的。如果数据量很大,又要线程安全,建议使用Vectorjava集合框架笔记HashSetHashMap
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
HashSet 允许有 null 值。
HashSet 是无序的,即不会记录插入的顺序。
HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
HashSet 实现了 Set 接口。
HashSet 无法通过下标获取元素,只能使用 contains() 判断元素是否存在于集合。
HashMap 可以直接被打印。使用put() 添加键和值。使用get() 获取对应键的值。
putIfAbsent() 如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。
Map<Integer, String> hm = new HashMap<>();
hm.put(0, "zero");
hm.put(1, "zero");
hm.put(2, "zero");
System.out.println(hm);
System.out.println(hm.putIfAbsent(3, "zero"));
System.out.println(hm);
{0=zero, 1=zero, 2=zero}
null
{0=zero, 1=zero, 2=zero, 3=zero}
computeIfAbsent() 方法对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中。
需要map的值类型为数值。
hashmap当put同样的键值对时会去重,最终保留唯一的键值对。
computeIfPresent() 方法对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中
如果 key 对应的 value 不存在,则返回该 null,如果存在,则返回通过 remappingFunction 重新计算后的值。
package test;
import java.net.InterfaceAddress;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @Description: TODO
* @author: HardyDragon
* @date: 2021年06月09日 13:51
*/
public class Test05 {
public static void main(String[] args) {
// Set<Integer> set = new HashSet<>();
// set.add(1);
// set.add(2);
// set.add(3);
// for (Integer i : set) {
// System.out.println(i);
// }
//
// System.out.println(set.contains(1));
Map<Integer, String> hm = new HashMap<>();
hm.put(0, "zero");
hm.put(1, "zero");
hm.put(2, "zero");
// System.out.println(hm);
// System.out.println(hm.putIfAbsent(3, "zero"));
// System.out.println(hm);
System.out.println(hm.containsKey(1));
System.out.println(hm.containsValue("zero"));
System.out.println("replace() 返回被替换前的值");
System.out.println(hm.replace(1, "one"));
System.out.println(hm);
hm.replaceAll((integer, s) -> "hello");
System.out.println(hm);
System.out.println(hm.getOrDefault(99, "not find!"));
System.out.println("foreach 不会影响实际引用变量。");
hm.forEach((integer, s) -> {
integer = integer * integer;
s.toUpperCase();
System.out.println(integer + "s=" + s);
});
System.out.println("+++++++++++++++++++++");
Set<Map.Entry<Integer, String>> entries = hm.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry);
}
System.out.println("+++++++++++++++++++++");
for (Integer i : hm.keySet()) {
System.out.println(i);
}
System.out.println("+++++++++++++++++++++");
for (String s : hm.values()) {
System.out.println(s);
}
System.out.println("+++++++++++++++++++++");
hm.compute(0, (integer, s) -> s.toUpperCase());
System.out.println(hm);
System.out.println("+++++++++++++++++++++");
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("one", 1);
hashMap.put("two", 2);
System.out.println(hashMap.computeIfAbsent("one", v -> 222));
System.out.println(hashMap.computeIfAbsent("three", v -> 333));
System.out.println(hashMap);
System.out.println("+++++++++++++++++++++");
System.out.println(hashMap.computeIfPresent("two", (k, v) -> v * v));
System.out.println(hashMap);
}
}
result
true
true
replace() 返回被替换前的值
zero
{0=zero, 1=one, 2=zero}
{0=hello, 1=hello, 2=hello}
not find!
foreach 不会影响实际引用变量。
0s=hello
1s=hello
4s=hello
+++++++++++++++++++++
0=hello
1=hello
2=hello
+++++++++++++++++++++
0
1
2
+++++++++++++++++++++
hello
hello
hello
+++++++++++++++++++++
{0=HELLO, 1=hello, 2=hello}
+++++++++++++++++++++
1
333
{one=1, three=333, two=2}
+++++++++++++++++++++
4
{one=1, three=333, two=4}
以上是关于Java中HashMap,HashSet是线程安全的吗,ArrayList是线程不安全的那如何避免其出异常?的主要内容,如果未能解决你的问题,请参考以下文章
java中hashmap和hashtable和hashset的区别