zoukankan      html  css  js  c++  java
  • Java 集合:(十一) Set子接口

    一、Set 接口概述

      1、Set 接口是 Collection 的子接口,set 接口没有提供额外的方法;

      2、Set接口:存储无序的、不可重复的数据,Set 接口中会以某种规则保证存入的元素不出现重复

      3、Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个  Set 集合中,则添加操作失败;

      4、Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法;

      5、Set 集合不是同步的,多线程不安全的;

      6、Set 接口的结构

        

       特点查询速度快,不重复,没有索引。

    二、常用实现类

      1、HashSet

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

        构造方法:

    HashSet() :构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75

         源码:

        

      2、LinkedHashSet

        作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历,对于频繁的遍历操作,LinkedHashSet效率高于HashSet。

        构造方法:

    LinkedHashSet(): 构造一个带默认初始容量 (16) 和加载因子 (0.75) 的新空链接哈希 set
    LinkedHashSet(int initialCapacity) :构造一个带指定初始容量和默认加载因子 (0.75) 的新空链接哈希 set

        源码:

        

        

      3、TreeSet

        TreeSet:可以按照添加对象的指定属性,进行排序,底层使⽤红⿊树,能够按照添加元素的顺序进⾏排序,排序的⽅式有⾃然排序和定制排序。

        构造方法:

    TreeSet() :构造一个新的空 set,该 set 根据其元素的自然顺序进行排序
    TreeSet(Comparator<? super E> comparator) :构造一个新的空 TreeSet,它根据指定比较器进行排序
    

        源码:

        

      4、小结

        (1)Set 的内部实现其实是一个 Map,即HashSet的内部实现是一个HashMap,TreeSet的内部实现是一个TreeMap,LinkedHashSet的内部实现是一个LinkedHashMap。

        (2)但是 Set 中只有一个元素,又是怎么变成(key,value)的呢?

          以 HashSet 的 add 方法为例:

        原来是,把添加到 Set 中的元素作为内部实现 map 的 key,然后用一个常量对象 PRESENT 对象,作为value。

        所有的 HashSet 共用同一个PRESENT对象,所有的 TreeSet 共用同一个 PRESENT对象,所有的 LinkedHashSet 共用同一个 PRESENT 对象。

        这是因为 Set 的元素不可重复和 Map 的 key 不可重复有相同特点。Map 有一个方法 keySet() 可以返回所有 key。

    三、实现类的对比

      1、Set 集合是有序的吗?

        ① 如果按照元素的存储顺序来说,有一些是可以保证的,有一些是不能保证的。唯有 LinkedHashSet可以保证元素添加的顺序

        ② 如果按照元素的大小顺序来说,有一些是可以保证的,有一些是不能保证的。唯有 TreeSet可以保证元素的大小顺序

        ③ HashSet:既不能保证添加顺序,也不能保证大小顺序。是完全无序的。

      2、HashSet 与 LinkedHashSet 区别?

        HashSet:完全无序。

        LinkedHashSet:是按照添加顺序来存储的。LinkedHashSet 是 HashSet 的子类,比 HashSet 多维护了添加的顺序。

        当既想要实现集合的元素的不可重复性,又想要保证元素的添加顺序,就选择使用LinkedHashSet(效率低),否则就用List系列或HashSet。

      3、HashSet 与 TreeSet 的区别?

        HashSet:完全无序。

        TreeSet:是按照存储元素的大小来排序,当你需要元素不可重复,又要给元素排大小时,就用TreeSet。

        注意:要用到TreeSet,存储的元素对象一定要实现 要用到TreeSet,一定要用java.lang.Comparable或java.util.Comparator

      3、如何保证元素不可重复的呢?(如何判断两个元素是重复的呢)

        (1)HashSet 和 LinkedHashset 集合:

            ① 先比较元素的 hash 值,如果 hash 值不一样,说明两个元素一定不相同。

            ② 如果 hash 值一样,再调用 equals 方法比较

        (2)TreeSet 集合:

           按照存储元素的大小来决定元素是否相同,如果两个元素大小“相等”就是相同的元素。即必须实现 java.lang.Comparable或java.util.Comparator。

    四、Set 的无序性与不可重复的理解

      1、无序性

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

      2、不可重复性

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

        不可重复性是指添加的元素按照 equals()判断时 ,返回 false,需要同时重写 equals()⽅法和 HashCode()⽅法。

      3、

    四、Set 中方法

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

      

    五、如何保证数据的一致性(不可重复性)?

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

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

      重写两个方法的小技巧:对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。

  • 相关阅读:
    Rsync
    SpringCloud-Eureka
    mysql-主从复制
    java中延迟任务的处理方式
    mysql-分组
    rpm相关
    shell中#*,##*,#*,##*,% *,%% *的含义及用法
    cygwin的用途
    cocos2d-lua-win
    ant打包遇到的问题
  • 原文地址:https://www.cnblogs.com/niujifei/p/14675877.html
Copyright © 2011-2022 走看看