由于经常忘记关于hashset及hashmap中插入重复值时hashcode及equals的是怎样执行的,所以把一个例子记录下来来,省得以后忘记!首先引用老紫竹(java2000_net)的一个测试例子:
import java.util.HashSet;
import java.util.Set;
/**
* 老紫竹JAVA提高教程(2)-认识Set集合之HashSet。<br>
* Set用来保存不允许重复的数据。可以是任何对象类型。<br>
* JDK5以后,主类型可以通过autobox 放入Set里面。
*
* @author 老紫竹 JAVA世纪网(java2000.net)
*
*/
public class lession1 {
public int age;
public String name;
public static void main(String[] args) {
// 测试HashSet的特殊性
testForHashSet();
}
/**
* 专门针对HashSet的测试。
*/
public static void testForHashSet() {
System.out.println("----- testForHashSet -----------");
HashSet set = new HashSet();
// 增加一个null对象
set.add(null);
// 我们再次看看集合里对象的数量
System.out.println(set.size());
// 再次增加一个null看看
set.add(null);
// 我们再次看看集合里对象的数量
System.out.println(set.size());
MyObject obj = new MyObject("java2000", 2);
set.add(obj);
System.out.println("1----");
set.add(new lession1());
System.out.println("2----");
obj = new MyObject("csdn", 10);
set.add(obj);
// 我们再次看看集合里对象的数量
System.out.println(set.size());
// 判断是否包含某个对象
System.out.println(set.contains(obj));
obj = new MyObject("java2000_net", 2);
set.add(obj);
// 我们再次看看集合里对象的数量
System.out.println(set.size());
// 我们尝试把obj再次放入set看看
// 并没有增加,因为是重复的
System.out.println("---");
set.add(obj);
System.out.println(set.size());
// 我们构造一个新的对象,内容和前面的相同
obj = new MyObject("java2000_net", 2);
set.add(obj);
System.out.println(set.size());
// 我们修改一下obj里面的年龄,再看看
obj.setAge(3);
// 我们再测试看看是否包含此对象。
// 请注意,我们这个obj和前面的obj是同一个对象
// 我们仅仅修改了一下我们的年龄
System.out.println(set.contains(obj));
// 我们尝试把obj再次放入set看看
// 我们又增加了长度
set.add(obj);
System.out.println(set.size());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
System.out.println("lession hashcode "+result);
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("lesson equals");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final lession1 other = (lession1) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
/**
* @author Administrator
*
*/
class MyObject {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
MyObject(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
System.out.println("hashCode"+result);
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("equals");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final MyObject other = (MyObject) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
执行结果:
----- testForHashSet -----------
1
1
hashCode-582794785
1----
lession hashcode 961
2----
hashCode3064305
4
hashCode3064305
true
hashCode-337761603
5
---
hashCode-337761603
5
hashCode-337761603
equals
5
hashCode-337761572
false
hashCode-337761572
6
从结果集中不难看出每在hashset中增加一个对象,就会执行一次hashcode。所以判断两个对象是否重复首先得判断hashcode是否相等。如果不相等则说明是两个不同的对象,可以插入。
那hashcode相等的情况下怎么判断是否重复呢?
满足如下条件之一即可:
条件1:插入的引用的是同一个对象且equals 相等。比如上例中的
// 我们构造一个新的对象,内容和前面的相同
obj = new MyObject("java2000_net", 2);
set.add(obj);
条件2:插入同一个引用。比如上例中的
obj = new MyObject("java2000_net", 2);
set.add(obj);
set.add(obj);
此外这个例子还能说明一个问题:
如果是第二种插入
obj = new MyObject("java2000_net", 2);
set.add(obj);
set.add(obj);
则不会进行euqals比较,直接认为是重复。相当于==成立,如果在第二次插入之间改变某一属性则可能会导致hashcode改变则直接可以插入,就如上例子中最后一些代码
// 我们修改一下obj里面的年龄,再看看
obj.setAge(3);
// 我们再测试看看是否包含此对象。
// 请注意,我们这个obj和前面的obj是同一个对象
// 我们仅仅修改了一下我们的年龄
System.out.println(set.contains(obj));
// 我们尝试把obj再次放入set看看
// 我们又增加了长度
set.add(obj);
分享到:
相关推荐
主要介绍了重写hashCode()和equals()方法详细介绍,涉及重写equals()方法,重写hashCode()方法,重写equals()而不重写hashCode()的风险等相关内容的介绍,具有一定借鉴价值,需要的朋友可以参考下
原因是因为,在Java自带的容器HashMap和HashSet中, 都需同时要用到对象的hashCode()和equals()方法来进行判断,然后再插入删除元素,这点我们一会再谈。 那么我们还是单独来看hashCode(),为什么HashMap需要用到...
Java集合中有两类,一类是List,一类是Set他们之间的区别就在于List集合中的元素师有序的,且可以重复,而Set集合中元素是无序不可重复的。对于List好处理,但是对于Set而言我们要如何来保证元素不重复呢?通过迭代...
HashSet 是如何保证不重复的 向 HashSet 中 add ()元素时...重复( HashMap 比较key是否相等是先比较 hashcode 在比较 equals )。 HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程 环境下不安全)?
set集合是无序的相较于list集合是没有下标的,hashset底层去重,与hashCode、equals方法相关,排序的元素不是String,而是对象Person
HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有...
简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等注意,如果要把一个对
记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。 一般情况下,如果自定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。 建立对象判断是否相同的依据。...
注意:因为Person类是自定义类,需要重写hashCode()方法和equals()方法,并规定只有姓名和身份证号都相等,则对象相等。 其中计算哈希码的算法:(31 + ((name == null) ? 0 : name.hashCode()))*31 + id (注:...
中只有值传递、==与equals、 hashCode与equals) (String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) (Arraylist 与 LinkedList ...
中只有值传递、==与equals、 hashCode与equals) (String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......) (Arraylist 与 LinkedList ...
java8 集合源码分析 ...保证唯一性:元素hashCode和equals方法。hashCode方法相同,判断equals方法 ---LinkedHashSet: 有序,是HashSet的子类 2.TreeSet: 底层是二叉树,可对元素进行排序,默认是自然顺序
Java类集框架 最大单值操作父接口Collection及其子接口、子类: List接口、ArrayList类、Vector类、栈操作类Stack、链表操作类LinkList、队列操作接口Queue、Set接口、...Comparable接口、equals()方法、hashCode()方法
数据结构java队列——queue详细解析Queue:先进先出(FIFO)的数据结构。与List、Set同一级别,都...HashSet不存入重复元素的规则是:hashCode()和equals()。元素的哈希值通过元素的hashCode()方法来获取,hashSet首先会
HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有...
1、java中==和equals和hashCode的区别 2、int与integer的区别 3、String、StringBuffer、StringBuilder区别 4、什么是内部类?内部类的作用 5、进程和线程的区别 6、final,finally,finalize的区别 7、...
jdk 的集合框架的主体结构: Set 成员不能重复 HashSet 外部无序地遍历成员。 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。
底层哈希表,基于hashCode的equals的比较方式,线程不安全,存取速度快。 SortedSet 标记: interface TreeSet 标记: class 实现comparable接口,元素是以二叉树的形式存放的。线程不安全 CopyOnWriteArraySet 标记:...
} public Boolean equals(Object b){return true} public static void main(String args[]){ Set set=new HashSet(); set.add(new A()); set.add(new A()); set.add(new A()); System.out....
hash 值如何求,hashCode 是什么,用来做什么 2. 冲突 1. 什么是冲突 2. 怎么避免冲突 3. 冲突了怎么办 3. equals 方法用来做什么 4. hash 表用在 Java 中是什么形式的 1. HashMap 是什么 2. HashSet 是什么...