集合里Collection接口(下)

Collection:存储单列数据

  • List:有序可重复

  • Set:无序不可重复(不是按照插入顺序输出的)

     Set接口是Collection子接口,set没有提供额外的方法
     HashSet :是set接口的典型实现类,大多数使用set即可的时候,都会选择该类
    

今天要学习的内容:红色划线的部分
在这里插入图片描述
Hashset底层是:数组+链表
底层也是有数组的,初始长度为16;
当使用率超过原来的0.75倍的时候就去扩容,0.75*16=12,超过12的时候就去扩容,扩容两倍;16–32—64

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

public class SetDemo01 {
    public static void main(String[] args) {
       
        Set hs=new HashSet();
        hs.add("小智");
        hs.add("iu");
        hs.add("海子");
        System.out.println(hs.add("iu"));//数据重复,插入失败
        System.out.println(hs);

        HashSet<Student> hs1=new HashSet();
        hs1.add(new Student("小泽川",16));
        /*
        当向集合中添加小泽川这名学生对象的时候,
            先去调用'小泽川'学生对象所在类的hashCode方法,计算出当前对象的hash值
            此时hash值经过某种算法,算出该元素在hashSet底层数组存储的下标(索引)
            如果该下标处没有元素,则此时'小泽川'添加成功
         */
        hs1.add(new Student("小波比",18));
        /*
        前提'小泽川'和'小波比'两个对象通过某种特定算法得出的下标一致
            当'小泽川'添加成功后,再添加'小波比'我们就会发现指定的下标处有元素'小泽'
            当发现下标元素相同的元素时,需要判断两个对象是否同一个对象,如果是添加失败,反之添加成功
            1.比较两个元素的hash值
                如何hash值不相同,则元素添加成功
                如果hash值相同,则通过equals比较两个对象
            2.比较两个元素的equals方法
                如果equals方法返回false,则'小波比'添加成功
                如果equals方法返回true,则'小波比'添加失败
         */
        hs1.add(new Student("小苍梧",17));
        /*
        LinkedHashSet是HashSet的子类:
            LinkedHashSet他使用双向链表来维护元素的顺序
            使得元素看起来是按照插入顺序保存的
         */
        Set hs2=new LinkedHashSet();
        hs2.add("小智");
        hs2.add("iu");
        hs2.add("海子");
        System.out.println(hs2);
    }
}
class Student{

    String name;
    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);
    }
   
}

TreeSet是SortedSet,SortedSet是Set的子接口(查询速度比List还快,底层是2叉树)

  • TreeSet是红黑树结构存储的数据
  • TreeSet可以确保集合元素处于排序状态
  • TreeSet两个排序操作:自然排序和定制排序

自然排序:

  1. 先让自定义类型实现连接 ( implements ) 接口Comparable
  2. 重写compareTo方法,根据自己需求去对不同属性进行排序
import java.util.TreeSet;

public class SetDemo02 {
    public static void main(String[] args) {
        TreeSet set1=new TreeSet();
        set1.add("777");
        set1.add("333");
        set1.add("111");
        set1.add("222");
        System.out.println(set1);

        TreeSet<Student> set2=new TreeSet();
        set2.add(new Student("333",18));
        set2.add(new Student("333",19));
        set2.add(new Student("333",17));
        System.out.println(set2);
    }
}
//连接接口Comparable
class Student implements Comparable{

    String name;
    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);
    }
    /*
    重写compareTo方法
   
    需要学生按照什么顺序排序
    根据名字或这年龄
    this当前对象:o对象
     */
    @Override
    public int compareTo(Object o) {
        if (o instanceof Student) {
            //o能转为学生类,则比较内容
            //1.将o强转为Student
            Student s = (Student) o;
            //2.如果按照名字排序
            //默认升序
            //return this.name.compareTo(s.name);
            //return -this.name.compareTo(s.name);//降序
            //3.如果只根据年龄排序
            //return Integer.compare(this.age,s.age);
            //4.如果先根据名字,在根据年龄排序
            int num = this.name.compareTo(s.name);
            if (num == 0) {//判断名字比较结果是否为0;如果为0则表示名字相同,这样才会比较年龄
                return -Integer.compare(this.age, s.age);
            }else{
                return num;
            }

        } else {
            //o不能转为学生类,则不需要比较
            throw new RuntimeException("类型不匹配,无法比较");
        }
    }
}

