详解关于Set、HashSet、Arrays.asList的一句经典代码
private Set<String> isxxSector = new HashSet<>(Arrays.asList("0100", "0251", "0252", "0241", "0242", "0211", "0200"));
1. 代码中的每个部分含义
private:访问修饰符,表示该属性只能在当前类中访问,外部无法直接访问。
Set<String>:使用了Set集合,泛型参数<String>表示该集合只能存储字符串类型的数据。
isxxSector:变量名,表示该字段是一个Set类型的属性。
= new HashSet<>():创建一个新的HashSet对象。
HashSet是Set接口的一种实现,具有以下特点:
✅ 无序:元素的存储顺序与插入顺序无关。
✅ 不允许重复:相同的元素只能存在一次。
Arrays.asList(...):将指定的字符串数组快速转换为一个固定长度的List(ArrayList),然后传递给HashSet进行初始化。
2. 代码的实际作用
✅ 创建了一个不可重复、无序的Set集合,并初始化了以下字符串元素:
"0100", "0251", "0252", "0241", "0242", "0211", "0200"
3. 为什么要使用Set而不是List?
使用Set的原因主要有以下几个:
✅ 数据去重:Set具有去重特性,如果这些编码可能存在重复数据,Set 会自动处理。
✅ 快速查找:HashSet的底层基于哈希表,查找、添加、删除的时间复杂度为O(1),性能优于List。
✅ 无序性:Set不保证元素的顺序(如果不关心顺序,Set会更合适)。
4. Arrays.asList()的注意点
Arrays.asList()创建的List是固定长度的:
- 不能add()、remove(),否则会抛出 UnsupportedOperationException 异常。
- set()方法可用于修改已有元素。
✅ 转成 HashSet 后,这些限制就不再存在,因为 HashSet是可变集合。
这句代码的本质就是将一个固定长度的Arrays.asList()转换成一个可变集合HashSet,从而实现后续的增删改查操作。
1. 代码解读(逐步剖析)
原代码
private Set<String> iscpSector = new HashSet<>(Arrays.asList("0100", "0251", "0252", "0241", "0242", "0211", "0200"));
分解步骤
🔹 Step 1:Arrays.asList() 转换成List(固定长度)
List<String> fixedList = Arrays.asList("0100", "0251", "0252", "0241", "0242", "0211", "0200");
示例:
fixedList.add("0300"); // ❌ 报错:UnsupportedOperationException fixedList.set(0, "0300"); // ✅ 成功修改
🔹 Step 2:将List转换成HashSet(可变集合)
Set<String> iscpSector = new HashSet<>(fixedList);
- HashSet接收List作为参数,完成初始化。
- 由于HashSet的本质是无序且唯一,即使Arrays.asList()中存在重复元素,HashSet也会自动去重。
- 现在的iscpSector已变成一个可变集合,支持add()、remove()、clear()等操作。
🔹 Step 3:操作HashSet
iscpSector.add("0300"); // ✅ 可新增 iscpSector.remove("0100"); // ✅ 可删除 System.out.println(iscpSector);
输出:
[0211, 0252, 0251, 0300, 0241, 0242, 0200]
2. 为什么Arrays.asList()返回的是固定长度?
Arrays.asList()返回的是java.util.Arrays类的一个内部静态类ArrayList,它与java.util.ArrayList并不相同。
- Arrays.asList()返回的ArrayList本质上只是原始数组的视图(View)。
- 修改List中的元素,相当于修改原始数组中的元素。
- 但是,无法改变List的长度(即不能 add() / remove())。
示例
String[] arr = {"A", "B", "C"}; List<String> list = Arrays.asList(arr); list.set(0, "X"); // ✅ 修改成功,arr[0] 也变成了 "X" list.add("D"); // ❌ 报错:UnsupportedOperationException
3. 为什么要用HashSet转换?
✅ HashSet是可变集合,支持add()、remove()、clear()等方法。
✅ HashSet 具有唯一性,可自动去重。
✅ HashSet 查找性能优于 List,在数据量较大时效率更高。
4. 更简洁的写法(推荐使用)
如果你使用的是JDK 9+,推荐使用Set.of(),更简洁优雅:
private Set<String> iscpSector = new HashSet<>(Set.of("0100", "0251", "0252", "0241", "0242", "0211", "0200"));
或者更进一步,如果无需修改数据:
private Set<String> iscpSector = Set.of("0100", "0251", "0252", "0241", "0242", "0211", "0200");
🚨 注意:Set.of() 生成的Set是不可变集合,无法执行add()或remove()操作。
5. 等效写法
这行代码的作用也可以用其他方式实现:
✅ 更简洁的写法(推荐使用) — JDK 9+ 支持
private Set<String> iscpSector = Set.of("0100", "0251", "0252", "0241", "0242", "0211", "0200");
Set.of() 特点:自动去重(若存在重复元素会报错)。
返回的是不可变集合,无法修改。
✅ 传统写法(更直观)
private Set<String> iscpSector = new HashSet<>(); static { iscpSector.add("0100"); iscpSector.add("0251"); iscpSector.add("0252"); iscpSector.add("0241"); iscpSector.add("0242"); iscpSector.add("0211"); iscpSector.add("0200"); }