11-HashSet

HashSet

特点

  1. 放入Integer类型数据

            //创建一个HashSet集合:
            HashSet<Integer> hs = new HashSet<>();
            hs.add(19);
            hs.add(5);
            hs.add(20);
            hs.add(19);//存重复数据
            hs.add(41);
            hs.add(0);
            System.out.println(hs.size());//6个数据,只存了5个
            System.out.println(hs);//[0, 19, 20, 5, 41] 唯一,无序
            //注:数据重复储存,只有第一个数据被存入。
    
  2. 放入String类型数据

            HashSet<String> hs = new HashSet<>();
            hs.add("hello");
            hs.add("apple");
            hs.add("banana");
            hs.add("html");
            hs.add("apple");
            hs.add("css");
            System.out.println(hs.size());//5
            System.out.println(hs);//[banana, apple, css, html, hello]
    
  3. 放入自定义的引用数据类型的数据:

            HashSet<Student> hs = new HashSet<>();
            hs.add(new Student(19,"lili"));//之前Integer和String不用对象是因为自动装箱
            hs.add(new Student(20,"lulu"));
            hs.add(new Student(18,"feifei"));
            hs.add(new Student(19,"lili"));
            hs.add(new Student(10,"nana"));
            hs.add(new Student(11,"jiejie"));
            System.out.println(hs.size());//6
            System.out.println(hs);//发现两个lili都存入了!
    //输出:[Student{age=18, name='feifei'}, Student{age=10, name='nana'},
    // Student{age=20, name='lulu'}, Student{age=19, name='lili'},
    // Student{age=19, name='lili'}, Student{age=11, name='jiejie'}]
    
    • 上面自定义的类型不满足 唯一,无序的特点。为什么呢?、

    因为Student没有重写hashCode和equals(底层原理分析)

简要底层原理

  • 底层=数组+链表
  • 数组都有下标
  • 存入的数据--->每一个数据通过hashCode计算哈希值(这里Integer类型的哈希值与存入的数据一样)
  • 把每个数据的哈希值通过一个表达式计算出存入底层数组的下标(可能不同哈希值算出一样的)
  • 分别将数据存入对应下标的数组中
    • 若存入时,该位置有数据---->要存入的数据与该数据做比较(equals方法)
    • 若相等,则不存入(相当于丢弃)
    • 若不等,在此位置追加出一个链表,将要存入的数据放在链表处(上图11与19)

疑问

  • 底层数组长度是多少
  • 数组的类型是上面
  • hashCode,equals方法真的调用了吗
  • 哈希值和一个表达式算出存放位置,底层表达式是什么
  • 同一个位置的不同数据是向前放还是向后放(是19后加链表11;还是11后加链表19)
  • 放入数组中的数据,是直接放的吗,是否封装成对象了
posted @ 2024-09-08 19:07  呆头尖瓜  阅读(17)  评论(0)    收藏  举报