软件编程
位置:首页>> 软件编程>> java编程>> Java集合之Set接口及其实现类精解

Java集合之Set接口及其实现类精解

作者:叶绿体不忘呼吸  发布时间:2022-01-23 17:27:44 

标签:Java,Set,接口
目录
  • Set接口概述

  • HashSet实现类

    • 1、HashSet 具有以下特点:

    • 2、HashSet 集合判断两个元素相等的标准

    • 3、向HashSet中添加元素的过程

  • LinkedHashSet实现类

    • TreeSet实现类

      Set接口概述

      1、Set接口是Collection的子接口,set接口没有定义额外的方法,使用的都是Collection接口中的方法。
      2、Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set 集合中,则添加操作失败。

      Java集合之Set接口及其实现类精解

      3、Set:存储无序的、不可重复的数据
      (以HashSet为例说明)
      ①无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值。
      ②不可重复性:保证添加的元素按照equals()判断时,不能返回true。即:相同的元素只能添加一个。

      HashSet实现类

      1、HashSet 具有以下特点:

      ①不能保证元素的排列顺序
      ②HashSet 不是线程安全的
      ③集合元素可以是 null

      2、HashSet 集合判断两个元素相等的标准

      两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。因此对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode()方法,以实现对象相等规则,即:“相等的对象必须具有相等的散列码”。

      3、向HashSet中添加元素的过程

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

      如果此位置上没有其他元素,则元素a添加成功。—>情况1
      如果此位置上有其他元素b(或以链表形式存在多个元素),则比较元素a与元素b的hash值:

      如果hash值不相同,则元素a添加成功。—> 情况2
      如果hash值相同,进而需要调用元素a所在类的equals()方法:

      如果equals()返回true,元素a添加失败
      如果equals()返回false,则元素a添加成功。—>情况3

      对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上数据以链表的方式存储。(七上八下)
      jdk 7 : 新来元素a放到数组中,指向已存在的旧元素。
      jdk 8 : 已存在的旧元素在数组中,指向新来元素a

      Java集合之Set接口及其实现类精解

      底层为“数组+链表”,数组初始容量为16,当如果使用率超过0.75(16*0.75=12)就会扩大容量为原来的2倍。(16扩容为32,依次为64,128…等)

      重写equals()方法的时候一般都需要同时复写hashCode()方法。通常参与计算hash值的对象的属性也应该参与到equals()中进行计算

      Java集合之Set接口及其实现类精解

      LinkedHashSet实现类

      1、LinkedHashSet 是 HashSet 的子类,也是根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

      2、LinkedHashSet插入性能略低于 HashSet,但在迭代访问(遍历) Set 里的元素时有很好的性能。

      3、LinkedHashSet 不允许集合元素重复。

      Java集合之Set接口及其实现类精解

      TreeSet实现类

      1、TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。元素应为相同类的对象。

      2、TreeSet底层使用红黑树结构存储数据。

      3、TreeSet 两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。

      4、自然排序
      ①TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按条件排列。如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。实现 Comparable 的类必须重写compareTo(Object obj) 方法,两个对象通过compareTo(Object obj) 方法的返回值来比较大小。
      ②向 TreeSet 中添加元素时,只有第一个元素无须比较compareTo()方法,后面添
      加的所有元素都会调用compareTo()方法进行比较。
      ③因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同
      一个类的对象。
      ④对于 TreeSet 集合而言,它判断两个对象是否相等的唯一标准是两个对象通过 compareTo(Object obj) 方法比较的返回值。


      import java.util.Iterator;
      import java.util.TreeSet;

      /**
      * @Author: Yeman
      * @Date: 2021-09-16-16:48
      * @Description:
      */

      class Student implements Comparable{
         String name;
         int age;

      public Student() {
         }

      public Student(String name, int age) {
             this.name = name;
             this.age = age;
         }

      @Override
         //姓名从小到大,年龄从大到小排列
         public int compareTo(Object o) {
             if (o instanceof Student){
                 Student student = (Student) o;
                 int nameResult = this.name.compareTo(student.name);
                 if (nameResult == 0){
                     return -Integer.compare(this.age,student.age);
                 }else {
                     return nameResult;
                 }
             }else throw new RuntimeException("类型不匹配");
         }

      @Override
         public String toString() {
             return "Student{" +
                     "name='" + name + '\'' +
                     ", age=" + age +
                     '}';
         }
      }

      public class TreeSetTest {
         public static void main(String[] args) {
             TreeSet treeSet = new TreeSet();
             treeSet.add(new Student("Tom",18));
             treeSet.add(new Student("Tom",22));
             treeSet.add(new Student("jim",18));
             treeSet.add(new Student("Anne",19));
             treeSet.add(new Student("Lily",25));
             treeSet.add(new Student("LiLei",25));

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

      Java集合之Set接口及其实现类精解

      5、定制排序
      ①定制排序,通过Comparator接口来实现,需要重写compare(T o1,T o2)方法。
      ②要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。
      ③仍然只能向TreeSet中添加类型相同的对象。否则发生ClassCastException异常。
      ④使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0。


      import java.util.Comparator;
      import java.util.Iterator;
      import java.util.TreeSet;

      /**
      * @Author: Yeman
      * @Date: 2021-09-16-16:48
      * @Description:
      */

      class Student{
         String name;
         int age;

      public Student() {
         }

      public Student(String name, int age) {
             this.name = name;
             this.age = age;
         }

      @Override
         public String toString() {
             return "Student{" +
                     "name='" + name + '\'' +
                     ", age=" + age +
                     '}';
         }
      }

      public class TreeSetTest {
         public static void main(String[] args) {
             Comparator com = new Comparator() {
                 @Override
                 public int compare(Object o1, Object o2) {
                     if (o1 instanceof Student && o2 instanceof Student) {
                         Student student1 = (Student) o1;
                         Student student2 = (Student) o2;
                         return Integer.compare(student1.age, student2.age);
                     } else throw new RuntimeException("类型不匹配");
                 }
             };
             TreeSet treeSet = new TreeSet(com);
             treeSet.add(new Student("Tom",18));
             treeSet.add(new Student("Tom",22));
             treeSet.add(new Student("jim",18));
             treeSet.add(new Student("Anne",19));
             treeSet.add(new Student("Lily",25));
             treeSet.add(new Student("LiLei",25));

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

      Java集合之Set接口及其实现类精解

      来源:https://blog.csdn.net/m0_46653805/article/details/120329878

      0
      投稿

      猜你喜欢

      手机版 软件编程 asp之家 www.aspxhome.com