Java : Set 集合详解

set 是 Collection 子接口,模拟了数学上集合的概念
  Set 只包含从 Collection 集成的方法,不过 Set 无法记住添加的顺序,不允许包含重复的元素,当视图添加两个相同元素进 Set 集合,添加操作失败,即 add() 方法返回 false。

  Set 判断两个对象是否相等用 equals,而不是用 == ,也就是说两个对象 equals 比较返回 true 的情况下,Set 集合是不会接受这两个对象的。

  HashSet 是 Set 接口最常用的实现类,顾名思义,底层采用了哈希表(散列/hash)算法,其底层其实也是一个数组,存在的意义是提供查询速度,插入速度也比较快,但是适用于少量数据的插入操作。

在 HashSet 中如何判断两个对象是否相同:

两个对象的 equals 比较相等,返回 true,则说明是相同对象
两个对象的 hashCode 方法返回值相等

ps : 二者缺一不可。

  存储在哈希表中的对象,都应该覆盖 equals 方法和 hashCode 方法,并且保证equals 相等的时候,hashCode 也应该相等。

各类型 hashCode 算法

类型HashCode 值
BooleanhashCode = (f ? 0 : 1)
整数类型(byte、short、int、char)hashCode = (int)f
longhashCode = (int)(f ^ (f >>> 32))
floathashCode = Float.floatToIntBits(f)
doublelong l = Double.doubleToLongBits(f)
hashCode = (int)(l ^ (l >>> 32))
普通引用类型hashCode = f.hashCode()

  TreeSet 集合是底层采用红黑树(R-B Tree)算法,会对存储的元素默认使用自然排序(从小到大)。

注:必须保证 TreeSet 集合中的元素对象是相同的数组类型,否则报错。

TreeSet的排序规则:

自然排序:TreeSet 调用集合元素的 compareTo 方法来比较元素的大小关系,然后将集合元素按照升序排列,要求 TreeSet 集合中元素得实现 java.util.Comparable 接口。
定制排序:在 TreeSet 构造器传递 java.lang.Comparator 对象,并覆盖 public int compare(Object o1,Object o2),再编写比较规则。

  TreeSet 调用集合元素的 compareTo 方法来比较元素的大小关系,然后将集合元素按照升序排序(从小到大)
注:要求 TreeSet 集合中元素得实现 java.util.Comparable 接口。

BigDecinal,BigInteger,ByteDouble,Float,Integet,LongShort:按数字大小排序。
Character 按字符的 Unicode 值的数字大小排序
String 按字符中字符的 Unicode 值排序
java.util.Comparable 接口 — >> 比较接口

覆盖 public int compareTo(Object o); 方法,在该方法中编写比较规则。
在该方法中,比较当前对象(this)和参数对象 o 做比较(严格上说比较的是对象中的数据):

this>0;返回正整数:1
this<0;返回负整数:-1
this==0;返回0,此时认为两个对象为同一个对象。

在 TreeSet 的自然排序中,认为如果两个对象做比较的 compareTo 方法返回的是 0,则以为是同一个对象。
定制排序:(从大到校,按照字符串长短等)
对于 TreeSet 集合而言,要么使用自然排序,要么使用定制排序。

Set接口的实现类
共同的特点:

都不允许元素重复。

都不是线程安全的类。

解决方案:Set s = Collections.synchronizedSet(Set 对象)

HashSet :

  不保证元素的先后添加顺序,底层采用的是哈希表算法,查询效率较高。
判断两个对象是否相等的规则:

equals比较为true

hashCode值相同

要求:存在在哈希表中的对象元素都得覆盖 equals 和 hashCode 方法

LinkedHashSet :

  HashSet 的子类,底层也采用的是哈希表算法,但是也使用了链表算法来维持元素的先后添加顺序,判断两个对象是否相等的规则和 HashSet 相同。因为需要多使用一个链表来记录元素的顺序,所以性能相对于 HashSet 较低,一般少用,如果要求一个集合既要包子元素不重复,又需要记录添加先后顺序,才选择使用 LinkedHashSet。

TreeSet :

  不保证元素的先后添加顺序,但是会对集合中的元素做排序操作。底层采用红黑树算法(树结构,比较擅长做范围查询)。
TreeSet 要么采用自然排序,要么定制排序。

自然排序:要求在 TreeSet 集合中的对象必须实现 java.lang.Comparable 接口,并覆盖 compareTo 方法。

定制排序:要求在构建 TreeSet 对象的时候,传入一个比较器对象(必须实现 java.lang.Comparator接口)在比较器中覆盖 compare 方法,并编写比较规则。

HashSet 做等值查询效率高,TreeSet 做范围查询效率高。

而更多的情况,都是做等值查询,在数据库的索引中做范围查询较多,所以树结构主要用于做索引,用来提高查询效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值