Java TreeSet

Java collections framework 的 TreeSet 类提供了树形数据结构的功能。

它实现了 NavigableSet 接口。

Java TreeSet class implements the NavigableSet interface.


创建 TreeSet

为了创建树集,我们必须先导入 java.util.TreeSet 包。

导入包后,我们可以这样在 Java 中创建 TreeSet


TreeSet<Integer> numbers = new TreeSet<>();

在这里,我们创建了一个不带任何参数的 TreeSet。在这种情况下,TreeSet 中的元素会按自然顺序(升序)排序。

但是,我们可以使用 Comparator 接口来自定义元素的排序。我们将在本教程后面学习它。


TreeSet 的方法

TreeSet 类提供了各种方法,允许我们对集合执行各种操作。


向 TreeSet 插入元素

  • add() - 将指定的元素插入到集合中
  • addAll() - 将指定集合中的所有元素插入到集合中

例如,

import java.util.TreeSet;

class Main {
    public static void main(String[] args) {

        TreeSet<Integer> evenNumbers = new TreeSet<>();

        // Using the add() method
        evenNumbers.add(2);
        evenNumbers.add(4);
        evenNumbers.add(6);
        System.out.println("TreeSet: " + evenNumbers);

        TreeSet<Integer> numbers = new TreeSet<>();
        numbers.add(1);

        // Using the addAll() method
        numbers.addAll(evenNumbers);
        System.out.println("New TreeSet: " + numbers);
    }
}

输出

TreeSet: [2, 4, 6]
New TreeSet: [1, 2, 4, 6]

访问 TreeSet 元素

要访问树集的元素,我们可以使用 iterator() 方法。为了使用此方法,我们必须导入 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);

        // Calling iterator() method
        Iterator<Integer> iterate = numbers.iterator();
        System.out.print("TreeSet using Iterator: ");
        // Accessing elements
        while(iterate.hasNext()) {
            System.out.print(iterate.next());
            System.out.print(", ");
        }
    }
}

输出

TreeSet: [2, 5, 6]
TreeSet using Iterator: 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);

        // Using the remove() method
        boolean value1 = numbers.remove(5);
        System.out.println("Is 5 removed? " + value1);

        // Using the removeAll() method
        boolean value2 = numbers.removeAll(numbers);
        System.out.println("Are all elements removed? " + value2);
    }
}

输出

TreeSet: [2, 5, 6]
Is 5 removed? true
Are all elements removed? true

由于 TreeSet 类实现了 NavigableSet,因此它提供了各种方法来遍历树集中的元素。

1. first() 和 last() 方法

  • first() - 返回集合中的第一个元素
  • last() - 返回集合中的最后一个元素

例如,

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);

        // Using the first() method
        int first = numbers.first();
        System.out.println("First Number: " + first);

        // Using the last() method
        int last = numbers.last();
        System.out.println("Last Number: " + last);
    }
}

输出

TreeSet: [2, 5, 6]
First Number: 2
Last Number: 6

2. ceiling()、floor()、higher() 和 lower() 方法

  • higher(element) - 返回大于指定 element 的元素中最小的那个。
  • lower(element) - 返回小于指定 element 的元素中最大的那个。
  • ceiling(element) - 返回大于指定 element 的元素中最小的那个。如果传递的 element 存在于树集中,则返回作为参数传递的 element
  • floor(element) - 返回小于指定 element 的元素中最大的那个。如果传递的 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);

        // Using higher()
        System.out.println("Using higher: " + numbers.higher(4));

        // Using lower()
        System.out.println("Using lower: " + numbers.lower(4));

        // Using ceiling()
        System.out.println("Using ceiling: " + numbers.ceiling(4));

        // Using floor()
        System.out.println("Using floor: " + numbers.floor(3));

    }
}

输出

TreeSet: [2, 4, 5, 6]
Using higher: 5
Using lower: 2
Using ceiling: 4
Using floor: 2

3. pollfirst() 和 pollLast() 方法

  • pollFirst() - 返回并移除集合中的第一个元素
  • pollLast() - 返回并移除集合中的最后一个元素

例如,

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);

        // Using pollFirst()
        System.out.println("Removed First Element: " + numbers.pollFirst());

        // Using pollLast()
        System.out.println("Removed Last Element: " + numbers.pollLast());

        System.out.println("New TreeSet: " + numbers);
    }
}

输出

TreeSet: [2, 4, 5, 6]
Removed First Element: 2
Removed Last Element: 6
New TreeSet: [4, 5]

4. headSet()、tailSet() 和 subSet() 方法


headSet(element, booleanValue)

headSet() 方法返回树集中指定 element(作为参数传递)之前的所有元素。

booleanValue 参数是可选的。它的默认值为 false

如果将 true 作为 booleanValue 传递,则该方法返回指定元素之前的所有元素,包括指定的元素。

例如,

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);

        // Using headSet() with default boolean value
        System.out.println("Using headSet without boolean value: " + numbers.headSet(5));

        // Using headSet() with specified boolean value
        System.out.println("Using headSet with boolean value: " + numbers.headSet(5, true));
    }
}

输出

TreeSet: [2, 4, 5, 6]
Using headSet without boolean value: [2, 4]
Using headSet with boolean value: [2, 4, 5]

