在本教程中,我們將借助示例學(xué)習(xí)Java TreeSet類及其各種操作和方法。
Java集合框架的TreeSet類提供樹數(shù)據(jù)結(jié)構(gòu)的功能。
它擴(kuò)展了NavigableSet接口。
為了創(chuàng)建樹集,我們必須首先導(dǎo)入java.util.TreeSet包。
導(dǎo)入包之后,下面是如何在Java中創(chuàng)建TreeSet。
TreeSet<Integer> numbers = new TreeSet<>();
在這里,我們創(chuàng)建了一個(gè)沒有任何參數(shù)的TreeSet。在本示例中,TreeSet中的元素自然排序(升序)。
但是,我們可以使用Comparator接口自定義元素的排序。 我們將在本教程的后面部分中學(xué)習(xí)它。
TreeSet類提供了各種方法,允許我們對(duì)集合執(zhí)行各種操作。
add() - 將指定的元素插入集合
addAll() - 將指定集合的所有元素插入集合
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> evenNumbers = new TreeSet<>(); // 使用 the add() 方法 evenNumbers.add(2); evenNumbers.add(4); evenNumbers.add(6); System.out.println("TreeSet: " + evenNumbers); TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(1); // 使用 the addAll() 方法 numbers.addAll(evenNumbers); System.out.println("新的TreeSet: " + numbers); } }
輸出結(jié)果
TreeSet: [2, 4, 6] 新的TreeSet: [1, 2, 4, 6]
要訪問樹集的元素,我們可以使用iterator()方法。為了使用這種方法,我們必須導(dǎo)入java.util.Iterator包。例如,
import java.util.TreeSet; import java.util.Iterator; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(2); numbers.add(5); numbers.add(6); System.out.println("TreeSet: " + numbers); // 調(diào)用 iterator() 方法 Iterator<Integer> iterate = numbers.iterator(); System.out.print("TreeSet使用迭代器: "); //訪問元素 while(iterate.hasNext()) { System.out.print(iterate.next()); System.out.print(", "); } } }
輸出結(jié)果
TreeSet: [2, 5, 6] TreeSet使用迭代器: 2, 5, 6,
remove() - 從集合中刪除指定的元素
removeAll() - 從集合中刪除所有元素
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(2); numbers.add(5); numbers.add(6); System.out.println("TreeSet: " + numbers); // 使用remove() 方法 boolean value1 = numbers.remove(5); System.out.println("5被刪除了? " + value1); // 使用removeAll() 方法 boolean value2 = numbers.removeAll(numbers); System.out.println("是否刪除了所有元素? " + value2); } }
輸出結(jié)果
TreeSet: [2, 5, 6] 5被刪除了? true 是否刪除了所有元素? true
因?yàn)門reeSet類實(shí)現(xiàn)了NavigableSet,所以它提供了各種方法來導(dǎo)航樹集的元素。
first() - 返回集合的第一個(gè)元素
last() - 返回集合的最后一個(gè)元素
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(2); numbers.add(5); numbers.add(6); System.out.println("TreeSet: " + numbers); // 使用 first() 方法 int first = numbers.first(); System.out.println("第一個(gè)數(shù)字: " + first); // 使用 last() 方法 int last = numbers.last(); System.out.println("最后一個(gè)數(shù)字: " + last); } }
輸出結(jié)果
TreeSet: [2, 5, 6] 第一個(gè)數(shù)字: 2 最后一個(gè)數(shù)字: 6
Higher(element) - 返回大于指定元素(element)的最小元素。
lower(element) - 返回小于指定元素(element)的最大元素。
ceiling(element) - 返回大于指定元素(element)的那些元素中的最小元素。如果傳遞的元素(element)存在于樹集中,則返回作為參數(shù)傳遞的元素(element)。
floor(element) - 返回小于指定元素(element)的元素中最大的元素。如果傳遞的元素(element)存在于樹集中,則返回作為參數(shù)傳遞的元素(element)。
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(2); numbers.add(5); numbers.add(4); numbers.add(6); System.out.println("TreeSet: " + numbers); // 使用 higher() System.out.println("使用 higher: " + numbers.higher(4)); // 使用 lower() System.out.println("使用 lower: " + numbers.lower(4)); // 使用 ceiling() System.out.println("使用 ceiling: " + numbers.ceiling(4)); // 使用 floor() System.out.println("使用 floor: " + numbers.floor(3)); } }
輸出結(jié)果
TreeSet: [2, 4, 5, 6] 使用 higher: 5 使用 lower: 2 使用 ceiling: 4 使用 floor: 2
pollFirst() - 返回并從集合中刪除第一個(gè)元素
pollLast() - 返回并從集合中刪除最后一個(gè)元素
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(2); numbers.add(5); numbers.add(4); numbers.add(6); System.out.println("TreeSet: " + numbers); // 使用 pollFirst() System.out.println("刪除第一個(gè)元素: " + numbers.pollFirst()); // 使用 pollLast() System.out.println("刪除最后一個(gè)元素: " + numbers.pollLast()); System.out.println("新的TreeSet: " + numbers); } }
輸出結(jié)果
TreeSet: [2, 4, 5, 6] 刪除第一個(gè)元素: 2 刪除最后一個(gè)元素: 6 新的TreeSet: [4, 5]
headSet()方法返回指定元素(作為參數(shù)傳遞)之前的樹集的所有元素。
booleanValue參數(shù)是可選的。默認(rèn)值為false。
如果booleanValue的值為true,則該方法返回指定元素之前的所有元素,包括指定元素。
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(2); numbers.add(5); numbers.add(4); numbers.add(6); System.out.println("TreeSet: " + numbers); // 使用 headSet()使用默認(rèn)的布爾值 System.out.println("使用不帶布爾值的headSet: " + numbers.headSet(5)); // 使用 headSet()使用指定的布爾值 System.out.println("將headSet與布爾值一起使用: " + numbers.headSet(5, true)); } }
輸出結(jié)果
TreeSet: [2, 4, 5, 6] 使用不帶布爾值的headSet: [2, 4] 將headSet與布爾值一起使用: [2, 4, 5]
tailSet()方法返回包含指定元素的指定元素(作為參數(shù)傳遞)之后的樹集的所有元素。
booleanValue參數(shù)是可選的。默認(rèn)值為true。
如果false作為a傳遞booleanValue,則該方法將返回指定后的所有元素,element而不包括指定的element。
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(2); numbers.add(5); numbers.add(4); numbers.add(6); System.out.println("TreeSet: " + numbers); // 使用 tailSet()使用默認(rèn)的布爾值 System.out.println("tailSet()使用默認(rèn)的布爾值: " + numbers.tailSet(4)); // 使用 tailSet() with specified boolean value System.out.println("tailSet()帶有布爾值: " + numbers.tailSet(4, false)); } }
輸出結(jié)果
TreeSet: [2, 4, 5, 6] 使用 tailSet()使用默認(rèn)的布爾值: [4, 5, 6] tailSet()帶有布爾值: [5, 6]
subSet()方法返回e1和e2之間的所有元素,包括e1。
bv1和bv2是可選參數(shù)。 bv1的默認(rèn)值為true,bv2的默認(rèn)值為false。
如果將false作為bv1傳遞,則該方法返回e1和e2之間的所有元素,而不包括e1。
如果將true作為bv2傳遞,則該方法返回e1和e2之間的所有元素,包括e1。
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(2); numbers.add(5); numbers.add(4); numbers.add(6); System.out.println("TreeSet: " + numbers); // 使用 subSet() with default boolean value System.out.println("subSet()使用默認(rèn)布爾值: " + numbers.subSet(4, 6)); // 使用 subSet() 使用指定的布爾值 System.out.println("subSet()使用指定的布爾值: " + numbers.subSet(4, false, 6, true)); } }
輸出結(jié)果
TreeSet: [2, 4, 5, 6] subSet()使用默認(rèn)布爾值: [4, 5] subSet()使用指定的布爾值: [5, 6]
TreeSet類的方法還可以用于執(zhí)行各種集合操作。
為了執(zhí)行兩個(gè)集合之間的并集,我們使用 addAll()方法。例如,
import java.util.TreeSet;; class Main { public static void main(String[] args) { TreeSet<Integer> evenNumbers = new TreeSet<>(); evenNumbers.add(2); evenNumbers.add(4); System.out.println("TreeSet1: " + evenNumbers); TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(1); numbers.add(2); numbers.add(3); System.out.println("TreeSet2: " + numbers); //兩個(gè)集合的并集 numbers.addAll(evenNumbers); System.out.println("Union is: " + numbers); } }
輸出結(jié)果
TreeSet1: [2, 4] TreeSet2: [1, 2, 3] 并集: [1, 2, 3, 4]
為了執(zhí)行兩個(gè)集合之間的交集,我們使用retainAll()方法。例如,
import java.util.TreeSet;; class Main { public static void main(String[] args) { TreeSet<Integer> evenNumbers = new TreeSet<>(); evenNumbers.add(2); evenNumbers.add(4); System.out.println("TreeSet1: " + evenNumbers); TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(1); numbers.add(2); numbers.add(3); System.out.println("TreeSet2: " + numbers); // 兩個(gè)集合的交集 numbers.retainAll(evenNumbers); System.out.println("集合的交集: " + numbers); } }
輸出結(jié)果
TreeSet1: [2, 4] TreeSet2: [1, 2, 3] 集合的交集: [2]
要計(jì)算兩組之間的差集,我們可以使用removeAll()方法。例如,
import java.util.TreeSet;; class Main { public static void main(String[] args) { TreeSet<Integer> evenNumbers = new TreeSet<>(); evenNumbers.add(2); evenNumbers.add(4); System.out.println("TreeSet1: " + evenNumbers); TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(1); numbers.add(2); numbers.add(3); numbers.add(4); System.out.println("TreeSet2: " + numbers); //集合的差集 numbers.removeAll(evenNumbers); System.out.println("差集: " + numbers); } }
輸出結(jié)果
TreeSet1: [2, 4] TreeSet2: [1, 2, 3, 4] 差集: [1, 3]
為了檢查一個(gè)集合是否是另一個(gè)集合的子集,我們使用containsAll()方法。例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(1); numbers.add(2); numbers.add(3); numbers.add(4); System.out.println("TreeSet1: " + numbers); TreeSet<Integer> primeNumbers = new TreeSet<>(); primeNumbers.add(2); primeNumbers.add(3); System.out.println("TreeSet2: " + primeNumbers); //檢查primeNumbers是否為numbers子集 boolean result = numbers.containsAll(primeNumbers); System.out.println("TreeSet2是TreeSet1的子集嗎? " + result); } }
輸出結(jié)果
TreeSet1: [1, 2, 3, 4] TreeSet2: [2, 3] TreeSet2是TreeSet1的子集嗎? True
方法 | 描述 |
---|---|
clone() | 創(chuàng)建TreeSet的副本 |
contains() | 在TreeSet中搜索指定的元素并返回布爾結(jié)果 |
isEmpty() | 檢查是否TreeSet為空 |
size() | 返回TreeSet的大小 |
clear() | 從TreeSet中刪除所有元素 |
TreeSet和HashSet都實(shí)現(xiàn)了Set接口。然而,它們之間存在著一些區(qū)別。
與HashSet不同,TreeSet中的元素是以某種順序存儲(chǔ)的。這是因?yàn)門reeSet還實(shí)現(xiàn)了SortedSet接口。
TreeSet提供了一些易于導(dǎo)航的方法。 例如first(),last(),headSet(),tailSet()等。這是因?yàn)門reeSet還實(shí)現(xiàn)了NavigableSet接口。
對(duì)于添加、刪除、包含和大小等基本操作,HashSet比TreeSet更快。
在以上所有示例中,樹集元素都是自然排序的。但是,我們也可以自定義元素的順序。
為此,我們需要?jiǎng)?chuàng)建自己的comparator類,基于對(duì)樹集中的元素進(jìn)行排序。例如
import java.util.TreeSet; import java.util.Comparator; class Main { public static void main(String[] args) { //使用自定義比較器創(chuàng)建TreeSet TreeSet<String> animals = new TreeSet<>(new CustomComparator()); animals.add("Dog"); animals.add("Zebra"); animals.add("Cat"); animals.add("Horse"); System.out.println("TreeSet: " + animals); } //創(chuàng)建一個(gè)比較器類 public static class CustomComparator implements Comparator<String> { @Override public int compare(String animal1, String animal2) { int value = animal1.compareTo(animal2); //元素以相反的順序排序 if (value > 0) { return -1; } else if (value < 0) { return 1; } else { return 0; } } } }
輸出結(jié)果
TreeSet: [Zebra, Horse, Dog, Cat]
在上面的示例中,我們創(chuàng)建了一個(gè)樹集,將CustomComparator類作為參數(shù)傳遞。
CustomComparator類實(shí)現(xiàn)了Comparator接口。
然后,我們重寫compare()方法?,F(xiàn)在,該方法將以相反的順序?qū)υ剡M(jìn)行排序。