Java中的set集合

set集合的概述

  1. set集合的特点
  • 集合中的对象不按特定方式排序
  • 没有重复对象,元素唯一
  1. set集合的实现类
  • Set主要有两个实现类:HashSet和TreeSet。
  • HashSet类按照哈希算法来存取集合中的对象,当向集合中加入这个对象时,HahshSet会调用对象的hashCode()方法来获得哈希码,然后根据哈希码进一步计算出对象在集合中存放的位置,因此存取速度比较快。HashSet类还有一个子类LinkedHashSet类,它不仅实现了哈希算法,而且还实现了链表数据结构。链表数据结构能够提高插入和删除元素的性能。
  • TreeSet类实现了SortSet接口,具有排序功能。
HashSet类

HashSet按照Hash算法存储集合中的元素,具有很好的存取和查找性能。当向HashSet中添加一些元素时,HashSet会根据该对象的HashCode()方法来得到该对象的HashCode值,然后根据这些HashCode的值来决定元素的位置。

  1. HashSet的特点:
  • 存储顺序和添加的顺序不同
     - HashSet不是同步的,如果多个线程同时访问一个HashSet,假设有两个或更多的线程修改了集合中的值,则必须通过代码使线程同步。
  • HastSet允许集合中的元素为null。
  • JDK1.7 HashSet的数据结构是 数组跟链表
  • JDK1.8 HashSet的数据结构是 数组跟链表和二叉树
  1. 判断两个元素相同的标准是:
    两个对象通过equals()方法相等,且HashCode()方法的返回值也相等。如果元素不重写这两个方法则无法保证元素的唯一性
LinkedHashSet类

LikedHashSet是HashSet的子类,它也是根据元素的HashCode值进来决定元素的存储位置,但它能够同时使用链表来维护元素的添加次序,使得元素能以插入顺序保存。

public class LinkHashSetTest {
    public static void main(String[] args){
        LinkedHashSet lh = new LinkedHashSet();
        lh.add(1);
        lh.add(2);
        lh.add(3);
        //输出:[1, 2, 3]
        System.out.println(lh);
        lh.remove(1);
        lh.add(1);
        //输出:[ 2, 3 ,1]
        System.out.println(lh);
    }
}
TreeSet类
  1. TreeSet 集合的特点:
  • 元素唯一,且能对元素进行排序
  • TreeSet 底层的数据结构是二叉树
  1. TreeSet 对元素进行排序
  • 排序会分为两种:1,自然排序,2,比较器排序
  • 采用空参构造时,就用的是自然排序,自然排序要求元素必须实现一个Compareble 接口 并且重写接口中 compareTo 这个比较的方法,根据此方法的返回值的正负0 来决定元素放置到树结构的位置,以及不往里面放
  • 下面举例说明自定义学生类通过学生姓名长度或是年龄进行排序
    测试类:
public class MyTest {
    public static void main(String[] args) {
        TreeSet<Student> set = new TreeSet<>();
        set.add(new Student("赵六", 26));
        set.add(new Student("赵六2", 26));
        set.add(new Student("张三2222", 233));
        set.add(new Student("田七", 230));
        set.add(new Student("吴八222", 2313));
        set.add(new Student("张三22", 23));
        set.add(new Student("张三222", 23));
        set.add(new Student("李四11111111", 24));
        set.add(new Student("王五", 20));
        //按照学生的年龄大小进行排序

        //按照名字的长度来排序

      //  System.out.println(set);
        for (Student student : set) {
            System.out.println(student);
        }


    }
}

学生类重写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 int compareTo(Student student) {
        //System.out.println("会调用比较方法");
        //如果年龄一样,还得比较姓名
        int num = this.age - student.age;
        //if(num==0){
        //    num=this.name.compareTo(student.name);
        //}
        int num2 = num == 0 ? this.name.compareTo(student.name) : num;
        return num2;
    }
}

学生类通过重写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 int compareTo(Student student) {
        //比较逻辑,
        //按照姓名的长度来排序
        int num = this.name.length() - student.name.length();
        //当姓名长度一样时,还得比较姓名的内容
        int num2 = num == 0 ? this.name.compareTo(student.name) : num;
        //当姓名的长度和内容一样时,害得比较姓名是否一样
        int num3 = num2 == 0 ? this.age - student.age : num2;

        return num3;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值