黑马程序员 集合学习笔记二

Java Map接口详解
本文详细介绍了Java中Map接口及其主要实现类的特点与应用场景,包括Hashtable、HashMap和TreeMap,并通过示例展示了如何获取Map集合中的元素。

----------android培训java培训、java学习型技术博客、期待与您交流!----------

 

Map<K,V>:Map接口声明从关键字K到值V的映射,实现Map接口的类主要有Hashtable、HashMap和TreeMap,Set集合底层通过Map实现的,其中方法

Collection<V>values() 返回映射中包含的值的Collection 视图。特殊之处是方法put(K key, V value)返回不是boolean值,而是V类型的value值,若键重复,则返回的是前一个键对应的value,且用后续的value覆盖之前的value如:

map.put(1, "w01");

System.out.println(map.put(2, "w02"));//打印结果为w01

 

因为该方法的特性,所以一个很常见的应用是利用TreeMap集合判断字符串中某个字母出现的次数

1、Hashtable:通过hash表结构实现Map,该实现是同步的。Hashtable中不可以存入null键和null值。

2、HashMap:通过hash表结构实现Map,该实现不是同步的。HashMap中可以存入null键和null值。通过键的publicint hashCode()及public Boolean equals(Object obj)方法保证键的唯一性。HashMap通过hash码对其内部的映射关系进行快速的查找,HashMap类实现的Map集合对于添加和删除操作效率较TreeMap的更高。

3、TreeMap:通过二叉树结构实现Map,该实现不是同步的。该映射根据其键的自然顺序进行排序,通过元素实现Comparable接口的int  compareTo(T o)方法使键具有可比性,也可以构造比较器进行特殊比较。TreeMap中的映射关系存在一定的顺序,如果希望Map集合中的映射值也存在一定的顺序,应该使用TreeMap实现Map集合。

4、Map集合中元素的获取,通过查看API发现Map集合没有提供直接的迭代器,但是提供了以下方法:

Set<K>

keySet() 返回此映射中包含的键的Set 视图。

V

get(Object key)返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null

Set<Map.Entry<K,V>>

entrySet()返回此映射中包含的映射关系的 Set视图。

所以可以采取以下两种方式获取集合的元素


(1)、通过keySet方法获取键的Set集合,而Set集合提供了迭代器,那么可以通过迭代器迭代Map集合的键,再通过get(Object key)方法获取键所对应的的值。一个简单的示例:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapGetElements {

	
	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>();
		map.put("w001", "aaa");
		map.put("w002", "bbb");
		map.put("w003", "ccc");
		map.put("w004", "ddd");
		
		Set<String> keySet = map.keySet();
		Iterator<String> it = keySet.iterator();
		
		while(it.hasNext()){
			String key = it.next();
			String value = map.get(key);
			System.out.println(key+"="+value);
		}		
	}
}

(2)、

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class MapGetElements {

	
	public static void main(String[] args) {
				Map<String,String> map = new HashMap<String,String>();
		map.put("w001", "aaa");
		map.put("w002", "bbb");
		map.put("w003", "ccc");
		map.put("w004", "ddd");
		
		Set<Map.Entry<String, String>> entrySet = map.entrySet();
		Iterator<Entry<String, String>> it = entrySet.iterator();
		
		while(it.hasNext()){
			Entry<String, String> element = it.next();
			String key = element.getKey();
			String value = element.getValue();
			System.out.println(key+"="+value);
		}
	}
}


这里,while循环的遍历也可以采用for的增强形式进行遍历,此时便不需要迭代器

for (Entry<String, String> entry : entrySet) {

            String key = entry.getKey();

            String value = entry.getValue();

            System.out.println(key+"="+value);

}



public interface Map<K,V> {
// 查询
	int size();
	boolean isEmpty();
	boolean containsKey(Object key);
	boolean containsValue(Object value);
	V get(Object key);
// 修改
	V put(K key, V value);
	V remove(Object key);
// 块操作
	void putAll(Map<? extends K, ? extends V> m);
	void clear();
// 视图
	Set<K> keySet();	// 因为key值不允许重复,所以用Set
	Collection<V> values();	// 而value值是允许重复的,所以用Collection
	Set<Map.Entry<K, V>> entrySet();	// Map 的 entrySet() 方法返回一个实现 Map.Entry 接口的对象集合。集合中每个对象都是底层 Map 中一个特定的键-值对。
	interface Entry<K,V> {//详细介绍:http://zhidao.baidu.com/question/32679780.html
		K getKey();
		V getValue();
		V setValue(V value);
		boolean equals(Object o);
		int hashCode();
    }
// 比较 希哈
	boolean equals(Object o);
	int hashCode();
}

对于 Map 接口,在“集合框架”中也有两个常规实现类,和 Set 接口类似,他们是:

HashMap

更适合Map中插入、删除和定位元素

使用HashMap要求添加的键类明确定义了hashCode()实现

TreeMap

适合按顺序遍历键。

有了TreeMap实现,添加到映射的元素一定是可排序的

实例:

public class Demo {
        public static void main(String[] args) throws Exception {
        	String[] arg={"zhang","jin","yu","is","zhang","yun","yuan's","borather","and","is","wang","qi's","husband"};
        	Map map=new HashMap<>();
        	Integer ONE=new Integer(1);
        	for(int i=0, n=arg.length; i<n; i++){
        		String key=arg[i];
        		Integer frequency=(Integer)map.get(key);
        		if(frequency==null){
        			frequency=ONE;
        		}else{
        			int value=frequency.intValue();
        			frequency=new Integer(value+1);
        		}
        		map.put(key, frequency);
        	}
        	System.out.println(map);
        	Map sorted_map=new TreeMap(map);
        	System.out.println(sorted_map);
        }
}
运行结果:
{jin=1, is=2, yu=1, qi's=1, yuan's=1, zhang=2, yun=1, borather=1, husband=1, wang=1, and=1}
{and=1, borather=1, husband=1, is=2, jin=1, qi's=1, wang=1, yu=1, yuan's=1, yun=1, zhang=2}
结果分析:
<span style="color:#FF0000;">
当map中已经有一个Key为“zhang”时,再往其中添加Key值为“zhang”的key-value对会覆盖之前的。
</span> 

为了优化HashMap空间的使用,可以调优初始容量和负载因子。这个TreeMap没有调优选项,因为该树总处于平衡状态(和Set中一样)。

AbstractMap(抽象类)

AbstrctMap类也覆盖了equals()hashCode()方法,以确保两个相等映射返回相同的散列码。如果两个映射大小相等、包含同样的键且每个键在这两个映射中对应的值都相同,则这两个映射相等。按定义,映射的散列码是映射元素散列码的总和,其中每个元素是Map.Entry接口的一个实现。因此,不论映射内部顺序如何,两个相等映射会报告相同的散列码。

总结:使用HashMap要求添加的键类明确定义了hashCode()实现


 

----------android培训java培训、java学习型技术博客、期待与您交流!----------

 

(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值