定制排序:Comparator

  1. 创建Comparator定制排序的实例
  2. 将定制排序的实例传入TreeSet
import java.util.Comparator;
import java.util.TreeSet;

public class SetDemo03 {
    public static void main(String[] args) {
        //1.使用匿名内部类创建Comparator实例
        Comparator c1=new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof String && o2 instanceof String){
                    String s1=(String)o1;
                    String s2=(String)o2;
                    return -s1.compareTo(s2);
                }
                return 0;
            }
        };

        //需要将上述定制排序的实例传入TreeSet
        TreeSet set1=new TreeSet(c1);
        set1.add("777");
        set1.add("333");
        set1.add("111");
        set1.add("222");
        System.out.println(set1);
    }
}

小案例
1.创建麻将对象

    1.花色 color

    2.字符  num

    3.每个数字牌对应的个数,方便后面比对,这里使用字符串 index

分别使用定制排序,或者自然排序;对插入的五个麻将对象(自行随机插入五个)进行排序

定制排序使用按照花色升序和字符排序升序

自然排序按照花色降序和字符降序

代码如下:

package work.day0302;


import java.util.Objects;


public class mahjong implements Comparable{
    private String color;
    private int num;
    private int index;
    public mahjong() {
    }
    public mahjong(String color, int num, int index) {
        this.color = color;
        this.num = num;
        this.index = index;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    @Override
    public String toString() {
        return "mahjong{" +
                "color='" + color + '\'' +
                ", num=" + num +
                ", index=" + index +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        mahjong mahjong = (mahjong) o;
        return num == mahjong.num &&
                index == mahjong.index &&
                Objects.equals(color, mahjong.color);
    }

    @Override
    public int hashCode() {
        return Objects.hash(color, num, index);
    }
	
	//自然排序:按照我的需求排序
    @Override
    public int compareTo(Object o) {
       if (o instanceof mahjong){
            mahjong m=(mahjong)o;
            //先判断花色
            int num1=-this.color.compareTo(m.color);
            if (num1==0){
            	//花色相同,判断数值
                return -Integer.compare(this.num,m.num);
            }else{
                return num1;
            }
       }else{
           throw  new RuntimeException("类型不匹配");
       }
    }
}

针对上述类,做的一个自然排序测试类

package work.day0302;

import java.util.TreeSet;

//自然排序
public class Test2 {
    public static void main(String[] args) {
        TreeSet<mahjong> t=new TreeSet();
        t.add(new mahjong("筒",3,1));
        t.add(new mahjong("筒",1,1));
        t.add(new mahjong("条",3,1));
        t.add(new mahjong("万",9,1));
        t.add(new mahjong("筒",4,1));
        System.out.println(t);
    }
}

效果图如下
在这里插入图片描述
对mahjong做一个定制排序测试类

package work.day0302;

import java.util.Comparator;
import java.util.TreeSet;

public class Test1 {
    public static void main(String[] args) {
        Comparator c=new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //判断
                if (o1 instanceof mahjong && o2 instanceof mahjong){
                    mahjong m1=(mahjong)o1;
                    mahjong m2=(mahjong)o2;
                    int num=m1.getColor().compareTo(m2.getColor());
                    if (num==0){
                        return Integer.compare(m1.getNum(),m2.getNum());
                    }else{
                        return m1.getColor().compareTo(m2.getColor());
                    }
                }else{
                    throw new RuntimeException("类型不匹配");
                }
            }
        };
        TreeSet<mahjong> t=new TreeSet(c);
        t.add(new mahjong("筒",3,1));
        t.add(new mahjong("筒",1,1));
        t.add(new mahjong("条",3,1));
        t.add(new mahjong("万",9,1));
        t.add(new mahjong("筒",4,1));
        System.out.println(t);
    }
}

效果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值