java中的set集合及其子类

Set系列集合:添加的元素是无序(添加的数据的顺序和获取出数据顺序不一样),不重复,无索引

如:HashSet:无序,不可重复,无索引

LinkedHashSet:有序,不重复,无索引

TreeSet:按照大小默认升序排序,不重复,无索引

public class java {
    public static void main(String[] args) {
        //1:创建一个set对象
        Set<Integer>set=new HashSet<>();//Set是一个抽象类

        set.add(111);
        set.add(111);
        set.add(444);
        set.add(444);
        set.add(444);
        set.add(888);
        set.add(888);
        System.out.println(set);//[888, 444, 111]-->HashSet无序,不重复,无索引
    }
}

哈希值:

就是一个int类型的数值,java对象都有一个
哈希值

java中所有的对象都可以调用Object类提供的hashCode方法,返回自己对象的哈希值

对象哈希值的特点:
同一个对象多次调用hashCode()方法返回的哈希值是相同的

不同的对象哈希值一般不同,但也有可能相同(哈希碰撞) 

HashSet集合的底层原理:
基于哈希表:数组+链表+红黑树

注意:HashSet集合默认不能对内容一样的两个对象去重复!

比如两个相同内容的对象存入到HashSet集合中去,HashSet不能去重复

Student类:
 

public class Student {
    private String name;
    private int age;

    public Student() {
    }

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

    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;
    }

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

public class test {
    public static void main(String[] args) {
        HashSet<Student>hashset=new HashSet<>();
        hashset.add(new Student("hh",12));
        hashset.add(new Student("hh",12));
        hashset.add(new Student("aa",88));
        System.out.println(hashset);
       // [Student{name='aa', age=88}, Student{name='hh', age=12}, Student{name='hh', age=12}]

    }
}

方法:重写equals,hashcode方法

@Override//两个对象的内容一样返回true,不重写的话比较的是地址
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override//只要两个对象的内容一样,哈希值一样
    public int hashCode() {
        return Objects.hash(name, age);

结果:[Student{name='aa', age=88}, Student{name='hh', age=12}]

LinkHashSet:

有序,不重复,无索引

TreeSet:
不重复,无索引,可排序(默认是升序排序,按照元素从大到小默认排序) 

对于数值类型:直接按照大小进行排序

对于字符串类型:默认按照首字符的编号升序排序

public class test {
    public static void main(String[] args) {
        TreeSet<Integer>treeSet=new TreeSet<>();
        treeSet.add(12);
        treeSet.add(10);
        treeSet.add(11);
        System.out.println(treeSet);//[10, 11, 12]
    }
}

如何实现自定义排序:

直接排序自定义对象会报错

方法一:让自定义的类实现Comparable接口,重写里面的compareTo方法来指定比较规则

//方法一:实现Comparable
public class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student() {
    }

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

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", 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 age == student.age && Objects.equals(name, student.name);
    }

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

    @Override
    public int compareTo(Student o) {
       return this.age-o.age;//按照年龄升序
    }
}
public class test2 {
    public static void main(String[] args) {
        TreeSet treeSet =new TreeSet<>();
        treeSet.add(new Student("aa",18));
        treeSet.add(new Student("cc",20));
        treeSet.add(new Student("bb",19));
        treeSet.add(new Student("bb",19));

        System.out.println(treeSet);//[Student{name='aa', age=18}, Student{name='bb', age=19}, Student{name='cc', age=20}]



    }
}

方法二:通过调用TreeSet集合的有参构造器,可以设置comparator对象(用Lambda表达式)

public class test3 {
    public static void main(String[] args) {
        //方法二:
        /*TreeSet<Student>treeSet=new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge()-o2.getAge();
            }
        });*/

        TreeSet<Student>treeSet=new TreeSet<>((o1,o2)->o1.getAge()-o2.getAge() );

        treeSet.add(new Student("aa",18));
        treeSet.add(new Student("cc",20));
        treeSet.add(new Student("bb",19));
        treeSet.add(new Student("bb",19));

        System.out.println(treeSet);



    }
}

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落落落sss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值