关于Set —— 莫把Set与Map搞混淆

1.Set和Map的本质区别

数据结构

仅存储唯一的值

存储键值对 (key-value)

是否成对

❌ 只存值,没有 key

✅ 每个 value 都有对应的 key

数据存储

HashSet、TreeSet、LinkedHashSet

HashMap、TreeMap、LinkedHashMap

查找性能

查找、添加、删除的效率为 O(1)

(HashSet)

查找、添加、删除的效率为

O(1) (HashMap)

数据去重

✅ 自动去重

✅ Key 自动去重,Value 不去重

元素顺序

❌ 无序 (HashSet)

❌ 无序 (HashMap)

2.Set<String>的本质

Set只存储值(Value),并不存储 key

那为什么Set还能做到"唯一性"呢?

Set的底层实现利用了哈希表(HashSet)或树(TreeSet)的数据结构。

在HashSet中:

  • 每个元素都会根据其哈希值 (Hash Code) 来定位存储位置。
  • 在存储时,如果哈希值已存在,就不会再添加该元素,从而实现唯一性。

🚨关键点:Set并不需要显式地存储key,因为 HashSet 的底层机制就是将每个元素的哈希值作为其"定位点"(相当于隐形的key)。

3.Set的实际应用场景

尽管Set只有值,但在以下场景中非常实用:

✅ (1) 数据去重

当需要在一堆数据中提取唯一元素时,Set是最佳选择。

Set<String> uniqueNames = new HashSet<>(Arrays.asList("Alice", "Bob", "Alice", "Charlie"));
System.out.println(uniqueNames); // 输出: [Alice, Bob, Charlie]

✅ (2) 快速查找

HashSet查找元素的速度远快于List,尤其在数据量较大时。

Set<String> codes = new HashSet<>(Arrays.asList("0100", "0251", "0252"));
if (codes.contains("0100")) {
    System.out.println("找到编码0100");
}

✅ (3) 集合运算(交集、并集、差集)

Set提供了快速的集合运算支持:

Set<String> set1 = new HashSet<>(Arrays.asList("A", "B", "C"));
Set<String> set2 = new HashSet<>(Arrays.asList("B", "C", "D"));

// 求交集
set1.retainAll(set2); 
System.out.println(set1);  // 输出: [B, C]

4. 为什么Set适合iscpSector这种编码集合?

在你的代码中:

private Set<String> iscpSector = new HashSet<>(Arrays.asList("0100", "0251", "0252", "0241", "0242", "0211", "0200"));

✅ 编码数据本身不需要 key,只需记录一组唯一值。

✅ Set能自动去重,避免因重复编码而出错。

✅ HashSet查找效率高,判断 "0100" 是否存在的效率远高于List。

5.如果需要key-value形式怎么办?

如果你的数据确实是成对的(即 key-value),应该使用Map,而不是Set。

示例:使用Map存储key-value

Map<String, String> serviceMap = new HashMap<>();
serviceMap.put("0100", "水运干线");
serviceMap.put("0251", "集港");
serviceMap.put("0252", "疏港");

Set适合仅存储唯一值

Map适合存储key-value键值对

6.总结

🔹 Set不存储key,它本质上只有value。

🔹 Set的“唯一性”是靠哈希值自动实现的,不需要显式的key。

🔹 在你的代码中,iscpSector只是一组编码,使用Set更合适。

🔹 如果你要存储的是 "编码 → 描述" 的形式(如 "0100" → "水运干线"),就应该使用 Map

全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务