39 Set接口

Set接口

Set接口:存储无序的,不可重复的数据 ----->高中讲的“集合”

HashSet :作为Set接口的主要实现类,线程不安全的;可以存储null值

LinkedHashSet :作为HashSet的子类,遍历其内部的数据时,可以按照添加的顺序遍历

TreeSet :可以按照添加对象的指定属性,进行排序

 

  1. Set接口中没有额外定义新的方法,使用的都是Collection中声明的方法

 

一、Set接口:存储无序的,不可重复的数据

HashSet为例

  1. 无序的:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的 哈希值决定的

  2. 不可重复性:保证添加的元素 按照 equals方法判断时,不能返回true。即 相同的元素只能添加一个

二、添加元素的过程:以HashSet为例:

我们向HashSet中添加元素a ,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已经有元素:

如果此位置没有元素,则元素a直接添加成功,---->情况1

如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较a与元素b的哈希值:

如果哈希值不相同,则元素a添加成功 ---->情况2

如果哈希值相同,进而需要调用元素a所在类的equals()方法:

equals()方法返回true,添加失败,

equals()方法返回false,则元素a添加成功 ---->情况3

对于添加成功的情况2和情况3而言:元素a 与 已经存在指定索引位置上数据以链表的方式存储

jkd 7 :元素a放到数组中,指向原来的元素

jdk8 : 原来的元素放到数组中,指向元素a

 

HashSet底层: 数组 + 链表的结构

 

要求:向Set(主要指HashSet LinkedHashSet)中添加的数据,其所在的类一定要重写hashCode() 和 equals()

重写的hashCode() 和 equals() 尽可能的保持一致性 : 相等的对象必须具有相等的散列码

 

HashSet

//person类中已经重写了hashCode()  和 equals() 
@Test
   public void test3(){
       HashSet set = new HashSet();
       Person p1 = new Person(1001,"AA");
       Person p2 = new Person(1002,"BB");

       set.add(p1);
       set.add(p2);
       System.out.println(set);
       //里面有两个元素AA BB

       p1.name = "CC";
       set.remove(p1);
       System.out.println(set);
       //里面有两个元素CC BB remove时通过索引一定能找到CC set是先找了1001 CC哈希值,找位置的时候大概率是空的
       
       set.add(new Person(1001,"CC"));
       System.out.println(set);
       //里面有3个元素 CC BB CC 算1001 CC的哈希值 发现那个位置是空的
       所以成功了
       
       set.add(new Person(1001,"AA"));
       System.out.println(set);
       //有四个元素CC BB CC AA 1001 AA 的和 第一个CC哈希值一样 但是equals是不一样的
       
  }

 

 

LinkedHashSet

作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录了此数据前一个数据和后一个数据

优点:对于频繁的遍历操作,LinkedHashSet效率高于HashSet

  @Test
   public void test1(){
       Set set = new LinkedHashSet();
       set.add(123);
       set.add(456);
       set.add(456);
       set.add("AA");
       set.add("CC");
       set.add(new User("Tom",12));
       set.add(new User("Tom",12));
       
  }

 

 

TreeSet

  1. TreeSet中添加的数据,要求是相同类的对象

  2. 两种排序方式自然排序(实现Comparable()接口和定制排序(Comaprator()))

  3. 自然排序,比较两个对象是否相同的标准为:CompareTo()返回0,不再是equals()

    定制排序,比较两个对象是否相同的标准为:compare()返回0,不再是equals()

       TreeSet set = new TreeSet();
       set.add(12);
       set.add(-12);
       set.add(43);
       set.add(44);
       set.add(8);

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

 

posted @   flypiggg  阅读(57)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示