Map双列集合
1、概念
Java.util.Map<k,v>集合
双列集合,顶层父类接口
是一个键值对的集合
2、特点
1、Map集合是一个双列集合,一元素包含两个值(一个key,一个value)
2、Map集合中的元素,key和value的数据类型可以相同,可以不同
3、Map集合中的元素,key唯一,value允许重复
4、Map集合中的元素,key和value是一一对应关系(映射关系)
5、可以存储null值
6、存储无序
3、Map集合常用方法
//增
V put(K key, V value);将指定的键值对放入Map集合中。返回被替换的值
//获取
V get(Object key); 返回到指定键所映射的值,或 null如果此映射包含该键的映射。
//删
V remove(Object key) ;如果存在(从可选的操作),从该Map中删除一个键的映射。
//判断
boolean containsKey(Object key); 如果此映射包含指定键的映射,则返回 true
//遍历
Set<Map.Entry<K,V>> entrySet(); 返回Map集合中所有的键。
Set<K> keySet(); 返回此Map中包含的所有键的集合
4、Map集合遍历
public static void main (String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("张三",18);
map.put("李四",19);
map.put("王五",20);
//第一种遍历方法:通过键找值
/*
实现步骤
1、使用Map集合中的方法keySet(),把集合中所有的key取出来,存在一个Set集合
2、遍历Set集合,获取Map集合中的每一个key
3、通过Map集合中的方法get(key),通过key找到value
*/
Set<String> keys= map.keySet();
//2.1 使用增强for遍历Set集合
for (String key: keys) {
Integer value = map.get(key);
System.out.println(key+"="+value);
}
System.out.println("-----------------------------------");
//2.2 使用迭代器遍历Set集合
Iterator<String> it = keys.iterator();
while (it.hasNext()){
String key = it.next();
Integer value = map.get(key);
System.out.println(key+"="+value);
}
//第二种遍历方式:使用Entry对象
/*
实现步骤:
1、使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中
2、遍历Set集合,获取每一个Entry对象
3、使用Entry对象中的方法getKey()和getValue()获取键与值
*/
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> entry: entries) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"="+value);
}
}
5、Map集合常用实现子类
HashMap、LinkedHashMap、TreeMap、
5.1 HashMap集合(实现类)
概念
java.util.HashMap<k,v>集合 implements map<k,v>接口
特点
1、底层是:哈希表(查询速度块)
JDK1.8之前,数组+单向链表
JDK1.8之后:数组+单向链表/红黑树(链表长度超过8):提高查询速度
2、存储无序
哈希表原理
为什么是无序的?
因为哈希值生成的是一个整数值,
这个整数值和对象无关,与HashCode本身是有关的,哈希码值会存储到哈希表,随机无序
为什么唯一?
进行比较,第一个会拿到HashCode进行判断,
如果相等。就会用equals方法进行比较。
如果相等,代表是重复的,不存储在哈希表中
如果不相等,则会存储在哈希表中
如果不相等,不存储到哈希表中
HashMap存储自定义类型键-值
在测试类中:
/*
HashMap 存储自定义类型键值
Map集合保证key是唯一的
作为key的元素,必须重写hashCode()方法和equals()方法以保证key唯一
*/
public static void main(String[] args) {
//创建HashMap集合
HashMap<String, Person> map = new HashMap<>();
//添加元素
map.put("北京",new Person("张三",18));
map.put("上海",new Person("李四",19));
map.put("深圳",new Person("王五",20));
map.put("上海",new Person("赵六",18));
//keySet + foreach 遍历Map集合
Set<String> keys = map.keySet();
for (String key: keys ){
Person value = map.get(key);
System.out.println(key+"->"+value);
}
}
在Person类中:
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
5.2 LinkedHashMap集合(实现类)
概念
java.util.LinkedHashMap<k,v>集合 extends HashMap<k,v>集合
特点
1、底层:哈希表+链表(保证迭代顺序)
2、存储有序
5.3 Hashtable集合(实现类)
概念
java.util.Hashtable<k,v> implement Map<k,v>接口
旧的集合(新的集合为HashMap)
特点
1、底层:哈希表
2、线程安全(单线程),速度慢
3、不能存储null值【之前的所有集合(除Tree)都可以存储null值】
二、经典例题
1、例题一
/*
计算一个字符串中的每个字符出现的次数
分析:
1、使用Scanner获取用户输入的字符串
2、创建Map集合,key是字符串中的字符value是字符的个数
3、遍历字符串,获取每一个字符
4、使用获取到的字符,去Map集合判断key是否存在
key存在:
通过字符key,获取value字符个数
vlaue++
put(key,value) 把新的value存储到Map集合中
key不存在
put(key,1)
5、遍历Map集合,输出结果
*/
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String str = scanner.next();
//创建Map集合
HashMap<Character, Integer> map = new HashMap<>();
//遍历字符串,获取每一个字符
for (char c:str.toCharArray()) {
if(map.containsKey(c)){
Integer value = map.get(c);
value++;
map.put(c,value);
}else {
map.put(c,1);
}
}
//遍历Map集合
for (Character key: map.keySet()) {
Integer value = map.get(key);
System.out.println(key+"="+value);
}
}
}