【Java学习笔记】Hashset判断自定义对象是否重复
2013-09-13 11:24
429 查看
昨天去面试,考官问了一个关于Java的容器Hashset的问题,是说在加入自定义的对象时,如何设置对象的某一个属性为关键属性,即该属性相同则不能添加,该属性不同则可以添加。用Java编程还是太少,之前真的是没有遇到过类似问题,所以当时瞎扯一通,很遗憾也没有猜对。回来看了看网上的讲解,自己又编了个程序试了试,终于明白了一点。唉,编程这东西,不积跬步无以至千里啊!
首先我编程发现,即使一模一样的两个对象,加入到Hashset中也是可以的。
如上面这段代码,建立了一个Car类,创建两个对象car和bus,这两个对象的价格都是1,颜色都是black,但是竟然可以都加入到Hashset中去!
为什么会这样呢?我上网搜了一下,Hashset在判断是否重复时,按如下机制进行工作当调用了 HashSet 的 add 方法存放对象 obj , HashSet 会首先调用 obj 的 hasCode 方法得到该对象的哈希码, HashSet 会使用一个算法把它的哈希码转换成一个数组下标,该下标“标记”了
obj 的位置。如果这个位置上的链表中没有元素,那么就把 obj 对象添加到链表上。如果这个位置上的链表中已经有了元素,则遍历这个链表,调用 obj 的 equals 方法,判断 obj 是否和其中的某个元素重复,如果没有重复的元素,那么就将 obj 添加到链表上;如果有重复的元素,则不会将 obj 对象存入 HashSet 中。另外自定义子类是继承了Object类的,其中判断重复的equals方法也是继承了父类的,所以我们要重写equals方法如下:
这样就是以价格这一属性为关键属性进行比较对象是否重复了。
但是还没结束,上面已经说过了,如果hashCode返回值不同是不可能去调用equals方法去判断的,也就是还要重写hashCode,保证相同属性的对象hashCode也一样,所以重写hashCode如下:
同时覆盖了这两个函数后,我们的工作就完成了,为了显示清楚,再重写toString方法:
至此我们再进行试验就会发现,只要是价格相同的对象是无法同时添加进入hashset中去的了!
首先我编程发现,即使一模一样的两个对象,加入到Hashset中也是可以的。
import java.util.HashSet; public class Car { private int price; private enumcolor color; public enum enumcolor{ red,blue,black,white; private String value; public void setcolor(String c){ this.setColor(c); } public String getColor() { return value; } public void setColor(String color) { this.value = color; } } public Car(int pri,enumcolor ecolor){ this.price=pri; this.color=ecolor; } public enumcolor getColor() { return color; } public void setColor(enumcolor color) { this.color = color; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } protected void showPrice(){ System.out.println(this.price); } public static void main(String args[]){ enumcolor cl1=enumcolor.black; enumcolor cl2=enumcolor.red; Car car = new Car(1,cl1); Car bus = new Car(1,cl1); HashSet<Car> carSet = new HashSet<Car>(); carSet.add(car); carSet.add(bus); System.out.println(carSet); for(Car ite:carSet){ System.out.println(ite); } } }
如上面这段代码,建立了一个Car类,创建两个对象car和bus,这两个对象的价格都是1,颜色都是black,但是竟然可以都加入到Hashset中去!
为什么会这样呢?我上网搜了一下,Hashset在判断是否重复时,按如下机制进行工作当调用了 HashSet 的 add 方法存放对象 obj , HashSet 会首先调用 obj 的 hasCode 方法得到该对象的哈希码, HashSet 会使用一个算法把它的哈希码转换成一个数组下标,该下标“标记”了
obj 的位置。如果这个位置上的链表中没有元素,那么就把 obj 对象添加到链表上。如果这个位置上的链表中已经有了元素,则遍历这个链表,调用 obj 的 equals 方法,判断 obj 是否和其中的某个元素重复,如果没有重复的元素,那么就将 obj 添加到链表上;如果有重复的元素,则不会将 obj 对象存入 HashSet 中。另外自定义子类是继承了Object类的,其中判断重复的equals方法也是继承了父类的,所以我们要重写equals方法如下:
@Override public boolean equals(Object st) { Car tempcar= (Car) st; if (price==tempcar.price) return true; else return false; }
这样就是以价格这一属性为关键属性进行比较对象是否重复了。
但是还没结束,上面已经说过了,如果hashCode返回值不同是不可能去调用equals方法去判断的,也就是还要重写hashCode,保证相同属性的对象hashCode也一样,所以重写hashCode如下:
public int hashCode() { return new Integer(price).hashCode(); }
同时覆盖了这两个函数后,我们的工作就完成了,为了显示清楚,再重写toString方法:
public String toString(){ return "color:"+color+",price:"+price; }
至此我们再进行试验就会发现,只要是价格相同的对象是无法同时添加进入hashset中去的了!
相关文章推荐
- Java中HashSet存储对象判断是否重复原理分析
- java怎么判断两个Set 里的对象的值是否相同【两个set中的值是否相等】、java treeset和hashset如何判断元素是否相同【即对象是否完全相同;利用一个set去除重复元素】
- 向HashSet插入自定义对象判断是否重复
- 【Java学习笔记】HashSet中加入自定义的类的对象
- 【Java学习笔记】HashSet中加入自定义的类的对象
- JAVA学习笔记_判断二位数组是否存在连续4个数的值相同
- 算法学习(java实现之字符串篇)·····判断字符串是否没有重复字符
- Java学习笔记72. 操作线程 -- 判断线程是否启动
- 深入理解Java虚拟机笔记---判断对象是否存活
- 深入理解Java虚拟机笔记---判断对象是否存活
- Java学习拾遗3——HashSet中加入自定义的类的对象
- ArrayList,HashSet判断对象是否重复的原理
- JAVA基础之——HashSet中是如何判断元素是否重复的
- java中使用hashSet的特性,判断数组是否有重复值
- java判断List<T>对象是否唯一、去重复
- 学习体会:在JAVA中如何判断两个对象是否相等
- Java判断一个值,或者对象是否存在list集合中和去掉list集合中重复的元素
- effective-java学习笔记(2)避免在程序中创建重复的对象
- Activiti 学习笔记十:开始活动节点(判断流程是否结束及查询历史)
- 【学习笔记14】java面向对象-成员内部类、局部内部类