Java中的集合(3)—— Set原理及用法 % ~ %

一、什么是Set?

Set是一种不包括重复元素的Collection无序,它维持它自己的内部排序,所以随机访问没有任何意义。

Set接口有三个具体实现类,分别是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet。

与List一样,它同样允许null元素的存在但是仅有一个

由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,即任意的两个元素e1和e2都有e1.equals(e2)=false,如果在对集合中元素进吃的行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。

Set是一种不包含重复的元素的Collection,Set最多有一个null。需要注意的是:虽然Set中元素没有顺序,但是元素在set中的位置是由该元素的HashCode决定的,其具体位置其实是固定的。

Set集合取出的元素的方式只有一种方式:迭代器。

此外需要说明一点,在set接口中的不重复是有特殊要求的。

二、如何保证Set中元素的唯一性

1、HashSet

我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数。

当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象。

如果没有哈希值相同的对象就直接存入集合

如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存

2、将自定义类的对象存入HashSet去重复

类中必须重写hashCode()和equals()方法

hashCode():属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)

equals():属性相同返回true, 属性不同返回false,返回false的时候存储

HashSet的实现方式大致如下,通过一个HashMap存储元素,元素是存放在HashMap的Key中,而Value统一使用一个Object对象。

三、HashSet

HashSet 是一个没有重复元素的集合。它是由HashMap实现的,不保证元素的顺序(这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致),而且HashSet允许使用null 元素。HashSet是非同步的,如果多个线程同时访问一个哈希set,而其中至少一个线程修改了该set,那么它必须保持外部同步。 HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能。

HashSet的实现方式:,通过一个HashMap存储元素,元素是存放在HashMap的Key中,而Value统一使用一个Object对象。

HashSet使用和理解中容易出现的误区:

1、HashSet中存放null值

HashSet中是允许存入null值的,但是在HashSet中仅仅能够存入一个null值。

2、HashSet中存储元素的位置是固定的

HashSet中存储的元素的是无序的,这个没什么好说的,但是由于HashSet底层是基于Hash算法实现的,使用hashcode,所以HashSet中相应的元素的位置是固定的。

3、必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。

四、LinkedHashSet

      LinkedHashSet继承自HashSet,其底层是基于LinkedHashMap来实现的,有序,非同步。LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。

五、TreeSet

     TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。

注意:TreeSet集合不是通过hashcode和equals函数来比较元素的.它是通过compare或者comparaeTo函数来判断元素是否相等.compare函数通过判断两个对象的id,相同的id判断为重复元素,不会被加入到集合中。

六、迭代器Iterator取值

从集合中取元素,无论是什么数据结构,最终共性的取出方式,一个一个取,取之前先判断,有元素,取, 没有不取结束,这种取出的共性方式:迭代。

官方示例:

for (Iterator iterator = hs.iterator(); iterator.hasNext();) {
    Person person = (Person) iterator.next();
}

如需要打印集合:

for (Iterator it = hs.iterator(); it.hasNext();) {
	Person person = (Person) it.next();
	System.out.println(person.getName());
}

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值