【Java入门提高篇】Day19 Java容器类详解(二)Map接口
上一篇里介绍了容器家族里的大族长——Collection接口,今天来看看容器家族里的二族长——Map接口。
Map也是容器家族的一个大分支,但里面的元素都是以键值对(key-value)的形式存放的,就像字典一样,用相应的key就可以拿到相应的value。
先来看看Map接口的内容,下面是阉割版的Map接口(去掉了default method),去掉的部分涉及Stream操作,属于Map的高级用法,所以暂时不做介绍。
import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
import java.util.Objects;
import java.util.Set; public interface Map<K,V> {
// 查询操作 /**
* 返回键值对数量
*/
int size(); /**
* Map是否为空
*/
boolean isEmpty(); /**
* Map中是否包含指定的key
*/
boolean containsKey(Object key); /**
* Map中是否包含指定的value
*/
boolean containsValue(Object value); /**
* 根据key获取对应的value
*/
V get(Object key); // Modification Operations /**
* 插入键值对,如果Map中已经存在该key,则新的value会覆盖原来的value
*/
V put(K key, V value); /**
* 移除指定key对应的键值对,并返回相应的value
*/
V remove(Object key); // 批量操作 /**
* 将另一个Map中的键值对全部复制过来
*/
void putAll(Map<? extends K, ? extends V> m); /**
* 移除所有键值对
*/
void clear(); // 视图 /**
* 返回包含Map中所有key的(Set类型)键视图,对Map的修改也会影响到键视图
*/
Set<K> keySet(); /**
* 返回包含Map中所有value的(Collection类型)值视图,对Map的修改也会影响到值视图
*/
Collection<V> values(); /**
* 返回包含Map中所有键值对的(java.util.Map.Entry类型)键值对视图
*/
Set<Map.Entry<K, V>> entrySet(); /**
* Map 键值对接口
*/
interface Entry<K,V> {
/**
* 返回键
*/
K getKey(); /**
* 返回值
*/
V getValue(); /**
* 设置键
*/
V setValue(V value); boolean equals(Object o); int hashCode(); /**
* 键比较器(内部比较器)
*/
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getKey().compareTo(c2.getKey());
} /**
* 值比较器(内部比较器)
*/
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> c1.getValue().compareTo(c2.getValue());
} /**
* 键比较器(外部比较器)
*/
public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
} /**
* 值比较器(外部比较器)
*/
public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
Objects.requireNonNull(cmp);
return (Comparator<Map.Entry<K, V>> & Serializable)
(c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
}
} // 比较和散列 boolean equals(Object o); int hashCode();
}
可以看到,Map接口的内容,其实比Collection接口更丰富,这里因为省略了很多高级方法,而且里面包含了另外一个接口,Map.Entry接口,也就是一直所说的键值对,这个接口是Map中元素需要实现的接口。
Map有三种遍历方式:1.通过遍历KeySet来遍历所有键值对,2.通过遍历EntrySet来实现,3.通过EntrySet的Iterator来遍历。这里还有一个新概念——视图,视图其实就是一个集合,但是是一个不能修改的集合,只能对视图进行查询和遍历操作,在Map中一共有三个视图,键视图,值视图,键值对视图,下面可以看一个小栗子:
public class Test {
public static void main(String[] args){
Map<Integer, Integer> map = new HashMap<>();
map.put(1,11);
map.put(2,22);
map.put(3,33); Set<Integer> keys = map.keySet();
Collection<Integer> values = map.values();
Set<Map.Entry<Integer,Integer>> entries = map.entrySet();
Iterator<Map.Entry<Integer,Integer>> iterator = entries.iterator();
System.out.println(keys);
System.out.println(values);
System.out.println(entries); System.out.println("按keyset遍历");
for (Integer key : keys){
System.out.println("key:" + key + " value:" + map.get(key));
} System.out.println("按键值对遍历");
for (Map.Entry<Integer,Integer> entry : entries){
System.out.println("entry:" + entry);
} System.out.println("按iterator遍历");
while (iterator.hasNext()){
Map.Entry<Integer,Integer> entry = iterator.next();
System.out.println("entry:" + entry);
} map.put(2,444);
map.put(4,44);
System.out.println("修改后的视图");
System.out.println(keys);
System.out.println(values);
System.out.println(entries); keys.add(5);
values.add(55);
}
}
输出如下:
[1, 2, 3]
[11, 22, 33]
[1=11, 2=22, 3=33]
按keyset遍历
key:1 value:11
key:2 value:22
key:3 value:33
按键值对遍历
entry:1=11
entry:2=22
entry:3=33
按iterator遍历
entry:1=11
entry:2=22
entry:3=33
修改后的视图
[1, 2, 3, 4]
[11, 444, 33, 44]
[1=11, 2=444, 3=33, 4=44]
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractCollection.add(AbstractCollection.java:262)
at com.frank.chapter19.Test.main(Test.java:44)
栗子里介绍了三种遍历方式,也看到了三种视图的样子,当我们试图修改视图时,抛出了一个UnsupportedOperationException异常,表明该视图集合无法修改。
在Map.Entry接口里,还可以看到外部比较器和内部比较器,这两个概念暂时也不做介绍,在之后的文章里会介绍。
关于Map,要说的主要就这么多了,目前来说只需要知道Map是以键值对的形式进行存取,并了解Map接口中的主要方法及其作用,了解Map的遍历方法,和视图的概念就已经足够了。
本篇到此结束,欢迎大家继续关注。
【Java入门提高篇】Day19 Java容器类详解(二)Map接口的更多相关文章
- 【Java入门提高篇】Java集合类详解(一)
今天来看看Java里的一个大家伙,那就是集合. 集合嘛,就跟它的名字那样,是一群人多势众的家伙,如果你学过高数,没错,就跟里面说的集合是一个概念,就是一堆对象的集合体.集合就是用来存放和管理其他类对象 ...
- 【Java入门提高篇】Day34 Java容器类详解(十五)WeakHashMap详解
源码详解系列均基于JDK8进行解析 说明 在Java容器详解系列文章的最后,介绍一个相对特殊的成员:WeakHashMap,从名字可以看出它是一个 Map.它的使用上跟HashMap并没有什么区别,所 ...
- 【Java入门提高篇】Day28 Java容器类详解(十)LinkedHashMap详解
今天来介绍一下容器类中的另一个哈希表———>LinkedHashMap.这是HashMap的关门弟子,直接继承了HashMap的衣钵,所以拥有HashMap的全部特性,并青出于蓝而胜于蓝,有着一 ...
- 【Java入门提高篇】Day26 Java容器类详解(八)HashSet源码分析
前面花了好几篇的篇幅把HashMap里里外外说了个遍,大家可能对于源码分析篇已经讳莫如深了.别慌别慌,这一篇来说说集合框架里最偷懒的一个家伙——HashSet,为什么说它是最偷懒的呢,先留个悬念,看完 ...
- 【Java入门提高篇】Day21 Java容器类详解(四)ArrayList源码分析
今天要介绍的是List接口中最常用的实现类——ArrayList,本篇的源码分析基于JDK8,如果有不一致的地方,可先切换到JDK8后再进行操作. 本篇的内容主要包括这几块: 1.源码结构介绍 2.源 ...
- 【Java入门提高篇】Day20 Java容器类详解(三)List接口
今天要说的是Collection族长下的三名大将之一,List,Set,Queue中的List,它们都继承自Collection接口,所以Collection接口的所有操作,它们自然也是有的. Lis ...
- 【Java入门提高篇】Day31 Java容器类详解(十三)TreeSet详解
上一篇很水的介绍完了TreeMap,这一篇来看看更水的TreeSet. 本文将从以下几个角度进行展开: 1.TreeSet简介和使用栗子 2.TreeSet源码分析 本篇大约需食用10分钟,各位看官请 ...
- 【Java入门提高篇】Day27 Java容器类详解(九)LinkedList详解
这次介绍一下List接口的另一个践行者——LinkedList,这是一位集诸多技能于一身的List接口践行者,可谓十八般武艺,样样精通,栈.队列.双端队列.链表.双向链表都可以用它来模拟,话不多说,赶 ...
- 【Java入门提高篇】Day30 Java容器类详解(十二)TreeMap详解
今天来看看Map家族的另一名大将——TreeMap.前面已经介绍过Map家族的两名大将,分别是HashMap,LinkedHashMap.HashMap可以高效查找和存储元素,LinkedHashMa ...
随机推荐
- shell 终端terminfo命令 tput
tput命令 tput 可以更改终端功能,如移动或更改光标,更改文本属性,清除终端屏幕的特定区域等. 光标属性 在shell脚本或命令行中,可以利用tput命令改变光标属性. tput clear # ...
- ES代码总结2
本文部分转载于: http://www.cnblogs.com/luxiaoxun/p/4869509.html ElasticSearch的基本用法与集群搭建 一.简介 ElasticSearch ...
- 修改linux的ssh默认端口号22的方法
一.修改配置文件 vi /etc/ssh/sshd_config 找到#Port 22 修改为自己要使用的端口号:Port 26000 然后 :x 退出保存 二.重启ssh服务 /etc/init. ...
- jquery的DataTable按列排序
不管你用SQL查询数据时,是如何排序的,当数据传递给DataTable时,它会按照它自己的规则再进行一次排序,这个规则就是"order" 可以使用以下代码来进行排序 $('#exa ...
- Java NIO系列教程(九) ServerSocketChannel
Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样.ServerSocketChannel类在 jav ...
- Java 8 新特性-菜鸟教程 (2) -Java 8 方法引用
Java 8 方法引用 方法引用通过方法的名字来指向一个方法. 方法引用可以使语言的构造更紧凑简洁,减少冗余代码. 方法引用使用一对冒号 :: . 下面,我们在 Car 类中定义了 4 个方法作为例子 ...
- Android系统版本、Platform版本、SDK版本、gradle修改
虽然之前分析了gradle,但是在eclipse导入Android studio的时候,各个版本出现的问题还是很模糊,下面对各种版本进行一下说明: 参考资料: https://developer.an ...
- WCF发布多个服务
using System; using System.Collections.Generic; using System.Linq; using System.Text; using WcfServi ...
- windows下使用python操作redis(Visual Studio Code)
1.编辑工具: Visual Studio Code(windows环境) 2.redis服务器:这里用了远程连接,需要配置redis.conf. (1)注释 #bind 127.0.0.1 (2)设 ...
- Oracle左连接、右连接、全外连接以及(+)号用法
1.准备工作 Oracle 外连接(OUTER JOIN)包括以下: 左外连接(左边的表不加限制) 右外连接(右边的表不加限制) 全外连接(左右两表都不加限制) 对应SQL:LEFT/RIGHT/F ...