📅  最后修改于: 2023-12-03 15:31:49.155000             🧑  作者: Mango
在Java中,HashSet
、LinkedHashSet
和TreeSet
都是用于存储一组不重复元素的集合类。虽然它们都具有相似的用途,但是它们的实现和使用方式有所不同,下面逐一介绍这些类的异同点。
HashSet
是基于哈希表实现的集合类,它存储的元素无序且不重复。底层实现使用了HashMap
(也是基于哈希表实现)来存储元素。具体来说,在HashSet
中添加元素时,会将元素作为HashMap
的键,使用一个空对象作为值,将键值对存储到HashMap
中。由于哈希表的特性,元素的存储和查找速度非常快。
下面是HashSet
的创建和使用示例代码:
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("pear");
System.out.println(set); // [pear, banana, apple]
上述代码创建了一个HashSet
集合,并向其中添加了三个元素。由于HashSet
无序,输出结果并不保证是按照添加顺序排列的。
LinkedHashSet
同样存储无序不重复元素,它的实现基于哈希表和链表。与HashSet
相比,LinkedHashSet
中的元素维护了一个插入顺序。这是通过使用一个双向链表来实现的,每次添加元素时,元素既被添加到了哈希表中,又被添加到了链表的尾部。
下面是LinkedHashSet
的创建和使用示例代码:
Set<String> set = new LinkedHashSet<>();
set.add("apple");
set.add("banana");
set.add("pear");
System.out.println(set); // [apple, banana, pear]
上述代码创建了一个LinkedHashSet
集合,并向其中添加了三个元素。由于LinkedHashSet
维护了插入顺序,输出结果保证是按照添加顺序排列的。
TreeSet
同样存储无序不重复元素,它的实现基于红黑树来实现。与哈希表不同,红黑树存储的元素是有序的。每次添加元素时,它都会在树中找到合适的位置,以保证元素的有序性。
TreeSet
的排序方式有两种:自然排序和定制排序。在自然排序中,元素要么实现了Comparable
接口,要么使用了默认的比较器(比如String
的字典序)。在定制排序中,需要提供一个Comparator
接口实现,用于定义元素的比较方式。
下面是TreeSet
的创建和使用示例代码:
Set<String> set = new TreeSet<>();
set.add("apple");
set.add("banana");
set.add("pear");
System.out.println(set); // [apple, banana, pear]
Set<Integer> set2 = new TreeSet<>((o1, o2) -> o2 - o1);
set2.add(3);
set2.add(1);
set2.add(2);
System.out.println(set2); // [3, 2, 1]
上述代码创建了两个TreeSet
集合,并向其中添加了多个元素。第一个集合是按照元素的字典序进行排序的,第二个集合使用了定制排序器,按照元素的降序排列。
| 类别 | HashSet | LinkedHashSet | TreeSet | | ------------ | ------------ | ------------- | ------------- | | 存储方式 | 哈希表 | 哈希表+链表 | 红黑树 | | 存储顺序 | 无序 | 插入顺序 | 有序 | | 元素排序方式 | 无序 | 无序 | 自然排序/定制排序 | | 性能 | 快(适用于查找和存储大量元素) | 介于HashSet和TreeSet之间 | 慢(适用于需要有序存储和查找元素) |
从上表可以看出,不同类型的集合类在实现和使用上都略有不同。程序员在使用的时候可以根据自己的需求进行选择。需要快速存储和查找元素时可以使用HashSet
,需要有序存储和查找元素时可以使用TreeSet
。如果有序性不是很重要,但是需要维护插入顺序时,则可以使用LinkedHashSet
。