java set集合的底层_Java学习疑点(6)--Set集合添加元素时底层如何实现无重复元素?...

最近在学习Collection时发现Set集合的一个显著特点: 不包含重复元素.经过测试之后发现Set集合在向其添加元素时add()和addAll()方法就对元素进行了"审查", 对比查看是否为尚未存在的元素然后选择是否添加进去. 关于这两种方法底层是如何实现的, 就是我在这里想要说明的.

我们知道Set集合是建立在Map的基础之上, 其绝大多数方法构造时都是直接引用了Map中的方法.

这里我们先以HashSet列举一个事例:

HashSet hs = new HashSet();

System.out.println(hs.add(null));

System.out.println(hs.add(null));

System.out.println(hs.add("Shawyeok"));

System.out.println(hs.add("Java"));

System.out.println(hs.add("Shawyeok"));

这里hs在调用add()向内添加元素的时候, 首先会判断元素是否为null(Set的这种不重复元素特性注定会出现一个现象----一个Set集合中最多只能包含一个null元素)若为null则会查找集合中是否有null元素, 若没有则添加成功, 返回true; 反之则添加失败, 返回false.

若元素非null, 则首先调用元素的hashCode()方法得到其哈希值与集合中的各个元素的哈希值一一比较, 如果不相同说明这是两个不同的元素, 可以添加;  如果相同则再调用equals方法对两个元素进行比较, 若equals方法返回true则说明两个元素是同一元素, 不能添加; 反之, 说明两元素非同一元素, 可以添加.

下面是运行结果:

true

false

true

true

false

如何向Set集合中添加我们自己定义的类的对象呢?

上面已经说明了Set集合是如何保证不添加重复元素的, 我们可以想到重写继承自Object类中hashCode()以及equals()方法来保证不添加重复元素. 同样的, 写一个事例:

import java.util.*;

class Test {

public static void main(String[] args) {

HashSet hs = new HashSet();

Person Tim = new Person("Tim", Person.MAN, 176);

Person Jine = new Person("Jine", Person.WOMAN, 173);

System.out.println(hs.add(Tim));

System.out.println(hs.add(Jine));

System.out.println(hs.add(new Person("Tim", Person.MAN, 176)));

}

}

class Person {

private String name;

private boolean gender;//true:man ; false:woman

private int height;

public static final boolean MAN = true;

public static final boolean WOMAN = false;

public Person(String name, boolean gender, int height) {

this.name = name;

this.gender = gender;

this.height = height;

}

public int hashCode() {

int sum = name.hashCode() + height*2;//这里height乘以2是为了尽量保证不同元素哈希值的唯一性

if(gender) {

sum++;

} else {

sum--;

}

return sum;

}

public boolean equals(Object obj) {

if(!(obj instanceof Person)) {

return false;

}

Person p = (Person)obj;

if(this.name != p.name) {

return false;

}

if(this.gender != p.gender) {

return false;

}

if(this.height != p.height) {

return false;

}

return true;

}

}

下面是程序打印结果:

true

true

false

从结果可以看出以上的分析是正确的.

注: 以上分析可能会有讲述不妥以及语义欠缺的情况, 敬请谅解.关于Set集合更多特性的详细信息请参考阅读Java源代码.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值