1.1 概述
java.util.Map
接口:一一对应的关系
我们通过查看Map
接口描述,发现Map
接口下的集合与Collection
接口下的集合,它们存储数据的形式不同,如下图。
Collection
中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。Map
中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。Collection
中的集合称为单列集合,Map
中的集合称为双列集合。- 需要注意的是,
Map
中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
常用方法:
public V put(K key, V value)
: 把指定的键与指定的值添加到Map集合中。public V remove(Object key)
: 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。public V get(Object key)
根据指定的键,在Map集合中获取对应的值。boolean containsKey(Object key)
判断集合中是否包含指定的键。public Set<K> keySet()
: 获取Map集合中所有的键,存储到Set集合中。public Set<Map.Entry<K,V>> entrySet()
: 获取到Map集合中所有的键值对对象的集合(Set集合)。- 既然Entry表示了一对键和值,那么也同样提供了获取对应键和对应值得方法:
public K getKey()
:获取Entry对象中的键。public V getValue()
:获取Entry对象中的值。
- 既然Entry表示了一对键和值,那么也同样提供了获取对应键和对应值得方法:
tips:
使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;
若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。
package com.itheima.demo;
import org.w3c.dom.events.Event;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/** `public V put(K key, V value)`: 把指定的键与指定的值添加到Map集合中。
* `public V remove(Object key)`: 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
* `public V get(Object key)` 根据指定的键,在Map集合中获取对应的值。
* `boolean containsKey(Object key) ` 判断集合中是否包含指定的键。
* `public Set<K> keySet()`: 获取Map集合中所有的键,存储到Set集合中。
* `public Set<Map.Entry<K,V>> entrySet()`: 获取到Map集合中所有的键值对对象的集合(Set集合)。
* * `public K getKey()`:获取Entry对象中的键。
* * `public V getValue()`:获取Entry对象中的值。*/
public class HelloWorld {
public static void main(String[] args) {
HashMap<String, String> stu = new HashMap<>();
stu.put("刘景亮", "18cm");
stu.put("马新航", "17cm");
stu.put("范程", "4cm");
stu.put("朱宇翔", "20cm");
System.out.println(stu);
stu.remove("范程");
System.out.println(stu);
System.out.println(stu.get("朱宇翔"));
System.out.println(stu.containsKey("范程"));
System.out.println(stu.containsKey("马新航"));
Set<String> key = stu.keySet();
for (String i : key) {
System.out.println(i + "有" + stu.get(i));
}
// 获取 所有的 entry对象 entrySet
Set<Map.Entry<String,String>> entrySet = stu.entrySet();
// 遍历得到每一个entry对象
for (Map.Entry<String, String> entry : entrySet) {
// 解析
String keys = entry.getKey();
String value = entry.getValue();
System.out.println(keys+"的身高是:"+value);
}
}
}
结果:
{朱宇翔=20cm, 马新航=17cm, 刘景亮=18cm, 范程=4cm}
{朱宇翔=20cm, 马新航=17cm, 刘景亮=18cm}
20cm
false
true
朱宇翔有20cm
马新航有17cm
刘景亮有18cm
朱宇翔的身高是:20cm
马新航的身高是:17cm
刘景亮的身高是:18cm
练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。
注意,学生姓名相同并且年龄相同视为同一名学生。
package com.itheima.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*练习:每位学生(姓名,年龄)都有自己的家庭住址。那么,既然有对应关系,则将学生对象和家庭住址存储到map集合中。学生作为键, 家庭住址作为值。
> 注意,学生姓名相同并且年龄相同视为同一名学生。
>
*/
class Student{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class HelloWorld {
public static void main(String[] args) {
HashMap<Student, String> stu = new HashMap<>();
stu.put(new Student("刘景亮",18), "18cm");
stu.put(new Student("马新航",18), "17cm");
stu.put(new Student("范程",18), "4cm");
stu.put(new Student("朱宇翔",18), "20cm");
Set<Student> key = stu.keySet();
for (Student i : key) {
System.out.println(i.getName() + "有" + stu.get(i));
}
// 获取 所有的 entry对象 entrySet
Set<Map.Entry<Student,String>> entrySet = stu.entrySet();
// 遍历得到每一个entry对象
for (Map.Entry<Student, String> entry : entrySet) {
// 解析
Student keys = entry.getKey();
String value = entry.getValue();
System.out.println(keys.getName()+"有"+keys.getAge()+"岁了,他的身高是:"+value);
}
}
}
结果:
范程有4cm
马新航有17cm
朱宇翔有20cm
刘景亮有18cm
范程有18岁了,他的身高是:4cm
马新航有18岁了,他的身高是:17cm
朱宇翔有18岁了,他的身高是:20cm
刘景亮有18岁了,他的身高是:18cm
2. LinkedHashMap
HashMap保证成对元素唯一,并且查询速度很快,可是无序
在HashMap下面有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构,即快而且有序。
练习:词法分析器
public class HelloWorld {
public static void main(String[] args) {
System.out.println("请录入一个字符串:");
String line = new Scanner(System.in).nextLine();
LinkedHashMap<Character,Integer> list = new LinkedHashMap<>();
for (int i = 0;i<line.length();i++){
if (!list.containsKey(line.charAt(i))){
list.put(line.charAt(i),1);
}
else {
Integer num = list.get(line.charAt(i));
//list.remove(line.charAt(i));
list.put(line.charAt(i),++num);
}
}
System.out.println(list);
Set<Character> key = list.keySet();
for (Character s:key){
System.out.println(s+"的数量是"+list.get(s)+"个");
}
}
}
结果:
{b=1, e=2, t=2, r=1}
b的数量是1个
e的数量是2个
t的数量是2个
r的数量是1个