Java集合之HashMap

首先上图:

Map接口是一种双列集合,不同于List和Set这些单列集合,它的每一个元素都包含一个键值对key和value,键和值对象之间存在一种对应关系,称为映射。从Map集合中访问元素时,只要指定了key,就可以通过key找到对应的value。由图可知,HashMap是Map接口的实现类,它基于哈希表,必须保证不出现重复的键,但没要求值也要唯一(相同的值可以有多个键对应),并且键和值都允许使用null,但它不保证映射的顺序(即存入顺序和取出顺序可能不一致)

HashMap实例有两个参数影响其性能,初始容量 加载因子,初始容量是创建实例时定义的哈希表中捅的数目,加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度(假设起初初始容量为16,加载因子为0.75,那么当哈希表中的条目数超过容量和因子的乘积时(即16*0.75=12),哈希表将进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。)

通常,默认加载因子 (0.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。也就是说如果有很多映射关系要存储在 HashMap 实例中,使用足够大的初始容量创建HashMap实例将使得映射关系能更有效地存储。(因为减少了rehash操作的次数)

注意,HashMap是不同步的,即线程不安全。如果需要同步,则要自己封装,使其变为同步,以满足自己的需求。下面通过一些带代码来看看HashMap的一些常用方法。

package practice;
import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;
public class HashMapPractice {
	public static void main(String args[]) {
		HashMap hm = new HashMap();
		hm.put(1, "Jack");//添加映射关系
		hm.put(1, "Rose");
		hm.put(null, "Lucy");//键为null
		hm.put("2", null);//值为null
		Set s = hm.keySet();//得到Map中所有键的集合
		Iterator it = s.iterator();//得到集合set的迭代器
		while(it.hasNext()){//遍历迭代器
			Object key = it.next();//set中的每一个元素是Map中的一个键
			System.out.println(key + " : "+hm.get(key));//根据键获得相应的值
		}
	}
}

运行结果:

null : Lucy
1 : Rose
2 : null

由结果可以看出,HashMap添加元素时使用的是put,而单列集合使用的是add。它允许使用null键和null值,并且当出现重复的键时,后存储的值会被原有的覆盖,简言之就是:键相同,值覆盖。

HashMap的遍历方法:

package practice;
import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;
import java.util.Collection;
public class HashMapPractice {
	public static void main(String args[]) {
		HashMap<Integer,String> hm = new HashMap();
		hm.put(0, "Jack");
		hm.put(1, "Rose");
		hm.put(2, "Lucy");
		hm.put(4, "Tom");
		/*
		 *第一种遍历方法:通过keySet方法得到Map中所有的键
		 *然后通过这些键得到相应的值 
		 */
		Set s = hm.keySet();//得到Map中所有键的集合
		Iterator it = s.iterator();//得到集合set的迭代器
		while(it.hasNext()){//遍历迭代器
			Object key = it.next();//set中的每一个元素是Map中的一个键
			System.out.println(key + " : "+hm.get(key));//根据键获得相应的值
		}
		System.out.println();
		/*
		 * 第二种遍历方法:通过entrySet方法得到Map中所有的映射关系
		 * 然后遍历集合中的Entry实例,通过Entry类的getKey和getValue
		 * 方法取得键和值
		 */
		Set entrySet = hm.entrySet();//获取集合中所有的映射关系
		it = entrySet.iterator();//获取集合的迭代器
		while(it.hasNext()) {
			Map.Entry entry = (Map.Entry)it.next();//得到Entry实例
			System.out.println(entry.getKey()+" : "+entry.getValue());//通过getKey和getValue方法得到键和值
		}
		System.out.println();
		for(Object obj : entrySet) {//也可用foreach循环遍历entrySet
			Map.Entry entry = (Map.Entry)obj;
			System.out.println(entry.getKey()+" : "+entry.getValue());
		}
		System.out.println();
		/*
		 * 第三种遍历方法:通过HashMap类的values方法
		 * 这种方法只能得到所有的值,不能得到对应的键
		 */
		Collection c = hm.values();
		for(Object obj : c)
			System.out.print(obj +" ");
	}
}

HashMap类的其他常用方法:

package practice;
import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;
import java.util.Collection;
public class HashMapPractice {
	public static void main(String args[]) {
		HashMap<Integer,String> hm = new HashMap();
		//put方法向Map中添加映射对
		hm.put(0, "Jack");
		hm.put(1, "Rose");
		hm.put(2, "Lucy");
		hm.put(4, "Tom");
		System.out.println("0对应的值为:"+hm.get(0));//通过键得到值
		System.out.println("是否包含键为1的映射对:"+hm.containsKey(1));//如果此映射包含对于指定键的映射关系,则返回 true
		System.out.println("是否包含值为Tom的映射对:"+hm.containsValue("Tom"));//如果此映射将一个或多个键映射到指定值,则返回 true
		hm.remove(4);//从此映射中移除指定键的映射关系(如果存在)
		System.out.println("是否包含键为4的映射对:"+hm.containsKey(4));
		hm.clear();//清空集合中所有的映射关系
		System.out.println("Map中映射对有:"+hm.size());//得到集合中映射对的数目
	}
}

运行结果:

0对应的值为:Jack
是否包含键为1的映射对:true
是否包含值为Tom的映射对:true
是否包含键为4的映射对:false
Map中映射对有:0
 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值