Java HashSet、LinkedHashSet和TreeSet的区别和相似之处
在这篇文章中,我们将学习,HashSet与LinkedHashSet和TreeSet的区别以及LinkedHashSet和TreeSet的相似之处。HashSet、LinkedHashSet和TreeSet都实现了Set接口。因此,我们试图列出java中HashSet、LinkedHashSet和TreeSet的区别和相似之处。
HashSet、LinkedHashSet 和TreeSet 之间的区别
特点 | HashSet | LinkedHashSet | TreeSet |
---|---|---|---|
内部工作 | HashSet内部使用HashMap来存储对象。 | LinkedHashSet内部使用LinkedHashMap来存储对象。 | TreeSet内部使用TreeMap来存储对象 |
何时使用 | 如果你不想保持插入的顺序,但想存储唯一的对象 | 如果你想保持元素的插入顺序,那么你可以使用LinkedHashSet。 | 如果你想根据一些比较器来对元素进行排序,那么可以使用TreeSet |
顺序 | HashSet不维护插入顺序 | LinkedHashSet维护对象的插入顺序 | 而TreeSet根据提供的比较器来排序元素。默认情况下,对象将按照它们的自然升序来放置。 |
操作的复杂性 | HashSet对于插入、移除和检索对象给出了O(1)的复杂度。 | LinkedHashSet给出了O(1)级的插入、移除和检索操作性能。 | 而TreeSet在插入、移除和检索操作中给出了O(log(n))的性能。 |
性能表现 | 与LinkedHashSet和TreeSet相比,HashSet的性能更好。 | LinkedHashSet的性能要比TreeSet慢一些。它几乎与HashSet相似,但是速度较慢,因为LinkedHashSet在内部维护LinkedList来维护元素的插入顺序。 | 除了插入和移除操作,TreeSet的性能比LinkedHashSet好,因为它必须在每次插入和移除操作之后对元素进行排序。 |
比较 | HashSet使用equals()和hashCode()方法来比较对象。 | LinkedHashSet使用equals()和hashCode()方法来比较它的对象。 | TreeSet使用compare()和compareTo()方法来比较对象。 |
空值元素 | HashSet只允许一个空值。 | LinkedHashSet只允许一个空值。 | TreeSet不允许空值。如果你在TreeSet中插入空值,它将抛出NullPointerException。 |
语法 | HashSet obj = new HashSet(); | LinkedHashSet obj = new LinkedHashSet(); | TreeSet obj = new TreeSet(); |
HashSet、LinkedHashSet 和TreeSet在插入顺序和所需时间方面 的区别 :
// Java program to demonstrate difference between
// HashSet, LinkedHashSet and TreeSet according
// to insertion order and insertion time
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
class GFG1 {
// Function show insertion order of
// LinkedHashSet, TreeSet and HashSet
private static void insertionOrder()
{
LinkedHashSet<String> geekLinkSet
= new LinkedHashSet<>();
TreeSet<String> geekTreeSet = new TreeSet<>();
HashSet<String> geekHashSet = new HashSet<String>();
// Add three object in
// LinkedHashSet and TreeSet
for (String str : Arrays.asList("Geek2", "Geek1",
"Geek3", "Geek1")) {
geekLinkSet.add(str);
geekTreeSet.add(str);
geekHashSet.add(str);
}
// should be sorted order HashSet
// stores element in sorted order
System.out.println("Insertion Order"
+ " of objects in HashSet :"
+ geekHashSet);
// insertion order or elements LinkedHashSet
// stores elements as insertion
System.out.println("Insertion Order of "
+ "objects in LinkedHashSet :"
+ geekLinkSet);
// should be sorted order TreeSet
// stores element in sorted order
System.out.println("Insertion Order of"
+ " objects in TreeSet :"
+ geekTreeSet);
}
// Function calculate insertion time of
// 1000 objects of LinkedHashSet,
// TreeSet and HashSet
private static void insertionTime()
{
// HashSet performance Test
// inserting 1000 elements
HashSet<Integer> numbersHS = new HashSet<>();
long startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
numbersHS.add(i);
}
long endTime = System.nanoTime();
System.out.println("Total time to insert"
+ " 1000 elements in"
+ " HashSet in nanoseconds: "
+ (endTime - startTime));
// LinkedHashSet performance Test
// inserting 1000 elements
LinkedHashSet<Integer> numbersLLS
= new LinkedHashSet<>();
startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
numbersLLS.add(i);
}
endTime = System.nanoTime();
System.out.println("Total time to insert"
+ " 1000 elements in"
+ " LinkedHashSet nanoseconds: "
+ (endTime - startTime));
// TreeSet performance Test inserting 1000 objects
TreeSet<Integer> numbersTS = new TreeSet<>();
startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
numbersTS.add(i);
}
endTime = System.nanoTime();
System.out.println("Total time to insert"
+ " 1000 elements in"
+ " TreeSet in nanoseconds: "
+ (endTime - startTime));
}
// Function calculate deletion time
// of 1000 objects LinkedHashSet,
// TreeSet and HashSet
// Deletion time always vary
private static void deletion()
{
// HashSet performance Test inserting
// and deletion 1000 elements
HashSet<Integer> deletionHS = new HashSet<>();
for (int i = 0; i < 1000; i++) {
deletionHS.add(i);
}
long startingTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
deletionHS.remove(i);
}
long endedTime = System.nanoTime();
System.out.println(
"Total time to Deletion "
+ "1000 elements in HashSet in nanoseconds: "
+ Math.abs(startingTime - endedTime));
// LinkedHashSet performance Test inserting
// and deletion 1000 elements
LinkedHashSet<Integer> deletionLLS
= new LinkedHashSet<>();
for (int i = 0; i < 1000; i++) {
deletionLLS.add(i);
}
startingTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
deletionLLS.remove(i);
}
endedTime = System.nanoTime();
System.out.println(
"Total time to Deletion 1000"
+ " elements in LinkedHashSet in nanoseconds: "
+ Math.abs(startingTime - endedTime));
// TreeSet performance Test inserting
// and deletion 1000 elements
TreeSet<Integer> deletionTS = new TreeSet<>();
for (int i = 0; i < 1000; i++) {
deletionTS.add(i);
}
startingTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
deletionTS.remove(i);
}
endedTime = System.nanoTime();
System.out.println(
"Total time to Deletion 1000"
+ " elements in TreeSet in nanoseconds: "
+ Math.abs(startingTime - endedTime));
}
public static void main(String args[])
{
insertionOrder();
insertionTime();
deletion();
}
}
输出
Insertion Order of objects in HashSet :[Geek3, Geek2, Geek1]
Insertion Order of objects in LinkedHashSet :[Geek2, Geek1, Geek3]
Insertion Order of objects in TreeSet :[Geek1, Geek2, Geek3]
Total time to insert 1000 elements in HashSet in nanoseconds: 791869
Total time to insert 1000 elements in LinkedHashSet nanoseconds: 882417
Total time to insert 1000 elements in TreeSet in nanoseconds: 11797657
Total time to Deletion 1000 elements in HashSet in nanoseconds: 834509
Total time to Deletion 1000 elements in LinkedHashSet in nanoseconds: 898922
Total time to Deletion 1000 elements in TreeSet in nanoseconds: 7437577
HashSet, LinkedHashSet和TreeSet 之间的相似之处
- 重复的对象。HashSet、LinkedHashSet和TreeSet都实现了Set接口,所以它们不允许存储重复的对象。
-
线程安全。如果我们想在多线程环境中使用HashSet、LinkedHashSet和TreeSet,那么首先要让它在外部同步,因为LinkedHashSet和TreeSet都不是线程安全的。
-
这三个都是可克隆和可序列化的。
在 Java中 何时使用HashSet、TreeSet 和LinkedHashSet
- HashSet: 如果你不想保持插入的顺序,但想存储唯一的对象。
- LinkedHashSet :如果你想保持元素的插入顺序,那么你可以使用LinkedHashSet。
- TreeSet: 如果你想根据一些比较器来对元素进行排序,那么可以使用TreeSet。
因此,正如你所看到的上述程序的输出,根据你的要求,你可以从HashSet、TreeSet和LinkedHashSet中选择任何一个。