set接口

不包含重复元素的 collection

  • 不允许添加重复的元素
  • 没有索引
  • 无序(插入和取出的顺序不一样与在TreeSet中自然排序不冲突)

   本身没有什么方法,都是从父类Collection继承过来的

Set接口的实现类——HashSet

  •  底层是哈希表结构  是一个HashMap的实例,而HashMap的底层是哈希表
  •  不允许重复  重复的不会被添加,而不是覆盖原有值
  •  无序 
  • ★HashSet里面的元素储存时由hashCode(根据对象的属性,方法,地址等)得到一个哈希值,把哈希值一样的元素存储到一起,所有哈希值按大小排列。所以在哈希的眼里是有序的,而在开发者看来是无序的。

如何过滤重复项:★【面试题】

  • 通过调用hashCode和equals方法,来过滤重复项
  • 先判断哈希值是否有一样的,如果没有,则直接添加   
  • 如果有一样的,则继续调用equals方法,判断是否相等,如果相等,则添加失败,如果不相等,则直接添加(普通类型和对象类型都一样)
  • 而不是添加进去覆盖原来的元素
  • 没有重写前: 哈希值是类名+地址号,equals比较的是地址号

对象类型,每新建一个新对象,不论里面的属性等是否一样,他们的哈希值都不一样,所以都能添加成功。实际开发中,希望若对象里面的属性等一样,则只添加一次,这就需要同过重新hashCode方法和equals方法来实现

重写hashCode方法  比较的是对象类的哈希值,全类名+地址号,每个对象都是不相同的

public int  hashCode() {
    // 乘以一个数,是为了避免两个不同的哈希值相加后相等的情况
    return name.hashCode()+birthday.hashCode()*12;

}

重写equals方法  没重写前比较的是对象类型的地址号,即使属性值都一样也会存进去

public boolean equals(Object obj){
        if(this==obj){   //判断地址是否相等
            return true;
        }
        if(!(obj instanceof Employee)){   //判断引用名obj指向的对象是否为Employee类型
            return false;
        }
        Employee e= (Employee)obj;    //向下转型
        if(e.name.equals(this.name)&&e.birthday==this.birthday){   //注意String用equals,数字类型的用==号
            return true;
        }
        return false;
    }

为什么要同时复写hashcode() 和 equals() 方法:

违反了相同对象必须具有相同散列码的原则

如果只复写了equals()那么当equals比较后相等时,为逻辑上相等,我们要认为他们是同一个对象,就必须让hashcode() 也相等,否则他们只是两个不同的对象

Set接口的实现类——TreeSet

     底层是 二叉树结构, 可以实现对添加的元素进行自然排序, 不允许添加重复元素

    二叉树结构(大的放右边,小的放左边,相等则不能存。实现从小到大的自然排序)

              100

        50           200

     30    60      150   220

 TreeSet 有两种排序方法 

 添加的参数必须具备比较性:八大包装类型,String类型都实现了Comparable 具备了比较性,所以我们自己定义的引用类型都要通过实现Comparable来拥有比较性。有以下两种方式(自己定义排序规则的方法)

// 方式一:对象类实现comparable接口,然后重写compareTo()方法
class Book implements Comparable
    @Override
    public int compareTo(Object o) {
        if(this==o){      //this代表新添加的元素 注意与重新equals中this代表的不同
            return 0;
        }
        Book b=(Book) o;
        //数字类型可以直接比较
        if(this.price>b.price){   //为什么这段程序中不用 instanceof    this是新元素,instanceof用于判断
            return 1;
        }else if(this.price<b.price){
            return -1;
        }
        //String类型比较用compareTo
        return this.name.compareTo(b.name);      //return 1 实现正序排列,return -1实现逆序排列
    }
// 方式二:创建对象时通过匿名内部类实现    Comparator是一个接口  没有构造器,不能直接创建对象,只能创建实现类或匿名内部类来创建
TreeSet set=new TreeSet(new Comparator(){
             public int compare(Object o1,Object o2){    //重写接口中compara方法
                if(o1==o2){
                    return 0;
                }
                if(!(o1 instanceof Book)||!(o2 instanceof Book)){
                    return 1;(此处返回1或-1 都行,看自己怎么定义了)
                }
                Book b1=(Book)o1;   //向下转型
                Book b2=(Book)o2;
                if( b1.getPrice()<b2.getPrice()){
                    return -1;
                }
                if(b1.getPrice()>b2.getPrice()){
                    return 1;
                }
                return b1.getName().compareTo(b2.getName());
            }
        });

###HashSet和TreeSet对比

               底层结构        过滤重复项                                       特点                 使用步骤

HashSet  哈希表        通过hashCode和equals                      无序                 相同

TreeSet   二叉树       通过比较,如果二者相等代表重复       自然排序          相同

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值