HashSet和HashMap

当在HashMap中添加key-value对,由其key的hashCode()返回值决定改key-value对的存储位置,当key-value对的key的hashCode()返回值相同时,key-value对的value将由key通过eqauls()比较值决定是采用覆盖行为(返回true)(key不做改变),还是产生key-value链(返回false)。
import java.util.*;
class Name
{
    private String first;
	private String last;
    public Name(String first, String last) 
	{
        this.first = first;
        this.last = last;
    }
	//根据first判断两个Name是否相等
    public boolean equals(Object o) 
	{
		if (this == o)
		{
			return true;
		}
		if (o.getClass() == Name.class)
		{
			Name n = (Name)o;
			return n.first.equals(first);
		}
		return false;
    }
	//根据first计算Name对象的hashCode()返回值
    public int hashCode()
	{
		return first.hashCode();
    }
	public String toString()
	{
		return "Name[first=" + first + ", last=" + last + "]";
	}
}
public class HashSetTest2
{
	public static void main(String[] args) 
	{
		HashMap<Name,String> set = new         HashMap<Name,String>(); 
		set.put(new Name("abc" , "123"),"1111111");
		set.put(new Name("abc" , "456"),"2222222");
		System.out.println(set);
	}
}
 输出:
{Name[first=abc, last=123]=2222222}
即key没变,value变了。

HashSet的实现只是封装了一个HashMap对象来存储所有的集合元素。所有放入HashSet中的集合元素实际上由HashMap的key来保存,而HashMap的value则存储了一个PRESENT,它是一个静态的Object对象。
由于HashSet的add()方法添加集合元素时实际上转变为调用HashMap的put()方法添加key-value对,当新放入HashMap的key-value对中key与集合中原有key-value对中的key相同(hashCode()返回值相等,通过eqauls()比较值也相等)时,新添加的key-value对的value将覆盖原来key-value对的value,但key不会有任何改变。因此,如果向HashSet中添加一个已经存在的元素,新添加的集合元素(底层由HashMap的key保存)不会覆盖已有的集合元素。
把上面代码main方法中改为:
HashSet<Name> set = new HashSet<Name>();
set.add(new Name("abc" , "123"));
set.add(new Name("abc" , "456"));
System.out.println(set);
则输出:
[Name[first=abc, last=123]]
即key没变


注意:在试图把某个对象当成HashMap的key,或者试图将这个类的对象放入HashSet中保存时,重写该类的equals(Object obj)方法和hashCode()方法很重要, 而且这两个方法的返回值必须一致。当该类的两个hashCode()返回值相同时,它们通过equals(Object obj)方法比较也应该返回true。通常来说,所有参与计算hashCode()返回值的关键属性,都应该用于作为equals(Object obj)比较的标准。
例如下面代码运行显示的是false,那是因为没有重写hashCode()方法。
import java.util.*;
/**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2010, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
class Name
{
    private String first;
	private String last;
    public Name(String first, String last) 
	{
        this.first = first;
        this.last = last;
    }
    public boolean equals(Object o) 
	{
		if (this == o)
		{
			return true;
		}
		if (o.getClass() == Name.class)
		{
			Name n = (Name)o;
			return n.first.equals(first)
				&& n.last.equals(last);
		}
		return false;
    }
}
public class HashSetTest
{
	public static void main(String[] args) 
	{
		Set<Name> s = new HashSet<Name>();
		s.add(new Name("abc", "123"));
		System.out.println(
			s.contains(new Name("abc", "123")));
	} 
}
 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值