Java中的Set集合

Set集合:

HashSet集合(元素唯一):

无序(存储和取出不一致),能够保证元素唯一

HashSet:底层数据结构是一个哈希表(桶结构)
线程不安全的类→→→不同步→→→执行效率高

JDK8以后;提供了juc(并发包:java.util.concurrent):
ConcurrentHashMap<K,V>和HashMap的区别 ?

String类型:String类型本身已经重写了hashCode()和equals,如果hashCode和equals()都相同,
那么认为同一个元素,存储以前的值
public class HashSetDemo {
    public static void main(String[] args) {

        //创建HashSet集合对象
        Set<String> set = new HashSet<>() ;

        //添加字符串元素
        set.add("hello") ;
        set.add("hello") ;
        set.add("world") ;
        set.add("JavaEE") ;
        set.add("JavaEE") ;
        set.add("world") ;
        set.add("android") ;
        set.add("php") ;
        set.add("php") ;
        set.add(null) ;
        System.out.println(set); //元素唯一,会自动去重
    }
}

如果现在存储是自定义对象,如何保证元素唯? ---- HashSet

HashSet集合依赖于add方法→→→HashMap的put方法

首先要比较元素的哈希码值相同→→→hash()就相同,还要比较成员信息是否相同,对应存储自定的类必须要重写Object的equals方法

比如Student的这个类,必须手动给出hashCode()和equals
(无序)Hashset集合不能保证顺序迭代恒久不变!

注意:

在一些需求中,如果没有明确要求元素重复,那就可以使用hashSet,保证元素唯一!
	类型:String,Integer,Long,....常用类都已经重写了hashCode和equals方法

手动给出HashCode() 和 equals方法

idea快捷键直接生成  alt+insert
    @Override
    public boolean equals(Object o) {
        ...
    }

    @Override
    public int hashCode() {
        ...
    }

TreeSet集合(自然排序):

无序性,元素唯一

底层依赖于TreeMap集合,  红黑树结构(也称为 "自平衡的二叉树结构"),可以实现Map的自然排序以及比较器排序取决于

构造方法:

public TreeSet():构造一个空的树,实现元素自然排序 (取决于存储的元素类型能否实现Comparable接口)

TreeSet能够实现两种排序:

1.自然排序

若要实现TreeSet的自然排序 ,执行TreeSet无参构造方法,而且前提条件当前存储类型必须实现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 s) { //后面需要和学生对象对比

        //主要条件:就是按照年龄从小到大排序
        //定义一个变量
        //年龄int类型
       /* int num = this.age - s.age ;
//        int num = s.age - this.age ;//从大到小

        //次要条件:年龄相同,还要比较姓名的内容是否相同
        int num2 = (num==0)?(this.name.compareTo(s.name)):num;    //字符串的字典顺序比较
                            //gaoyuanyuan
                            //jacky
        return num2;*/

       //主要条件:按照学生姓名的长度:从小到大进行排序
        int num = this.name.length() - s.name.length() ;

        //如果长度相同,还比较内容是否一样          "hello" ,"hel"
        int num2 = (num==0)?(this.name.compareTo(s.name)):num ;

        //如果长度相同,内容一样
        //按照学生的年龄从小到大比
        int num3 = (num2==0)? (this.age - s.age) :num2 ;
        return num3 ;
    }
}

需求:

使用TreeSet集合存储学生类型
主要条件:按照学生姓名的长度:从小到大进行排序
public class TreeSetDemo3 {
    public static void main(String[] args) {


        //无参构造方法创建TreeSet集合
        TreeSet<Student> ts = new TreeSet<>() ;

        //创建几个学生对象
        Student s1 = new Student("wenzhang",34) ;
        Student s2 = new Student("zhaosisi",36) ;
        Student s3 = new Student("wuyifan",40) ;
        Student s4 = new Student("wuyifan",32) ;
        Student s5 = new Student("gaoyuanyuan",42) ;
        Student s6 = new Student("gaoyuanyuan",42) ;
        Student s7 = new Student("zhangjunjie",20) ;
        Student s8 = new Student("liuqiangdong",50) ;


        ts.add(s1) ;
        ts.add(s2) ;
        ts.add(s3) ;
        ts.add(s4) ;
        ts.add(s5) ;
        ts.add(s6) ;
        ts.add(s7) ;
        ts.add(s8) ;

        //遍历
        for(Student s: ts){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}

运行结果

wenzhang---34
zhaosisi---36
wuyifan---40
wuyifan---32
gaoyuanyuan---42
zhangjunjie---20
liuqiangdong---50

2.比较器排序:

   public TreeSet(Comparator<? super E> comparator)

            Comparator是一个接口类型
                   1)自定义一个类实现Comparator接口,重写compare方法
                   2)使用接口的匿名内部类(推荐)


        使用TreeSet存储Student类型,遍历元素(使用比较器排序完成)
 排序条件:
        主要条件:按照学生的年龄从小到大排序

泛型高级通配符(了解)
<?> :任意Java类型,包括Object
<? super E> : 向上限定:E类型以及E父类
<? extends E>: 向下限定:E以及它的子类

public class MyComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {

        //主要条件:按照学生的年龄从小到大排序
        //s1---->就是刚才自然排序里面this
        //s2---->就是刚才自然排序里面s
        int num = s1.getAge() - s2.getAge() ;
        //如果年龄相同,比较姓名是否一样
        int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ;

        return num2;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值