Java 集合之TreeSet 自定义类 比较器

Java 集合之TreeSet

  • 基于 TreeMap 的 NavigableSet 实现。 使用元素的自然顺序进行排序,或者通过在集合创建时提供的 Comparator 进行排序,具体取决于使用的构造函数。唯一,无序(没有按照输入顺序进行输出)又有序(按照升序进行遍历)。

  • 此实现为基本操作(添加、删除和包含)提供有保证的 log(n) 时间成本。

  • 请注意,如果要正确实现 Set 接口,则 set 维护的顺序(无论是否提供了显式比较器)必须与 equals 一致。 (请参阅 Comparable 或 Comparator 以获取与 equals 一致的精确定义。)这是因为 Set 接口是根据 equals 操作定义的,但是 TreeSet 实例使用它的 compareTo(或 compare)方法执行所有元素比较,因此从 set 的观点来看,此方法认为相等的两个元素就是相等的。 即使它的顺序与 equals 不一致,set 的行为是明确定义的; 它只是不遵守 Set 接口的一般约定。

  • 请注意,此实现不是同步的。 如果多个线程同时访问一个 TreeSet,并且至少有一个线程修改了 set,则必须在外部进行同步。 这通常是通过同步一些自然封装集合的对象来实现的。 如果不存在此类对象,则应使用 Collections.synchronizedSortedSet 方法“包装”该 set。 这最好在创建时完成,以防止对集合的意外不同步访问:SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));

  • 此类的 iterator 方法返回的迭代器是快速失败的:如果在迭代器创建后的任何时间修改set,除了通过迭代器自己的 remove 方法以外的任何方式,迭代器都会抛出 ConcurrentModificationException。 因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒着任意、非确定性行为的风险。

  • 请注意,无法保证迭代器的快速失败行为,因为一般而言,在存在非同步并发修改的情况下不可能做出任何硬保证。 快速失败的迭代器会尽最大努力抛出 ConcurrentModificationException。 因此,编写依赖于此异常的程序的做法是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测 bug。

  • TreeSet底层的二叉树的遍历是按照升序的结果出现的,这个升序由中序遍历得到。

构造函数

  • TreeSet()

    • 构造一个新的空树集,根据其元素的自然顺序进行排序。
  • TreeSet (Collection<? extends E> c)

    • 构造一个包含指定collection 元素的新 TreeSet,根据其元素的自然顺序进行排序。
  • TreeSet (Comparator<? super E> Comparator)

    • 构造一个新的空TreeSet,根据指定的比较器进行排序。
  • TreeSet (SortedSet s)

    • 构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。

方法

Modifier and Type Method Description
boolean add (E e) 如果指定元素尚不存在,则将其添加到此集合中。
boolean addAll (Collection<? extends E> c) 将指定 collection 中的所有元素添加到此 set 中。
E ceiling(E e) 返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回 null。
void clear() 从此集合中删除所有元素。
Object clone() 返回此 TreeSet 实例的浅表副本。
Comparator<? super E> comparator() 返回用于对该集合中的元素进行排序的比较器,如果该集合使用其元素的自然排序,则返回 null。
boolean contains (Object o) 如果此集合包含指定的元素,则返回 true。
Iterator descendingIterator() 以降序返回此集合中元素的迭代器。
NavigableSet descendingSet() 返回此集合中包含的元素的逆序视图。
E first() 返回当前在此集合中的第一个(最低)元素。
E floor (E e) 返回该集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回 null。
SortedSet headSet (E toElement) 返回此集合中元素严格小于 toElement 的部分的视图。
NavigableSet headSet (E toElement, boolean inclusive) 返回此集合中元素小于(或等于,如果 inclusive 为真)toElement 的部分的视图。
E higher(E e) 返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回 null。
boolean isEmpty() 如果此集合不包含任何元素,则返回 true。
Iterator iterator() 以升序返回此集合中元素的迭代器。
E last() 返回当前在此集合中的最后一个(最高)元素。
E lower (E e) 返回此集合中严格小于给定元素的最大元素,如果没有这样的元素,则返回 null。
E pollFirst() 检索并删除第一个(最低)元素,如果此集合为空,则返回 null。
E pollLast() 检索并删除最后一个(最高)元素,如果此集合为空,则返回 null。
boolean remove (Object o) 如果指定的元素存在,则从该集合中移除该元素。
int size() 返回此集合中的元素数(set 的容量)。
Spliterator spliterator() 在此集合中的元素上创建一个后期绑定和快速失败的 Spliterator。
SortedSet subSet (E fromElement, E toElement) 返回此集合中元素范围从 fromElement(含)到 toElement(不含)的部分的视图。
SortedSet tailSet (E fromElement) 返回此集合中元素大于或等于 fromElement 的部分的视图。
NavigableSet tailSet (E fromElement, boolean inclusive) 返回此集合中元素大于(或等于,如果 inclusive 为真)fromElement 的部分的视图。
  • NavigableSet subSet (E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)
    • fromElement- 返回 set 的低端点,fromInclusive- 如果低端点要包含在返回的视图中,则为 true
      toElement- 返回 set 的高端点,toInclusive - 如果高端点要包含在返回的视图中,则为 true
    • 返回此 set 的部分视图,其元素范围从 fromElement 到 toElement。
    • 如果 fromElement 和 toElement 相等,则返回的 set 为空,除非 fromExclusive 和 toExclusive 都为 true。
    • 返回的 set 受此 set 支持,所以在返回 set 中的更改将反映在此 set 中,反之亦然。返回 set 支持此 set 支持的所有可选 set 操作。 如果试图在返回 set 的范围之外插入元素,则返回的 set 将抛出 IllegalArgumentException。

