List:ArrayList
Map:HashMap、TreeMap
Set:HashSet
使用场景ArrayList:有序集合,底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素。
//字符串集合 Listlist = new ArrayList (); list.add("张三"); list.add("李四"); list.add("王五"); //可重复 list.add("张三"); System.out.println(sites); // [张三, 李四, 王五,张三] //适用于通过下标获取数据结构中的元素,如需获取第二个元素 String content = list.get(1); System.out.println(content); // 李四
HashMap:散列表,它存储的内容是键值对(key-value)映射,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
//构造参数填"4"和不填的区分,可自行查阅资料 Mapmap = new HashMap (4); // 添加键值对 map.put(1, "张三"); map.put(2, "李四"); map.put(3, "王五"); System.out.println(map); // {1=张三, 2=李四, 3=王五} //覆盖key为2的值 map.put(2, "刘六"); System.out.println(map); // {1=张三, 2=刘六, 3=王五} //适用于通过元素对象的"特征"查找对应的元素,如需通过元素对象的编码获取对应的值 String content = map.get(2); // 获取编号为2的值 System.out.println(content); // 李四
TreeMap:非线程安全基于红黑树实现,与HashMap相比,TreeMap是一个能比较元素大小的Map集合,会对传入的key进行了大小排序。其中,可以使用元素的自然顺序,也可以使用集合中自定义的比较器来进行排序。
//适用于按自然顺序或自定义顺序遍历键(key),按照字典序输出可采用TreeMap方式实现
HashSet:底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的。
Set遍历方式set = new HashSet (); set.add("张三"); set.add("李四"); set.add("王五"); //重复项 set.add("李四"); System.out.println(set); // [张三,李四,王五] //适用于对元素集合做去重处理
《阿里巴巴 Java 开发手册》的描述如下:
不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。
通过反编译会发现 foreach 语法糖底层其实还是依赖 Iterator 。不过, remove/add 操作直接调用的是集合自己的方法,而不是 Iterator 的 remove/add方法,有兴趣可以看一下源码。
这就导致 Iterator 莫名其妙地发现自己有元素被 remove/add ,然后,它就会抛出一个 ConcurrentModificationException 来提示用户发生了并发修改异常。
Java8 开始,可以使用 Collection#removeIf()方法删除满足特定条件的元素
Listlist = new ArrayList<>(); for (int i = 1; i <= 10; ++i) { list.add(i); } list.removeIf(filter -> filter % 2 == 0); // 删除list中的所有偶数 System.out.println(list); // [1, 3, 5, 7, 9]
所以一般遍历集合推荐使用Iterator迭代器,或者是使用普通的for循环。如果不需要操作元素,就怎么方便怎么来都行。



