尚硅谷Java笔记-Set接口 | HashSet | LinkedHashSet

与Collection相比较,Set接口并没有扩充对Collection接口进行功能上的扩充,而且所有Set集合底层都是依靠Map实现。Set和Map密切相关。Map的遍历需要先变成单列集合,只能变成Set集合。

一、HashSet集合

1.HashSet是Set接口的实现类

2.特点:元素唯一、元素无序、无索引、线程不安全

3.数据结构:哈希表

        a. jdk8之前:哈希表=数组+链表

        b.jdk8之后:哈希表=数组+链表+红黑树。

        加入红黑树的目的:加快查询速度

4.方法:和 Collection一样

5.遍历:(1)增强for; (2)迭代器

public class Demo01HashSet {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("cat0");
        set.add("dog0");
        set.add("cat1");
        set.add("dog1");
        set.add("cat2");
        set.add("dog0");
        System.out.println(set);
        //输出:[cat2, cat0, cat1, dog1, dog0]
        System.out.println("===================");

        //迭代器
        Iterator<String> iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());

        }
        System.out.println("===================");
        //增强for
        for (String s : set) {
            System.out.println(s);
        }
    }

 二、LinkedHashSet

1.LinkedHashSet 继承了HashSet。

2.特点:元素唯一、元素有序、无索引、线程不安全

3.数据结构:哈希表+双向链表

4.使用:和HashSet一样

三、哈希值

哈希值是由计算机算出来的一个十进制数,可以看作是对象的地址值。获取对象的哈希值,使用的是Object中的方法:public  native int hashCode() 。

    public static void main(String[] args) {
        Person p1 = new Person("xiaotao", 18);
        Person p2 = new Person("wangfang", 20);
        System.out.println(p1);
        System.out.println(p2);
        /*
        输出:March.MyHash.Person@1e643faf
             March.MyHash.Person@6e8dacdf
         */
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        /*
        输出:509886383
             1854778591
         */
        System.out.println(Integer.toHexString(509886383));
        System.out.println(Integer.toHexString(1854778591));
        /*
        输出:1e643faf
             6e8dacdf
         */
    }

String的hashCode是由符号串的内容决定的。 but字符串不一样不代表Hash值一定不一样。

        System.out.println("=============");
        String s1="abc";
        String s2=new String("abc");
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        /*
        输出:96354
              96354
         */
        System.out.println("=============");
        String s3="通话";
        String s4="重地";
        System.out.println(s3.hashCode());
        System.out.println(s4.hashCode());
        /*
        输出:1179395
             1179395
         */

在类中重写hashCode(),则回根据类的属性生成hashCode,两个对象如果属性都相同,那么hashCode也相同。【如果重写了HashCode方法,那么计算的就是对象内容的哈希值】

    @Override
    public int hashCode() {
        return Objects.hash(name,age);
    }

哈希值不一样,内容肯定不一样;哈希值一样,内容也可能不一样(存在哈希冲突)。

HashSet的存储去重复的过程

1.先 计算元素的哈希值(重写hashCode方法),在比较内容(重写equals方法)

2.先比较哈希值,如果哈希值不一样,存储

3.如果哈希值一样,再比较内容

        a. 如果哈希值一样,内容不一样,存储

        b. 如果哈希值一样,内容也一样,去重复

如果不重写HashCode和equals方法,默认调用的是Object中的,那么不容的对象,肯定哈希值不一样并且也不相等。【默认的hashCode类似对象地址,具有唯一性;默认的equals也是通过比较两个对象的地址来判断是否相等】


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值