【javase复习】## day8 集合 Set接口 ##

Set接口

无序不可重复。
无序: 添加顺序与抓取出来的顺序不一致






实现类HashSet

特点: 底层哈希表, 存取速度快

原理:
①添加元素时,首先调用hashCode方法以确认该元素要存到哪个位置
②如果目标位置已经有元素,就调用equals方法判断是否相同,如果相同就不允许加入,如果不同就允许加入。(一个位置存放多个元素)

这里写图片描述

class Poker{

    String color;
    int num;

    public Poker(String color, int num){

        this.num = num;
        this.color=color;
    }

    public String toString(){
        return this.color+" "+this.num;
    }

    public int hashCode(){
        System.out.println("因为要确认"+this+"的位置,hasCode调用了!!");
        return this.num;
    }

    public boolean equals(Object obj){
        System.out.println("因为添加"+this+"时位置被占了!,调用equals方法看是否一致");
        Poker p =(Poker)obj;
        return this.num==p.num;
    }

}


public class eee {
     public static void main(String[] args) {
      HashSet s = new HashSet();
      s.add(new Poker("方块",13));
      s.add(new Poker("红桃",5));
      s.add(new Poker("黑桃",12));
      s.add(new Poker("红桃",5));
      System.out.println(s);

     }

}
因为要确认方块 13的位置,hasCode调用了!!
因为要确认红桃 5的位置,hasCode调用了!!
因为要确认黑桃 12的位置,hasCode调用了!!
因为要确认红桃 5的位置,hasCode调用了!!
因为添加红桃 5时位置被占了!,调用equals方法看是否一致
[红桃 5, 黑桃 12, 方块 13]






实现类TreeSet

底层用红黑树(二叉树)实现!!!

特点: 如果元素具备自然顺序的特性,则会按自然顺序的特性进行排序存储

自然顺序: 字母, 数字都可以直接排序,如果没有可比性的元素加入,就会报错。

这里写图片描述

如何解决这个问题??

实现Comparable接口,重写int compareTO方法!!!!!!!!!!!
给TreeSet添加比较器Comparator!!!,即自定义一个类实现Comparator接口,重写Compare方法!!然后创建TreeSet的时候当参数传入!!



Comparable接口!!!:::‘
这里写图片描述






既然可比性用的是compareTo方法,所以判断是否重复也是用的compareTo方法!!!,于是相等的就加不进来!!

还是同样的例子!!!

class Poker implements Comparable{

    String color;
    int num;

    public Poker(String color, int num){

        this.num = num;
        this.color=color;
    }

    public String toString(){
        return this.color+" "+this.num;
    }

    public int hashCode(){
        System.out.println("因为要确认"+this+"的位置,hasCode调用了!!");
        return this.num;
    }

    public boolean equals(Object obj){
        System.out.println("因为添加"+this+"时位置被占了!,调用equals方法看是否一致");
        Poker p =(Poker)obj;
        return this.num==p.num;
    }

    @Override
    public int compareTo(Object o) {
        System.out.println("因为要加入"+this+"调用了compareTo方法!!");
         Poker p =(Poker)o;
         return this.num-p.num;
    }

}


public class eee {
     public static void main(String[] args) {
      TreeSet s = new TreeSet();
      s.add(new Poker("方块",13));
      s.add(new Poker("红桃",5));
      s.add(new Poker("黑桃",12));
      s.add(new Poker("红桃",5));
      System.out.println(s);

     }

}

结果如此、!!通过各个元素调用compareTo方法的次数可以判断底层是二叉树!!!!!! 所以不依赖hashCode和equals方法!!!!!

另外注意: 如果三个节点构不成一个二叉,就会自动调整平衡!!!!,所以实际上比较次序是与二叉平衡树有关!!!

因为要加入方块 13调用了compareTo方法!!
因为要加入红桃 5调用了compareTo方法!!
因为要加入黑桃 12调用了compareTo方法!!
因为要加入黑桃 12调用了compareTo方法!!
因为要加入红桃 5调用了compareTo方法!!
因为要加入红桃 5调用了compareTo方法!!
[红桃 5, 黑桃 12, 方块 13]





给TreeSet添加比较器Comparator!!!,即自定义一个类实现Comparator接口,重写Compare方法!!然后创建TreeSet的时候当参数传入!!

class MyComparator implements Comparator{



    public int compare(Object o1, Object o2) {
        System.out.println("添加"+o1+"和"+o2+"比较的时候用了我呀");
        Poker e1 = (Poker) o1;
        Poker e2 = (Poker) o2;
        return e1.num - e2.num;
    }


}

class Poker implements Comparable{

    String color;
    int num;

    public Poker(String color, int num){

        this.num = num;
        this.color=color;
    }

    public String toString(){
        return this.color+" "+this.num;
    }

    public int hashCode(){
        System.out.println("因为要确认"+this+"的位置,hasCode调用了!!");
        return this.num;
    }

    public boolean equals(Object obj){
        System.out.println("因为添加"+this+"时位置被占了!,调用equals方法看是否一致");
        Poker p =(Poker)obj;
        return this.num==p.num;
    }

    @Override
    public int compareTo(Object o) {
        System.out.println("因为要加入"+this+"调用了compareTo方法!!");
         Poker p =(Poker)o;
         return this.num-p.num;
    }

}


public class eee {
     public static void main(String[] args) {
         MyComparator m = new MyComparator();
      TreeSet s = new TreeSet(m);
      s.add(new Poker("方块",13));
      s.add(new Poker("红桃",5));
      s.add(new Poker("黑桃",12));
      s.add(new Poker("红桃",5));
      System.out.println(s);

     }

}

结果如下


添加方块 13和方块 13比较的时候用了我呀
添加红桃 5和方块 13比较的时候用了我呀
添加黑桃 12和方块 13比较的时候用了我呀
添加黑桃 12和红桃 5比较的时候用了我呀
添加红桃 5和黑桃 12比较的时候用了我呀
添加红桃 5和红桃 5比较的时候用了我呀
[红桃 5, 黑桃 12, 方块 13]






当元素有自然顺序 ,且TreeSet也有比较器。则优先考虑比较器!!

总结:

 treeSet要注意的事项:
    1. 往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储。
    2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该元素所属的类必须要实现Comparable接口,把元素
    的比较规则定义在compareTo(T o)方法上。 

    3. 如果比较元素的时候,compareTo方法返回 的是0,那么该元素就被视为重复元素,不允许添加.(注意:TreeSet与HashCode、equals方法是没有任何关系。)

    4. 往TreeSet添加元素的时候, 如果元素本身没有具备自然顺序 的特性,而元素所属的类也没有实现Comparable接口,那么必须要在创建TreeSet的时候传入一个
    比较器。

    5.  往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而元素所属的类已经实现了Comparable接口, 在创建TreeSet对象的时候也传入了比较器
    那么是以比较器的比较规则优先使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值