Java TreeSet 教程与示例

x33g5p2x  于10个月前 转载在 Java  
字(8.6k)|赞(0)|评价(0)|浏览(60)

Java TreeSet 类是 Java 集合框架的一部分。它实现了 NavigableSet 接口,而后者又扩展了 SortedSet 接口。

TreeSet 类在内部使用 TreeMap 来存储元素。 TreeSet 中的元素根据它们的自然顺序进行排序。您还可以在创建时为 TreeSet 提供自定义 Comparator 以让它根据提供的比较器对元素进行排序。

SortedSet 接口提供了保持元素排序的功能。 NavigableSet 接口提供了在 SortedSet 中导航的功能。例如,查找刚好大于或小于给定元素的元素,查找 SortedSet 中的第一个和最后一个元素等。

由于 TreeSet 类实现了 NavigableSet 接口,它同时具有 NavigableSetSortedSet 的功能。

以下是 Java 中 TreeSet 需要注意的几个关键点 -

TreeSet 不能包含重复的元素。
*
TreeSet 中的元素按其自然顺序排序,或基于创建 TreeSet 时提供的自定义 Comparator 进行排序。
*
TreeSet 不能包含 null 值。
*
TreeSet 内部使用 TreeMap 来存储元素。
*
TreeSet 类不是线程安全的。您必须在多线程环境中显式同步对 TreeSet 的并发访问。

创建一个TreeSet

1. 简单的TreeSet

以下示例显示如何创建 TreeSet 并向其添加新元素。 TreeSet 将根据元素的自然顺序进行排序 -

import java.util.SortedSet;
import java.util.TreeSet;

public class CreateTreeSetExample {
    public static void main(String[] args) {
        // Creating a TreeSet
        SortedSet<String> fruits = new TreeSet<>();

        // Adding new elements to a TreeSet
        fruits.add("Banana");
        fruits.add("Apple");
        fruits.add("Pineapple");
        fruits.add("Orange");

        System.out.println("Fruits Set : " + fruits);

        // Duplicate elements are ignored
        fruits.add("Apple");
        System.out.println("After adding duplicate element \"Apple\" : " + fruits);

        // This will be allowed because it's in lowercase.
        fruits.add("banana");
        System.out.println("After adding \"banana\" : " + fruits);
    }
}
# Output
Fruits Set : [Apple, Banana, Orange, Pineapple]
After adding duplicate element "Apple" : [Apple, Banana, Orange, Pineapple]
After adding "banana" : [Apple, Banana, Orange, Pineapple, banana]

2. 带有自定义比较器的 TreeSet(不区分大小写的顺序)

此示例显示如何使用自定义比较器创建 TreeSet,该比较器通过忽略大小写对元素进行排序。

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

public class TreeSetCaseInsensitiveExample {
    public static void main(String[] args) {
        // Creating a TreeSet with a custom Comparator (Case Insensitive Order)
        SortedSet<String> fruits = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);

        /* The above TreeSet with the custom Comparator is the concise form of the following: SortedSet<String> fruits = new TreeSet<>(new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.compareToIgnoreCase(s2); } }); */

        // Adding new elements to a TreeSet
        fruits.add("Banana");
        fruits.add("Apple");
        fruits.add("Pineapple");
        fruits.add("Orange");

        System.out.println("Fruits Set : " + fruits);

        // Now, lowercase elements will also be considered as duplicates
        fruits.add("banana");
        System.out.println("After adding \"banana\" : " + fruits);
    }
}
# Output
Fruits Set : [Apple, Banana, Orange, Pineapple]
After adding "banana" : [Apple, Banana, Orange, Pineapple]

3. 带有自定义比较器的TreeSet(降序)

下面的示例演示了如何使用自定义比较器创建 TreeSet,该比较器按降序对元素进行排序 -

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

public class TreeSetDescendingOrderExample {
    public static void main(String[] args) {
        // Creating a TreeSet with a custom Comparator (Descending Order)
        SortedSet<String> fruits = new TreeSet<>(Comparator.reverseOrder());

        /* The above TreeSet with the custom Comparator is the concise form of the following: SortedSet<String> fruits = new TreeSet<>(new Comparator<String>() { @Override public int compare(String s1, String s2) { return s2.compareTo(s1); } }); */

        // Adding new elements to a TreeSet
        fruits.add("Banana");
        fruits.add("Apple");
        fruits.add("Pineapple");
        fruits.add("Orange");

        System.out.println("Fruits Set : " + fruits);
    }
}
# Output
Fruits Set : [Pineapple, Orange, Banana, Apple]

访问 TreeSet 的元素

下面的例子展示了如何

  • 查找 TreeSet 的大小。
  • 检查一个元素是否存在于 TreeSet 中。
  • 查找 TreeSet 中的第一个元素。
  • 查找 TreeSet 中的最后一个元素。
  • 查找刚好高于 TreeSet 中给定元素的元素。
  • 查找刚好低于 TreeSet 中给定元素的元素。
import java.util.TreeSet;

public class AccessTreeSetElementsExample {
    public static void main(String[] args) {
        TreeSet<String> students = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);

        students.add("Julia");
        students.add("Robert");
        students.add("Mark");
        students.add("Steven");