实例

整数型

//创建一个整数型TreeSet:
TreeSet<Integer> tsi = new TreeSet<>();
tsi.add(12);
tsi.add(3);
tsi.add(7);
tsi.add(9);
tsi.add(3);
tsi.add(16);
System.out.println(tsi.size()); //5
System.out.println(tsi); //[3, 7, 9, 12, 16]

在这里插入图片描述

String类型

//创建一个String类型TreeSet:
TreeSet<String> tss = new TreeSet<>();
tss.add("afyz");
tss.add("bfyz");
tss.add("afyz");
tss.add("dfyz");
System.out.println(tss.size()); //3
System.out.println(tss); //[afyz, bfyz, dfyz]

自定义类

内部比较器

自定义类可以通过Comparable接口自主决定存入数据时的比较内容

public class Student implements Comparable<Student> {
    
    
    private int age;
    private String name;
    public int getAge() {
    
    
        return age;
    }
    public void setAge(int age) {
    
    
        this.age = age;
    }
    public String getName() {
    
    
        return name;
    }
    public void setName(String name) {
    
    
        this.name = name;
    }
    public Student(int age, String name) {
    
    
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString() {
    
    
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
    @Override
    public int compareTo(Student o) {
    
     //比较器,比较时仅仅比较Age
        return this.getAge()-o.getAge();
    }
}

class TestST {
    
    
    public static void main(String[] args) {
    
    
        //创建一个Student类型TreeSet:
        TreeSet<Student> ts = new TreeSet<>();
        ts.add(new Student(1,"fyz"));
        ts.add(new Student(8,"fyz"));
        ts.add(new Student(6,"yjk"));
        ts.add(new Student(8,"fyz"));
        System.out.println(ts.size());
        System.out.println(ts);
    }
}
外部比较器
public class StudentOCT {
    
    
    public static void main(String[] args) {
    
    

        Comparator<Student> scpnt = new SCPN();//利用外部比较器,必须自己制定:
//        TreeSet<Student> ts = new TreeSet<>(scpnt);//一旦指定外部比较器,那么就会按照外部比较器来比较

        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
    
     //匿名内部类
            @Override
            public int compare(Student o1, Student o2) {
    
    
                return o1.getName().compareTo(o2.getName());
            }
        });//一旦指定外部比较器,那么就会按照外部比较器来比较

        ts.add(new Student(1,"fyz"));
        ts.add(new Student(8,"fyz"));
        ts.add(new Student(6,"yjk"));
        ts.add(new Student(8,"fyz"));
        System.out.println(ts.size()); //2
        System.out.println(ts); //[Student{age=1, name='fyz'}, Student{age=6, name='yjk'}]
    }
}


class SCPN implements Comparator<Student> {
    
     //外部比较类
    @Override
    public int compare(Student o1, Student o2) {
    
    
        return o1.getName().compareTo(o2.getName());
    }
}

猜你喜欢

转载自blog.csdn.net/m0_46530662/article/details/119778744