集合框架之Set集合

1.Set集合的特点

        (1)唯一性:不可添加重复元素

        (2)无序性:输出元素的顺序跟添加元素的顺序不一致,且没有元素下标。

        (3)可哈希性:‌Set中的元素必须是可哈希的,‌即元素必须有一个明确的哈希值。‌如果一个元素没有哈希值,‌那么它就不能被用作Set的元素。‌

        (4)内部实现:‌Set内部通常基于哈希表或平衡树等数据结构实现,‌这提供了快速插入、‌删除和查找的操作。‌由于内部实现采用哈希表或树形结构,‌查找某个元素的时间复杂度为O(1)或O(log n)。‌

        (5)Set集合由于没有继承ListIterator,所以无法调用其方法,但是能够调用Iterator。

2.Set集合的遍历方式

        (1)for遍历:

             由于for循环遍历集合需要依靠下标遍历集合元素,所以此遍历方式无法实现对Set集合的遍历。

        (2)foreach遍历:

                代码如下:

Set<String> set=new Set<>();
  set.add(new Student("z");
  set.add(new Student("x"));
  set.add(new Student("a"));

 for (Student s: set) {
    System.out.println(s);
 }

        (3)迭代器遍历:

                前面说到Set集合无法调用Listiterator,所以此处一定是调用iterator。

        代码如下:

Iterator<Student> it = set.iterator();
while (it.hasNext()){
  System.out.println(it.next());
}

3.Set集合存在的问题

       (1) Set集合的特点之一是唯一性,但我们在开发软件时大多都是将对象添加到集合中,那么这时添加两个属性值完全相同的对象,唯一性可能就不成立啦,这是为什么呢?问题就出在hashCode()和equals(),这两个方法,一个比较哈希码,一个比较字符,并且,比较顺序是先比较哈希码,如果相同,再用equals()比较;如果哈希码不同,它就不会用equals()比较啦。

        这时我们需要去重写equals(),这两个方法。

修改成这样:

@Override
    public boolean equals(Object o) {
       if (this == o) return true;
       if (o == null || getClass() != o.getClass()) return false;
       Student student = (Student) o;
       
       if (sname.equals(student.sname)){
            //为相同,将相同的那一个元素剔除
            return true;
        }else{
            //为不相同,保留元素
            return false;
        }
    }

        (2)这个时候有人还问:“我要是传入的两相同姓名,但是年龄或者成绩不同的对象,那该怎么办啊?”。这个时候就要从hashCode()下手啦,上面说到,比较顺序是先比较哈希码,如果相,再用equals()比较;如果哈希码不同,它就不会用equals()比较啦。

那么,这种情况下,主要导致问题的是传入对象的成绩或者年龄属性的哈希码,因为它发现两个对象的成绩或者年龄属性哈希码的值不同啦,它就不会再去用equals(),进而导致了相同姓名,不同年龄或成绩的对象添加到了Set集合中,所以解决方式是,我们干脆直接不让它去比较成绩或者年龄的哈希码。

        如下:

 public int hashCode() {
        int result = sid != null ? sid.hashCode() : 0;
        result = 31 * result + (sname != null ? sname.hashCode() : 0);
        return result;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值