tailSet(element, booleanValue)

tailSet() 方法返回树集中指定 element(作为参数传递)之后的所有元素,包括指定的 element

booleanValue 参数是可选的。它的默认值为 true

如果将 false 作为 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);

        // Using tailSet() with default boolean value
        System.out.println("Using tailSet without boolean value: " + numbers.tailSet(4));

        // Using tailSet() with specified boolean value
        System.out.println("Using tailSet with boolean value: " + numbers.tailSet(4, false));
    }
}

输出

TreeSet: [2, 4, 5, 6]
Using tailSet without boolean value: [4, 5, 6]
Using tailSet with boolean value: [5, 6]

subSet(e1, bv1, e2, bv2)

subSet() 方法返回 e1e2 之间的所有元素,包括 e1

bv1bv2 是可选参数。 bv1 的默认值为 truebv2 的默认值为 false

如果将 false 作为 bv1 传递,则该方法返回 e1e2 之间的所有元素,但不包括 e1

如果将 true 作为 bv2 传递,则该方法返回 e1e2 之间的所有元素,包括 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);

        // Using subSet() with default boolean value
        System.out.println("Using subSet without boolean value: " + numbers.subSet(4, 6));

        // Using subSet() with specified boolean value
        System.out.println("Using subSet with boolean value: " + numbers.subSet(4, false, 6, true));
    }
}

输出

TreeSet: [2, 4, 5, 6]
Using subSet without boolean value: [4, 5]
Using subSet with boolean value: [5, 6]

集合运算

TreeSet 类的方法也可以用于执行各种集合操作。


集合的并集

为了执行两个集合之间的并集,我们使用 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);

        // Union of two sets
        numbers.addAll(evenNumbers);
        System.out.println("Union is: " + numbers);

    }
}

输出

TreeSet1: [2, 4]
TreeSet2: [1, 2, 3]
Union is: [1, 2, 3, 4]

集合的交集

为了执行两个集合之间的交集,我们使用 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);

        // Intersection of two sets
        numbers.retainAll(evenNumbers);
        System.out.println("Intersection is: " + numbers);
    }
}

输出

TreeSet1: [2, 4]
TreeSet2: [1, 2, 3]
Intersection is: [2]

集合的差集

要计算两个集合之间的差集,我们可以使用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);

        // Difference between two sets
        numbers.removeAll(evenNumbers);
        System.out.println("Difference is: " + numbers);
    }
}

输出

TreeSet1: [2, 4]
TreeSet2: [1, 2, 3, 4]
Difference is: [1, 3]

集合的子集

为了检查一个集合是否是另一个集合的子集,我们使用 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);

        // Check if primeNumbers is subset of numbers
        boolean result = numbers.containsAll(primeNumbers);
        System.out.println("Is TreeSet2 subset of TreeSet1? " + result);
    }
}

输出

TreeSet1: [1, 2, 3, 4]
TreeSet2: [2, 3]
Is TreeSet2 subset of TreeSet1? True

TreeSet 的其他方法

方法 描述
clone() 创建 TreeSet 的副本
contains() 搜索 TreeSet 中指定的元素并返回布尔结果
isEmpty() 检查 TreeSet 是否为空
size() 返回 TreeSet 的大小
clear() TreeSet 中移除所有元素

要了解更多信息,请访问 Java TreeSet (官方 Java 文档)


TreeSet 与 HashSet

TreeSetHashSet 都实现了 Set 接口。但是,它们之间存在一些差异。

  • HashSet 不同,TreeSet 中的元素是按某种顺序存储的。这是因为 TreeSet 也实现了 SortedSet 接口。
  • TreeSet 提供了一些方便导航的方法。例如,first()last()headSet()tailSet() 等。这是因为 TreeSet 还实现了 NavigableSet 接口。
  • 对于 add、remove、contains 和 size 等基本操作,HashSetTreeSet 更快。

TreeSet Comparator

在以上所有示例中,树集元素均按自然顺序排序。但是,我们也可以自定义元素的排序。

为此,我们需要创建自己的比较器类,树集中的元素将根据该类进行排序。例如,

import java.util.TreeSet;
import java.util.Comparator;

class Main {
    public static void main(String[] args) {

        // Creating a tree set with a customized comparator
        TreeSet<String> animals = new TreeSet<>(new CustomComparator());

        animals.add("Dog");
        animals.add("Zebra");
        animals.add("Cat");
        animals.add("Horse");
        System.out.println("TreeSet: " + animals);
    }

    // Creating a comparator class
    public static class CustomComparator implements Comparator<String> {

        @Override
        public int compare(String animal1, String animal2) {
            int value =  animal1.compareTo(animal2);

            // elements are sorted in reverse order
            if (value > 0) {
                return -1;
            }
            else if (value < 0) {
                return 1;
            }
            else {
                return 0;
            }
        }
    }
}

输出

TreeSet: [Zebra, Horse, Dog, Cat]

在上面的示例中,我们创建了一个将 CustomComparator 类作为参数传递的树集。

CustomComparator 类实现了 Comparator 接口。

然后我们重写了 compare() 方法。该方法现在将按相反的顺序对元素进行排序。

要了解更多信息,请访问 Java Comparator (官方 Java 文档)

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战