Java-集合类-Set集合接口

        和Lsit接口同样,Set接口也是Collection接口的子接口,这两个接口的最大不一样是List接口中的子类集合内容容许重复,但java

是Set接口子类的集合容许重复,除此以外,Set接口没有对Collection接口进行扩充,因此Set接口中没有List接口中的get()方数据结构

法。你能够轻松的询问某个对象是否在某个Set中,因此查找是Set中最重要的操做。并且Set是根据对象的值来肯定归属性ide

的。        函数

        如今看一下Set接口的类关系图,我再作下面的一系列介绍。this

        

        Set接口有两个经常使用的实现子类:HashSet,TreeSet
编码


HashSet:
spa

        首先示例一个存放Integer对象的HashSet
3d

public class Main{
    public static void main(String[] args){
        Set<String> set = new HashSet<>();
        set.add("Message C");
        set.add("Message A");
        set.add("Message B");
        set.add("Message C");
        set.add("Message D");
        set.add("Message E");
        set.add("Message B");
        System.out.println(set);
    }
}

        根据结果咱们能够发现
code

        1:虽然添加了重复的元素,可是结果中每一个元素只出现了一次
对象

        2:HashSet存放数据彻底没有规律

        出于速度的缘由,HashSet的元素存储使用了散列函数,而TreeSet的元素存储使用的是红黑树的数据结构。


        HashSet重复元素判断

        若是HashSet中存放的系统类对象,那么在进行重复元素判断的时候须要依靠ComParable接口来完成,例如Integer类就

实现了ComParable接口。可是,若是存放的是自定义类对象,因为其和ComParable接口没有关系,那么进行重复元素判断的

候就须要覆写如下两个方法。

        1:hash码:public native int hashCode();

        2:对象比较: public boolean equals(Object obj);

        对象比较的操做一共有两步:经过对象的hash码找到一个对象的信息,编码匹配以后在调用equals()进行内容的比较。

例子:覆写hashCode()与equals()方法消除重复元素

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

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

    @Override
    public String toString() {
        return "[name = "+this.name+" "+"age = "+this.age+"]";
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(name,age);
    }

    @Override
    public int compareTo(Student o) {
        if(this.age > o.age){
            return 1;
        }else if(this.age < o.age){
            return -1;
        }else {
            return this.name.compareTo(o.name);
        }
    }

}


public class Main{
    public static void main(String[] args){
        Set<Student> set1 = new HashSet<>();
        set1.add(new Student("A",1));
        set1.add(new Student("B",2));
        set1.add(new Student("C",3));
        set1.add(new Student("B",3));
        set1.add(new Student("A",1));
        System.out.println(set1);

        由于使用hashSet,因此集合中元素是乱序的,可是在结果中已经去掉了重复的元素。

        要注意的是,若是要去重,必定要同时覆写equals()和hashCode()两个方法,重复对象判断必须这两个方法同时返回相同

才能判断为相同。


TreeSet:

        首先看TreeSet的使用方法,和hashSet的使用方法类似

public class Main{
    public static void main(String[] args){
        Set<String> set = new TreeSet<>();
        set.add("Message C");
        set.add("Message A");
        set.add("Message B");
        set.add("Message C");
        set.add("Message D");
        System.out.println(set);
    }
}

        咱们发现TreeSet相比于hashSet还实现了升序排序。

        TreeSet排序:

        若是进行的是自定义类对象的排序,那么对象所在的类就必须实现Comparable接口而且覆写compareTo()方法,而且类中

的全部属性都必须参加比较操做。

        示例:使用TreeSet排列自定义类对象

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

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

    @Override
    public String toString() {
        return "name = "+this.name+" age = "+this.age;
    }

    @Override
    public int compareTo(Person o) {
        if(this.age > o.age){
            return 1;
        }else if(this.age < o.age){
            return -1;
        }else {
            return this.name.compareTo(o.name);
        }
    }
}


public class Main{
    public static void main(String[] args){
        Set<Person> set = new TreeSet<>();
        set.add(new Person("A",1));
        set.add(new Person("B",2));
        set.add(new Person("C",3));
        set.add(new Person("B",3));
        set.add(new Person("A",1));
        System.out.println(set);
    }
}

           

        由于在比较排序的时候类中全部属性都要参与比较,若是类中有不少属性的话,因此使用TreeSet存放自定义类对象过于麻

烦了,因此仍是推荐使用hashSet来存储自定义类对象。

        去重的操做依靠Comparable接口来完成,因此咱们没必要像hashSet那样取覆写hashCode()方法和equals()方法。

        

        关于Set接口的内容就现总结到这里,但愿能对你们有所帮助。