        System.out.println("Students TreeSet : " + students);

        // Finding the size of a TreeSet
        System.out.println("Number of elements in the TreeSet : " + students.size());

        // Check if an element exists in the TreeSet
        String name = "Julia";
        if(students.contains(name)) {
            System.out.println("TreeSet contains the element : " + name);
        } else {
            System.out.println("TreeSet does not contain the element : " + name);
        }

        // Navigating through the TreeSet
        System.out.println("First element : " + students.first());
        System.out.println("Last element : " + students.last());

        name = "Robert";
        System.out.println("Element just greater than "  + name + " : " + students.higher(name));
        System.out.println("Element just lower than "  + name + " : " + students.lower(name));

    }
}
# Output
Students TreeSet : [Julia, Mark, Robert, Steven]
Number of elements in the TreeSet : 4
TreeSet contains the element : Julia
First element : Julia
Last element : Steven
Element just greater than Robert : Steven
Element just lower than Robert : Mark

从 TreeSet 中删除元素

这个例子展示了如何

  • 从 TreeSet 中删除一个元素。
  • 删除满足给定谓词的所有元素。
  • 移除 TreeSet 的第一个元素。
  • 移除 TreeSet 的最后一个元素。
import java.util.TreeSet;

public class RemoveTreeSetElementsExample {
    public static void main(String[] args) {
        TreeSet<Integer> numbers = new TreeSet<>();

        numbers.add(10);
        numbers.add(15);
        numbers.add(20);
        numbers.add(25);
        numbers.add(30);
        numbers.add(42);
        numbers.add(49);
        numbers.add(50);

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

        // Remove an element from the TreeSet
        boolean isRemoved = numbers.remove(49);
        if(isRemoved) {
            System.out.println("After Removing 49 : " + numbers);
        }

        // Remove all elements divisible by 3
        numbers.removeIf(number -> number % 3 == 0);
        System.out.println("After removeIf() : " + numbers);


        // Retrieve and remove the first element from the TreeSet
        Integer num = numbers.pollFirst();
        System.out.println("Removed first element " + num + " from the TreeSet : " + numbers);

        // Retrieve and remove the last element from the TreeSet
        num = numbers.pollLast();
        System.out.println("Removed last element " + num + " from the TreeSet : " + numbers);
    }
}
# Output
numbers TreeSet : [10, 15, 20, 25, 30, 42, 49, 50]
After Removing 49 : [10, 15, 20, 25, 30, 42, 50]
After removeIf() : [10, 20, 25, 50]
Removed first element 10 from the TreeSet : [20, 25, 50]
Removed last element 50 from the TreeSet : [20, 25]

带有用户定义对象的 TreeSet

本节中的示例展示了如何创建用户定义对象的 TreeSet。

由于 TreeSet 需要保持对象排序,因此您必须在用户定义的类中实现 Comparable 接口并提供 compareTo() 函数的实现,或者提供自定义 {{$4$}在创建 TreeSet 时。

import java.util.Comparator;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;

class Employee implements Comparable<Employee> {
    private int id;
    private String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // Two Employees are equal if their IDs are equal
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return id == employee.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    // Compare employees based on their IDs
    @Override
    public int compareTo(Employee employee) {
        return this.getId() - employee.getId();
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}


public class TreeSetUserDefinedObjectExample {
    public static void main(String[] args) {
        // Creating a TreeSet of User Defined Objects.

        /* The requirement for a TreeSet of user defined objects is that 1. Either the class should implement the Comparable interface and provide the implementation for the compareTo() function. 2. Or you should provide a custom Comparator while creating the TreeSet. */

        SortedSet<Employee> employees = new TreeSet<>();

        // TreeSet uses the compareTo() method of the Employee class to compare two employees and sort them
        employees.add(new Employee(1010, "Rajeev"));
        employees.add(new Employee(1005, "Sachin"));
        employees.add(new Employee(1008, "Chris"));

        System.out.println("Employees (sorted based on Employee class's compareTo() function)");
        System.out.println(employees);

        // Providing a Custom Comparator (This comparator compares the employees based on their Name)
        employees = new TreeSet<>(Comparator.comparing(Employee::getName));

        employees.add(new Employee(1010, "Rajeev"));
        employees.add(new Employee(1005, "Sachin"));
        employees.add(new Employee(1008, "Chris"));

        System.out.println("\nEmployees (sorted based on the supplied Comparator)");
        System.out.println(employees);

    }
}
# Output
Employees (sorted based on Employee class's compareTo() function)
[Employee{id=1005, name='Sachin'}, Employee{id=1008, name='Chris'}, Employee{id=1010, name='Rajeev'}]

Employees (sorted based on the supplied Comparator)
[Employee{id=1008, name='Chris'}, Employee{id=1010, name='Rajeev'}, Employee{id=1005, name='Sachin'}]

结论

恭喜各位!在本文中,您了解了什么是 Java 中的 TreeSet、如何创建 TreeSet、如何将自定义比较器传递给 TreeSet 以更改元素的排序顺序、如何访问 TreeSet 的元素、如何删除元素来自 TreeSet,以及如何创建用户定义对象的 TreeSet。

相关文章