Set集合

  • Post author:
  • Post category:其他


Set集合与Lis集合有许多区别,Set集合没有提供Collection接口额外的方法,

List的元素允许重复,而Set的元素则不允许重复,添加相同元素时Set集合会覆盖。

Set集合的常用类:


HashSet:散列存放(重点)


TreeSet:有序存放(重点)


LinkedHashSet: 有次序

一丶

HashSet:散列存放(重点)

  1. 是基于HashMap实现的,默认构造函数是构建一个初始容量为16,负载因子为0.75 的HashMap。封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 Object 对象。

  2. 当我们试图把某个类的对象当成 HashMap的 key,或试图将这个类的对象放入 HashSet 中保存时,重写该类的equals(Object obj)方法和 hashCode() 方法很重要,而且这两个方法的返回值必须保持一致:当该类的两个的 hashCode() 返回值相同时,它们通过 equals() 方法比较也应该返回 true。通常来说,所有参与计算 hashCode() 返回值的关键属性,都应该用于作为 equals() 比较的标准。

  3. HashSet的其他操作都是基于HashMap的。

 public static void main(String[] args) {
        Set set = new HashSet<>();
        set.add("a");
        set.add("b");
        set.add("c");//添加元素
        set.add("c");//添加相同元素会覆盖
        System.out.println(set);
    }

HashSet也提供了许多增删查改的方法,如果想添加相同元素,就需要重写HashCode.

2.2 hashCode()和equals()

因为hashCode()和equals()方法的返回值共同决定了两个对象是否相等,所以覆写着两个方法时一般要保证两个方法的

返回值保证兼容。

重写hashCode()和equals()方法的基本规则:

1、 如果两个对象通过equals()方法比较时返回true,则两个对象的hashCode()方法返回值应该也相等。

2、 对象中用作equals()比较标准的成员变量(属性),也应该参与到hashCode的计算。

二丶

TreeSet:有序存放(重点)

TreeSet是可排序的集合,TreeSet使用红黑树结构对加入的元素进行排序存放,所以放入TreeSet中元素必须是可

“排序”

的。

TreeSet可是采用两种方法实现排序:自然排序和定制排序。默认情况,TreeSet采用自然排序。

TreeSet调用调用集合元素的CompareTo()方法,根据该方法的返回值来比较元素之间的大小,然后进行“升序”排列,这种排序方式我们称之为自然排列。

注意:如果想采用自然排序,则要存储的对象所属类必须实现Comparable 接口。该接口只有一个方法public int compareTo(Object obj),必须实现该方法。

compareTo方法的实现规则:

返回 0,表示 this == obj。//则不会添加新对象

返回正数,表示 this> obj //添加到原来对象的右边

返回负数,表示 this < obj // 添加到原来对的左边

package Demo02;

import java.io.Serializable;

public class Student implements Comparable<Student>, Serializable {
    /**
     * 学号,姓名,年龄信息
     */
    private int number;
    private String name;
    private int age;

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

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

    @Override
    public int compareTo(Student o) {
        //根据年龄降序序排序
        int rs =   o.age - this.age;
        if(rs == 0 ){
            if(o == this){
                return 0;
            }else{
                return -1;
            }
        }
        return rs;
    }

}
TreeSet treeSet = new TreeSet();

        treeSet.add(new Student(1001,"张三",21));
        treeSet.add(new Student(1002,"李四",18));
        treeSet.add(new Student(1003,"王五",20));
        treeSet.add(new Student(1004,"赵六",19));
        System.out.println(treeSet);

3.3 定制排序

使用Comparable接口定义排序顺序有局限性:实现此接口的类只能按compareTo()定义的这一种方式排序。

如果需要更加灵活地排序,我们可以自定义(Comparator)比较器,在创建TreeSet集合对象时把我们自定义的比较器传入,则可以TreeSet会按照我们的比较器中定义的规则进行排序。

自定义比较器类,需要实现Comparator接口。Comparator接口只有一个抽象方法需要实现:public int compare(Object a, Object b);

判断规则:

返回 0,表示a == b

返回正数,表示b > b

返回负数,表示a < b

创建TreeSet集合对象时,把自定义比较器对象传入即可,TreeSet会自动按照比较器中的规则进行排序。

public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Student stu1 = (Student)o1;
                Student stu2 = (Student)o2;
                //按照年龄的降序排序
                return  stu2.getAge() - stu1.getAge() ;
            }
        });
       treeSet.add(new Student("张三",21));
        treeSet.add(new Student("李四",18));
        treeSet.add(new Student("王五",20));
        treeSet.add(new Student("李琦",19));
        System.out.println(treeSet);
    }
}



版权声明:本文为qq_48984694原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。