Java学习疑点(6)

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

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

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

HashSet<String> hs = new HashSet<String>();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则说明两个元素是同一元素, 不能添加; 反之, 说明两元素非同一元素, 可以添加.

下面是运行结果:

truefalsetruetruefalse

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

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

import java.util.*;class Test {public static void main(String[] args) {HashSet<Person> hs = new HashSet<Person>();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:womanprivate 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;}}

下面是程序打印结果:

truetruefalse

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

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

如果雨后还是雨,如果忧伤过后还是忧伤,

Java学习疑点(6)

相关文章:

你感兴趣的文章:

标签云: