聊聊Set集合?
1.HashSet简介
HashSet与ArrayList类似,都是线程不安全的,但HashSet的底层是HashMap,调用add方法时只需要传一个参数作为key,value是公共的Object对象 PRESENT
2.HashSet线程不安全案例
public class ContainerNotSafeDemo {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
for (int i = 1; i <= 3; i++) {
new Thread(() -> {
set.add(UUID.randomUUID().toString().substring(0 ,8));
System.out.println(set);
}, String.valueOf(i)).start();
}
}
}
当线程数量大一点,比如30时,会出现并发修改异常java.util.ConcurrentModificationException
3.线程安全解决方案
- 使用JDK提供的Collections工具类
Set<String> set = Collections.synchronizedSet(new HashSet<>()); - JUC下的CopyOnWriteArraySet
注意:CopyOnWriteArraySet的底层是通过CopyOnWriteArrayList实现的。Set<String> set = new CopyOnWriteArraySet<>();
4.set遍历的几种方式?
- for循环
for (String str : set) { System.out.println(str); } - iterator迭代器
Iterator<String> it = set.iterator(); while (it.hasNext()) { String str = it.next(); System.out.println(str); } - set.forEach(java8)
set.forEach(item -> { System.out.println(item); }); - set.stream().forEach(java8)
set.stream().forEach(item -> { System.out.println(item); });
总结:
- iterator 迭代器方式比 foreach 的效率高;
- forEach 最耗时;
- stream forEach 比较耗时和 for 循环差不多。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!