集合框架之Set

1.Set集合的特点

1.1无序

就是数据添加的顺序和取出的顺序是不一致的

Set<Integer> set=new HashSet<Integer>();
set.add(1);
set.add(4);
set.add(2);
set.add(8);
set.forEach(System.out::println);

                ​​​​​​​         

数据是不一样的,但是已经排序好了(升序)

1.2唯一

很好理解,就是唯一的是不可以添加重复的数据,否则会被覆盖

Set<Integer> set =new HashSet<Integer>();
set.add(1);
set.add(9);
set.add(7);
set.add(8);
set.add(8);
set.forEach(System.out::println);

                                

不仅仅已经排好序了,还把重复的数字8给覆盖了

但是数字不能直观的理解到,那我们就用数组来看一下

首先把User对象创建一下(先不要写tostring方法)

Set<User> set=new HashSet<User>();
set.add(new User(1,"zs","123"));
set.add(new User(2,"ls","123"));
set.add(new User(1,"zs","13"));
for (User user : set) {
    System.out.println(user);
}

                

用数组的换,就是可以看到,zs并没有被消除掉

而且输出的格式:类的全路径名+@+十六进制内存地址

问题原因:判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现;而在没有重写equals方法之前默认比较的是Object(引用类型),实际上比较的是内存地址。

所以我们要重写User对象中的equals方法,比较User对象中的属性。

到User里右键点击生成

        ​​​​​​​        ​​​​​​​        ​​​​​​​        

点击红色框框标记的地方

                

到了这里就要注意了,他这里默认的是最后一个,我们要选中第一个,也就是红色框框标记的,然后就点击下一步,后面出来的,都是点击下一步就可以了,就不用管他了

像这样给他们改一下,然后把tostring方法写上,运行看一下效果

  @Override
    public boolean equals(Object o) {
        //this是当前user对象
        //当前对象是否与传入的user对象相同
        if (this == o) return true;
        //传入的对象是null或者当前的对象的类对象不同于传入
        // 的user对象的类对象
        if (o == null || getClass() != o.getClass()) return false;
        //将O强制转换为String
        User user = (User) o;
//        if (id != user.id) return false;
//        if (!Objects.equals(uname, user.uname)) return false;
//        return Objects.equals(pwd, user.pwd);
//        判断当前User姓名与传入的user姓名是否相同
//        true:存在相同的
//        false:反之
        if (uname.equals(user.uname)){
            return true;
        }else {
            return false;
        }
    }

    @Override
    public int hashCode() {

        int result = id;
        result = 31 * result + (uname != null ? uname.hashCode() : 0);
//        result = 31 * result + (pwd != null ? pwd.hashCode() : 0);
        return result;
    }

                 ​​​​​​​

先比较hashcode方法,然后在比较equals方法
如果hashcode方法返回值相同,再比较equals方法的结果
如果hashcode方法返回值不相同 ,equals就不比较
不比较就是新对象,就允许添加
运行后是被覆盖了,还是过滤了.输出的密码为123 被过滤了,要是为13,就是被覆盖了

2.Set的遍历方式

2.1 foreach循环

Set<String> set=new HashSet<String>();
set.add("zs");
set.add("ls");
set.add("ww");
for(String str:set){
    System.out.println(str);
}

2.2 迭代器循环

Set<String> set=new HashSet<String>();
set.add("zs");
set.add("ls");
set.add("ww");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
    System.out.println(iterator.next());
}

        ​​​​​​​        ​​​​​​​        

两种循环运行出来的效果都是一样的,运行出来的数据就跟我们所写的数据是不一样的,是按照字母排序的

3.TreeSet

TreeSet:安照某种特定的规则对集合中的元素进行排序(升序和降序)

是一个有序的集合,它的作用是提供有序的Set集合。TreeSet是基于TreeMap实现的。

TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。

3.1 java.lang.Comparable:自然比较接口

在User中实现(implements)  Comparable<User>

重写

@Override
public int compareTo(User o) {
    return this.id-o.id;//升序
   // return -(this.id-o.id);//降序
   //这个方法也是升序的
   // if (this.id>o.id){
   //     return 1;
   // }else {
   //     if (this.id==o.id){
   //         return 0;
   //    }else {
   //         return -1;
   //     }
   // }
}
Set<User> set=new TreeSet<>();
set.add(new User(2,"zs","321"));
set.add(new User(4,"bs","321"));
set.add(new User(1,"hs","321"));
set.add(new User(3,"ls","321"));
set.forEach(System.out::println);

运行后的代码是

                        

上面id不是按照顺序写的,都是运行后就自动的分好了

3.2 java.util.Comparator:比较器

重新创建 NameComparator 类

实现 Comparator<User> 

重写方法

package com.zking.text;

import com.zking.entyti.User;

import java.util.Comparator;

public class NameComparator implements Comparator<User> {
    @Override
    public int compare(User a, User b) {
        return b.getUname().hashCode()-a.getUname().hashCode();
    }
}

Set<User> set=new TreeSet<>(new NameComparator());

set.add(new User(2,"zs","321"));

set.add(new User(4,"bs","321"));

set.add(new User(1,"hs","321"));

set.add(new User(3,"ls","321"));

set.forEach(System.out::println);

运行这串代码

        ​​​​​​​        

发现他不是按照id排序了,他是按照字母排序(降序)的

那就有人问了,为什么是降序呢,不是升序,简单

@Override
public int compare(User a, User b) {
    return -(b.getUname().hashCode()-a.getUname().hashCode());
}

                 

像这样子,是不是就升序了 

好啦,完成啦ヾ(≧▽≦*)o

 

  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值