黑马程序员技术交流社区
标题:
关于集合框架的疑问
[打印本页]
作者:
吴通
时间:
2012-8-28 22:04
标题:
关于集合框架的疑问
我们的集合List Set Map等
当定义了一个集合时,它应该就具备了自己特有的属性,
像ArrayList就是数组结构的,LinkedList是链表数组结构的
既然数组都有自己特有的属性,那么为什么我们在存取数组的时候还要刻意的
去复写某些方法 以HashSet为例:
import java.util.*;
class HashSetDemo
{
public static void main(String[] args)
{
HashSet al=new HashSet();
al.add(new Person("a1",11));
al.add(new Person("a2",12));
al.add(new Person("a3",13));
al.add(new Person("a4",12));
}
}
class Person
{
private String name;
private int age;
//复写hashCode方法
public int hashCode()
{
return name.hashCode()+age;
}
//定义特有的equals方法
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p=(Person)obj;
return this.name.epuals(p.name)&&tis.age==p.age;
}
Person(String name,String age)
{
this.name=name;
this.age=age;
}
//省略了set步骤
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
HashSet集合要复写HashCode和equals方法,我感觉好像并不是这个数组具有
这样的特性,而是我们刻意强加给它的,既然这样我们是不是刻意按照自己的需求再自定义
自己想要的集合类型呢?一直搞不明白!求指教
作者:
唐志兵
时间:
2012-8-28 22:29
本帖最后由 唐志兵 于 2012-8-28 22:56 编辑
Set集合是继承的 Collection接口,它的特性是不允许存放两个相同的元素。
HashSet al=new HashSet();
al.add(new Person("heima",2));
al.add(new Person("heima",2));
复制代码
如果在没有复写hashcode和equal的情况下上面的代码运行后会发生什么事呢,你觉得这两个元素能否被添加到集合当中去呢?
答案是 能够被添加到集合当中,因为它们虽然是两个相同的对象。但是它们在堆内存当中有不同的地址,所以它们的hashcode也会不相同。这样程序就会认为它们是两个不同的对象,而set集合的特性是 不允许存放两个相同的元素。
为了避免上面的情况我们就可以再类中复写 equal跟 hashcode,这样在给集合添加元素的时候 会先判断两个元素的 hashcode是否相同,如果相同,则说明是两个重复的元素,如果不相同,则继续调用equal方法判断两个对象是否相同。这样我们就可以通过
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p=(Person)obj;
System.out.println("equal");
return this.name.equals(p.name)&& this.age==p.age;
}
复制代码
这样的代码来 防止在set集合当中添加了两个相同的元素。。。
版主给点分吧。。。打字很累的。
作者:
方志亮
时间:
2012-8-28 22:45
HashSet
底层数据结构是哈希表。线程不安全。
如果保证元素的唯一性呢?
A:首先根据hashCode值判断。
B:如果hashCode值不同,那么,这就是不同的元素。直接存储。
如果hashCode值相同,那么,会继续根据equals方法进行判断,
根据自己的需求来决定元素是否相同。如果相同,就不存储。否则,存储。
//复写hashCode方法
public int hashCode()
{
return name.hashCode()+age*17;//这里要随便乘以一个数 用来保证hashCode的值不为一
}
作者:
周兴华
时间:
2012-8-28 23:08
Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。
那么在调用集合的添加方法时,必然会对元素进行比较,如果重复就不存入,如果不重复就存入。
而这个比较的过程为:1、先比较hashCode值,如果不同,则将对象存入集合中;
2、如果hashCode值相同,则调用equals方法判断两个对象是否相同,如果相同不存入,如果不同则存入集合中。
如果没有重写hashCode方法,就会可能出现两个元素的hashCode值不同,但元素内容是一样的,此时就会重复添加元素。
如果没有重写equals方法,那么当两个元素不一样,hashCode值不同,但AbstractSet类的的equals方法判断两个元素相同,就会少添加元素。
以楼主的代码为例:
al.add(new Person("a1",11));
al.add(new Person("a2",12));
al.add(new Person("a2",12));
//如果没有重写hashCode方法,因为每次new Person对象都会给一个不同的hashCode值,故会将此对象存入集合,出现重复元素的情况
al.add(new Person("a3",13));
al.add(new Person("a3",12));
//如果没有重写equals方法,有可能底层的equals方法判断new Person("a3",12)和new Person("a3",13)这两个对象一样,则不存入集合
//则少添加元素
al.add(new Person("a4",12));
对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。因此,需要重写hashcode和equals方法。
作者:
吴通
时间:
2012-9-3 21:31
谢谢 已解决
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2