Java TreeSet

时间:2020-02-23 14:36:59  来源:igfitidea点击:

Java TreeSet是java.util.SortedSet的最受欢迎的实现。
SortedSet是扩展java.util.Set的接口。
Java Sorted Set为其元素提供总排序。

Java TreeSet

换句话说,在迭代TreeSet时,我们可以期望排序后的数据。
Java TreeSet元素是按照其自然顺序排序的,或者我们可以在创建SortedSet时提供Comparator
如果我们在创建集时未提供特定的Comparator,则元素必须实现Comparable以确保自然排序。

Java TreeSet构造函数

TreeSet是SortedSet的非常流行的实现。
根据规范,所有排序集实现类都应提供4种类型的构造函数。

  • 一个void(无参数)构造函数:它应该创建一个排序集合,该集合根据其元素的自然顺序进行排序。

  • 一个参数类型为Comparator的构造函数:应创建一个已排序的集合,该集合根据提供的Comparator进行排序。

  • 一个参数类型为Collection的构造函数:它应使用提供的collection的元素创建一个排序集合,该元素根据元素的自然顺序进行排序。

  • 参数类型为SortedSet的构造函数:它应充当复制构造函数,并使用与提供的排序集合相同的元素和相同的顺序创建一个新的排序集合。

不幸的是,接口不能包含构造函数。
因此,没有任何方法可以执行这些建议。

Java TreeSet示例

现在,让我们使用不同的方式来创建一个排序集,如前所述,我们将研究Java TreeSet的不同示例。

//Create a sorted set of Integers
SortedSet<Integer> setWithNaturalOrdering = new TreeSet<>();
setWithNaturalOrdering.add(5);
setWithNaturalOrdering.add(9);
setWithNaturalOrdering.add(4);
setWithNaturalOrdering.add(2);
setWithNaturalOrdering.forEach(System.out::println);

上面的Java TreeSet示例代码的输出将如下图所示。

Java TreeSet Comparable

现在,我们将创建一个具有Person类对象的排序集。
要提供自然排序," Person"类应具有" Comparable"接口的实现。

class Person implements Comparable<Person> {
  int id;
  String name;

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

  @Override
  public int compareTo(Person p) {
      return this.name.compareTo(p.name);
  }

  @Override
  public String toString() {
      return this.name;
  }
}
//Create a sorted set with user defined class
SortedSet<Person> sortedSet = new TreeSet<>();
sortedSet.add(new Person(1, "Mark"));
sortedSet.add(new Person(2, "Vispi"));
sortedSet.add(new Person(3, "Harmony"));
sortedSet.forEach(System.out::println);

输出:

Harmony
Mark
Vispi

Java TreeSet比较器

为了提供不同的排序,我们需要在创建排序集时传递自定义比较器实现。
例如,让我们根据Person类的id属性进行排序。

//we can also provide instance of Comparator implementation instead of lambda
SortedSet<Person> customOrderedSet = new TreeSet<>((p1, p2) -> p1.id - p2.id);
customOrderedSet.addAll(sortedSet);
customOrderedSet.forEach(System.out::println);

Java排序set示例

我们还可以通过传递另一个集合对象或者其他排序集来创建排序集。

List<Person> listOfPerson = Arrays.asList(new Person(1, "Mark"), new Person(2, "Vispi"), new Person(3, "Harmony"));
SortedSet<Person> sortedSetFromCollection = new TreeSet<>(listOfPerson);
SortedSet<Person> copiedSet = new TreeSet<>(sortedSetFromCollection);
copiedSet.forEach(System.out::println);

在这两种情况下,我们都得到以下输出:

Harmony
Mark
Vispi

Java SortedSet方法

与Set相比,由于SortedSet的排序性质,它当然会获得一些另外的特权。
您可能已经猜到,除了从Set接口继承的方法外,它还提供了一些其他方法。

  • Comparator<? super E> compare():返回用于对集合中的元素进行排序的比较器实例。
    如果元素按照其自然顺序排序,则返回null。

  • SortedSet <E> subSet(E fromElement,E toElement):返回给定范围内此集合的一部分。
    (fromElement包含在内,而toElement包含在内)。
    请注意,它返回该子集的视图。
    因此,对返回的集合执行的更改会反映在实际集合中。

  • SortedSet <E> headSet(E toElement):返回此集合中元素严格小于toElement的部分的视图。

  • SortedSet <E> tailSet(E fromElement):返回此集合中元素大于或者等于fromElement的部分的视图。

  • E first():返回集合的第一个元素,恰好是集合中的最低元素。

  • E last():返回集合的最后一个元素,恰好是集合中的最高元素。

Java SortedSet实现

让我们以示例的方式探讨这些方法。
我们将通过一个比较器来创建一个排序集。
其中comparator()方法将返回相同的比较器:

SortedSet<Integer> intSet = new TreeSet<>(Comparator.naturalOrder());
intSet.addAll(Arrays.asList(7,2,1,4,6,5));
Comparator comparator = intSet.comparator();

现在,让我们使用subSet(from,to)方法找到子集。
请注意,对子集所做的更改也将反映在原始集合上。

SortedSet<Integer> subSet = intSet.subSet(2, 5);
System.out.println(subSet);
subSet.add(3);
System.out.println(intSet);

输出:

[2, 4]
[1, 2, 3, 4, 5, 6, 7]

同样,让我们看看其他方法:

subSet = intSet.headSet(3);
System.out.println("Head set");
System.out.println(subSet);

subSet = intSet.tailSet(3);
System.out.println("Tail set");
System.out.println(subSet);

System.out.println("Retrieving lowest and highest elements respectively");
System.out.println(intSet.first());
System.out.println(intSet.last());

输出:

Head set
[1, 2]
Tail set
[3, 4, 5, 6, 7]
Retrieving lowest and highest elements respectively
1
7