目录
一.Map集合概述
现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象,即java.util.Ma接口。
我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同,如下图。
- Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。
- Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
- Collection中的集合称为单列集合,Map中的集合称为双列集合。
- 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
- 需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
二.Map集合中常用的方法
- V put(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)
- V get(Object key) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
- int size() 返回此映射中的键-值映射关系数。
- void clear() 从此映射中移除所有映射关系(可选操作)
- boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true
- boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true
- Collection<V> values() 返回此映射中包含的值的 Collection 视图
- V remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)
- Set<K> keySet() 返回此映射中包含的键的 Set 视图
- Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 视图
三.Map集合遍历--键找值
- Map集合遍历:不能直接使用迭代器,不能直接使用增强for
- 遍历的思想:键找值
- Map集合中提供方法: Set<K> keySet() Map集合中的所有的键,存储到Set集合
- Set集合中存储的都是Map中的键
- 实现步骤
- Map集合方法keySet(),获取到存储所有键的Set集合
- 遍历Set集合,取出集合中所有的键
- 使用Map集合方法get()获取值
public class Demo03 {
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<String,Integer>();
map.put("a",1);
map.put("b",2);
map.put("c",3);
//1: Map集合方法keySet(),获取到存储所有键的Set集合
Set<String> set = map.keySet();
//2.遍历Set集合,取出了集合中的所有的键
Iterator<String> it = set.iterator();
while(it.hasNext()){
String key = it.next();//获取键
//Map集合方法get()获取值
Integer value = map.get(key);
System.out.println(key+" "+value);
}
}
}
四.Map集合遍历--键值对
- Map中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在Map中是一一对应关系,这一对对象又称做Map中的一个Entry(项)
- Map集合中定义方法:entrySet() 意义,将集合中的所有键值对的对应关系,存储到Set集合中,方法返回值 Set< Entry<K,V> >
- 实现步骤:
- Map集合的方法 entrySet(),获得每个键值对的对应关系对象 Entry, 存储在Set集合中
- 遍历Set集合,取出的是 键值对的对应关系对象
- 对应关系对象,获取键和值, Entry接口方法 getKey() getValue()
public class Demo03 {
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<String,Integer>();
map.put("a",1);
map.put("b",2);
map.put("c",3);
//1.Map集合的方法 entrySet()
Set<Map.Entry<String, Integer>> set = map.entrySet();
//2.遍历Set集合
Iterator<Map.Entry<String, Integer>> it = set.iterator();
while(it.hasNext()){
//3.对应关系对象,获取键和值
//set集合中,存储的元素是Entry对象, it.next()取出的也是Entry对象
Map.Entry<String, Integer> entry = it.next();
//Entry对象的方法 getKey() getValue()
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+" "+value);
}
}
}
五.简化遍历
public class Demo03 {
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<String,Integer>();
map.put("a",1);
map.put("b",2);
map.put("c",3);
//for间接遍历Map
//Set<String> set = map.keySet();
for(String key : map.keySet()){
// Integer value = map.get(key);
System.out.println(key+" "+map.get(key));
}
System.out.println("=====================");
//for间接遍历Map
// Set<Map.Entry<String,Integer>> set = map.entrySet();
for(Map.Entry<String,Integer> entry : map.entrySet()){
System.out.println(entry.getKey()+" "+entry.getValue());
}
}
}
六.HashMap集合
- Map接口实现类HashMap类特点:
- 底层哈希表结构。
- 不允许重复键。用作键的对象,应该重写hashCode()方法和equals()方法。
- 此集合可以使用null值和null键。
- 线程不安全,运行速度快
练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。注意,学生姓名相同并且年龄相同视为同一名学生。
七.LinkedHashMap介绍
我们知道HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,还要速度快怎么办呢?在HashMap下面有一个子类LinkedHashMap,底层是哈希表双向链表,保证迭代的顺序。
public static void main(String[] args) {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("邓超", "孙俪");
map.put("李晨", "范冰冰");
map.put("刘德华", "朱丽倩");
Set<Entry<String, String>> entrySet = map.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
八.Properties集合
Map接口实现类Hashtable的子类Properties类。Properties也是Map接口实现类,是存储键值对的双列集合,由于此类能和IO流结合使用,数据可以持久化,使用量很大。(IO部分后面课程详解)
- Properties集合特点:
- 继承Hashtable,底层数据结构是哈希表
- 线程安全,运行速度慢
- 不允许null值,null键
- 此集合存储键值对数据类型固定为String
- 可以和IO流结合使用,从流中加载数据
- Properties集合特有方法:
- Object setPropery(String key,String value),向集合中存储键值对
- String getProperty(String key),获取集合中键对应的值,无此键返回null
- Set<String> stringPropertyNames(),集合中的所有键存储到Set集合
- void load(输入流对象) ,IO部分讲解
public class Demo03 {
public static void main(String[] args) {
Properties pro=new Properties();
pro.setProperty("张三","23");
pro.setProperty("李四","24");
pro.setProperty("王五","25");
//键,存储到Set集合
Set<String> set = pro.stringPropertyNames();
for (String key : set) {
System.out.println(key+" "+pro.getProperty(key));
}
}
}
九.练习
计算一个字符串中每个字符出现次数。
* 1. 获取一个字符串对象
* 2. 创建一个Map集合,键代表字符,值代表次数。
* 3. 遍历字符串得到每个字符。
* 4. 判断Map中是否有该键。
* 5. 如果没有,第一次出现,存储次数为1;如果有,则说明已经出现过,获取到对应的值进行++,再次存储。
* 6. 打印最终结果
public class Demo03 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = sc.next();
//创建一个集合 存储字符以及字符出现的次数
HashMap<Character,Integer> map=new HashMap<Character, Integer>();
//遍历字符串
for (int i = 0; i <str.length() ; i++) {
//获取每一个字符
char c = str.charAt(i);
//判断该字符是否在键集中
if(!map.containsKey(c)){ //说明这个字符在集合中没有出现过
map.put(c,1);
}else{
//说明这个字符在键集中存在
Integer count = map.get(c);
count++;
map.put(c,count);
}
}
System.out.println(map);
}
}