📜  Java中HashSet、LinkedHashSet、TreeSet的异同(1)

📅  最后修改于: 2023-12-03 15:31:49.155000             🧑  作者: Mango

Java中HashSet、LinkedHashSet、TreeSet的异同

在Java中,HashSetLinkedHashSetTreeSet都是用于存储一组不重复元素的集合类。虽然它们都具有相似的用途,但是它们的实现和使用方式有所不同,下面逐一介绍这些类的异同点。

HashSet

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

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同样存储无序不重复元素,它的实现基于红黑树来实现。与哈希表不同,红黑树存储的元素是有序的。每次添加元素时,它都会在树中找到合适的位置,以保证元素的有序性。

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