黑马程序员技术交流社区
标题:
关于HashSet中是否重复的理解
[打印本页]
作者:
张 涛
时间:
2012-9-8 14:11
标题:
关于HashSet中是否重复的理解
本帖最后由 张 涛 于 2012-9-9 17:20 编辑
import java.util.HashSet;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args) {
Person p1 = new Person(21);
Person p2 = new Person(23);
Person p3 = new Person(21);
//set
HashSet<Person> hashSet = new HashSet<Person>();//构造方法
hashSet.add(p1);
hashSet.add(p2);
hashSet.add(p3);
System.out.println("hashSet:"+hashSet.size());
Iterator<Person> i = hashSet.iterator();
while(i.hasNext()){
System.out.println(i.next());
i.remove();
}
System.out.println("hashSet:"+hashSet.size());
}
}
class Person {
int age;
Person(int age){
this.age = age;
}
@Override
public boolean equals(Object obj) {
Person s = (Person)obj;
return this.age == s.age;
}
@Override
public String toString() {
return "Person age = "+ age;
}
}
复制代码
结果:
hashSet:3
Person age = 21
Person age = 23
Person age = 21
hashSet:0
疑问:我重写了Person的equals方法,那么hashSet判断是否可重复不是依据equals吗?有两个21岁,不是不重复了吗?第二个21岁怎么会添加进去呢?
作者:
王德升
时间:
2012-9-8 14:24
武庆东 发表于 2012-9-8 14:19
稍等一下哈!
你这战术不错!
作者:
AngieFans85
时间:
2012-9-8 14:27
本帖最后由 马镱洵 于 2012-9-8 14:57 编辑
凡是使用HashSet,HashMap,HashTable这三个容器,要放入这三个容器的对象所属的类必须要实现hashCode()方法和equals()方法.因为这三个容器是先判断放进来的对象的Hash码,如果Hash码不相同,那么就不会进行equals比较了,而是直接把对象存放进来了.你要知道,如果不重写hashCode()方法,每个对象的Hash码都不一样,所以你的代码中,虽然p1和p3两个对象的age属性都为21,但是p1和p3两个对象的Hash码却不一样,p1和p3当然可以同时放进你的容器中了.
作者:
彭润生
时间:
2012-9-8 14:32
import java.util.HashSet;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args) {
Person p1 = new Person(21);
Person p2 = new Person(23);
Person p3 = new Person(21);
//set
HashSet<Person> hashSet = new HashSet<Person>();//构造方法
hashSet.add(p1);
hashSet.add(p2);
hashSet.add(p3);
System.out.println("hashSet:"+hashSet.size());
Iterator<Person> i = hashSet.iterator();
while(i.hasNext()){
System.out.println(i.next());
i.remove();
}
System.out.println("hashSet:"+hashSet.size());
}
}
class Person {
int age;
Person(int age){
this.age = age;
}
@Override
public boolean equals(Object obj) {
Person1 s = (Person1)obj;
return this.age == s.age;
}
public int hashCode(){//覆盖了这个,就年龄不能重复了,如果没有,则以对象的hash值来判断,以对象当然是不同的了
return age*10;
}
@Override
public String toString() {
return "Person age = "+ age;
}
}
/ /如果覆盖了hashCode方法,那么年龄就不能重复了,HashSet先通过hash值来判断对象是否相同,如果相同后才equals();
作者:
张 涛
时间:
2012-9-8 15:10
扫噶。
原来是hashCode()没有重写,谢谢。
作者:
舒远
时间:
2012-9-8 15:11
因为没有重写hashCode方法,默认添加对象的时候会调用Object的hashCode方法,因为三个对象的内存地址都不同,那么比较hashCode则不同。所以都被添加进HashSet了。
HashSet在添加内容的时候是根据对象的hashCode和equals方法同时为true的时候才能判定重复。
作者:
广驰
时间:
2012-9-8 15:44
hashset判断元素是否相同的第一依据是hashCode是否相同,相同才执行equlas,equlas后还相同就代表元素重复,不同就放在相同hashCode的地址块中,如果hashCode都不同,那就不用调用equlas;
作者:
方志亮
时间:
2012-9-8 19:28
HashSet
底层数据结构是哈希表。线程不安全。
如果保证元素的唯一性呢?
A:首先根据hashCode值判断。
B:如果hashCode值不同,那么,这就是不同的元素。直接存储。
如果hashCode值相同,那么,会继续根据equals方法进行判断,
根据自己的需求来决定元素是否相同。如果相同,就不存储。否则,存储。
一般,用HashSet的时候,要重写hashCode和equals方法。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2