set及其常用子类

Set集合常用方法

Set


boolean    add(E e) 如果set中尚未存在指定元素则添加此元素,成功返回true,失败返回false
 boolean    addAll(Collection<? extends E> c) 如果 set 中没有指定 collection 中的所有元素,则将没有的元素添加到此集合,若包含了指定元素的全部元素,不添加。如果有添加操作返回true,没有则返回false。
boolean    contains(Object o) 如果此集合包含指定元素返回true
boolean    containsAll(Collection<?> c) 如果此set包含指定Collection的所有元素则返回true
boolean    isEmpty() 如果 set 不包含元素,则返回 true。
boolean    remove(Object o)如果 set 中存在指定的元素,则将其移除,返回true,不包含返回false
boolean    removeAll(Collection<?> c)  移除 set 中那些包含在指定 collection 中的元素,没有交集返回false
boolean    retainAll(Collection<?> c)仅保留 set 中那些包含在指定 collection 中的元素,没有交集则保留空,返回true
int    size()返回 set 中的元素数<T> T[] toArray(T[] a) 返回一个包含此 set 中所有元素的数组;返回数组的运行时类型是指定数组的类型。


HashSet   (可以添加null)


boolean    add(E e)
如果此 set 中尚未包含指定元素,则添加指定元素
 void    clear() 从此 set 中移除所有元素
 boolean    contains(Object o)如果此 set 包含指定元素,则返回 true
boolean    isEmpty()  如果此 set 不包含任何元素,则返回 true
boolean    remove(Object o)如果指定元素存在于此 set 中,则将其移除
int    size() 返回此 set 中的元素的数量(set 的容量)。

TreeSet   (默认是排好序的,不能添加null值)


构造方法
TreeSet() 
          构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。
调用此构造方法要求目标类(即范型类)实现了comparable接口,重写compareTo()方法
TreeSet(Comparator<?superE> comparator) 
          构造一个新的空 TreeSet,它根据指定比较器进行排序调用此构造方法必须传入一个比较器,即实现了Comparator接口重写了compare()方法的类或其匿名内部类。


方法
boolean    add(E e) 将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。
boolean    addAll(Collection<? extends E> c)将指定 collection 中的所有元素添加到此 set 中。
void    clear() 移除此 set 中的所有元素。
boolean    isEmpty()  如果此 set 不包含任何元素,则返回 true
int    size() 返回此 set 中的元素的数量(set 的容量)。
boolean    remove(Object o)如果指定元素存在于此 set 中,则将其移除

Set 集合 及其三个具体的子类


Set集合的特点:元素无序(存取顺序不一致),元素不重复,在遇到去重问题是可以用set集合存储。

Set保证集合元素的唯一性是靠重写hashCode()方法和equals()方法。不重写则无法保证。
原因:add()方法底层在存储的时候会调用hashCode()方法和equals()方法

我们在往Set集合存储元素是,他默认比较地址值,如果地址值不一样,就会存到集合当中,而我们认为两个对象只要成员变量的值一样就是同一个对象,此时需要重写hashCode()方法和equals()方法。


HashSet:

底层数据结构是哈希表,线程不安全,效率高,允许存储null值,元素无序
元素的唯一性是靠重写hashCode()方法和equals()方法。不重写则无法保证。
Integer 和String 默认重写了hashCode()和equals()方法


LinkedHashSet:

底层数据结构是链表和哈希表,线程不安全,效率高,元素有序且唯一

TreeSet:

底层数据结构是二叉树,线程不安全,效率高,元素有序且唯一。不允许null元素。

TreeSet可以对元素进行排序,排序方式有自然排序和比较器排序,具体取决于使用的构造方法。


1.自然排序


    使用无参构造方法时,采用自然排序,按照元素的自然顺序排序
    调用此方法要求元素实现了Comparable接口并重写了compareTo()方法,否则会报错:Exception in thread "main" java.lang.ClassCastException: org.westos.day0801.Student(元素类型) cannot be cast to java.lang.Comparable

元素类写法:(Student类)

public class Student implements Comparable<Student>{
    private String name;
    private Integer age;

    public Student() {
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name) &&
                Objects.equals(age, student.age);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public int compareTo(Student o) {
        int a =this.age-o.getAge();
        int r = a==0?this.name.compareTo(o.getName()):a;
        return r;
    }
}


2.比较器排序


    在创建TreeSet对象时,要给构造方法传一个比较器。此比较器是一个实现了Comparator接口的类或者其匿名内部类。比较器写法:

public class MyComparator implements Comparator<Integer> {


    @Override
    public int compare(Integer o1, Integer o2) {

        return o1-o2;
    }
}


但是比较器一般只用一次,重写一个类比较麻烦,一般我们直接传入匿名内部类

匿名内部类的比较器:

TreeSet<Student> students = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int a = o1.getAge() - o2.getAge();
                int r = a == 0 ? o1.getName().compareTo(o2.getName()) : a;
                return r;
            }
        });

在匿名内部类里面重写compare()方法,这里我们先按学生类的年龄排序,年龄相同在按照姓名的字典顺序排。

二叉树存储保证唯一和排序靠的是比较器,比较器中比较方法的返回值如果为负数,表示o1小于o2,返回值为0表示一样大,即重复了,不会存进去,返回值为正数,o1大于o2。默认按从小到大排,如果想从大到小排给返回值加个负号即可。

猜你喜欢

转载自blog.csdn.net/qq_38454165/article/details/81455195