与 Collection
单列集合存储元素采用一个个存储的方式不同,Map
集合是以键值对 key-value
的方式存储元素,通过 key
就能找到 value
,因此被叫做双列集合
Map
中的集合不能包含重复的键,值可以重复;每个键只能对应一个值
1. Map 常用子类及常用方法
Map
有很多子类,这里主要介绍两种常见的子类:
HashMap<k, v>
:存储结构采用哈希表结构,元素存储顺序不能保证一致,由于要保证键的唯一,需要重写键的hashCode、equals
方法LinkedHashMap<K, V>
:HashMap
下有个子类LinkedHashMap
,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()
方法、equals()
方法
常用方法
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集合)
import java.util.HashMap;
public class MapDemo1 {
public static void main(String[] args) {
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("name", "rose");
hashMap.put("gender", "female");
System.out.println(hashMap); // {gender=female, name=rose}
System.out.println(hashMap.get("name")); // rose
System.out.println(hashMap.containsKey("gender")); // tue
// 对于不存在的键,返回 null
System.out.println(hashMap.put("age", "18")); // null
// 对于存在的键,返回 value
System.out.println(hashMap.put("name", "lila")); // rose
hashMap.remove("gender");
System.out.println(hashMap); // {name=lila, age=18}
// 获取所有的键(组成一个 Set)
for (String key: hashMap.keySet()) {
System.out.println(key); // name、age
}
}
}
2. Map 集合遍历键值对
KeySet
通过 KeySet()
方法获取所有 key
组成的 Set
集合,遍历 Set
再通过 get()
方法即可获取到 value
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo2 {
public static void main(String[] args) {
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("name", "rose");
hashMap.put("gender", "female");
Set<String> keys = hashMap.keySet();
for (String key : keys) {
System.out.println("key: " + key + " value: " + hashMap.get(key));
}
}
}
输出结果:
key: gender value: female
key: name value: rose
Entry 对象
Entry
将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map
集合时,就可以从每一个键值对(Entry
)对象中获取对应的键与对应的值,
public K getKey()
:获取Entry
对象中的键public V getValue()
:获取Entry
对象中的值
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class HashMapDemo2 {
public static void main(String[] args) {
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("name", "rose");
hashMap.put("gender", "female");
Set<Entry<String, String>> entrySet = hashMap.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
}
}
3. HashMap 存储自定义类型键值
HashMap
中存放自定义对象时,如果自定义对象作为 key
存在,这时要保证对象唯一,必须复写对象的hashCode
和equals
方法
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class HashMapDemo3 {
public static void main(String[] args) {
Map<Student, String> studentHashMap = new HashMap<Student, String>();
studentHashMap.put(new Student("rose", 18), "北京");
studentHashMap.put(new Student("lila", 19), "深圳");
studentHashMap.put(new Student("john", 18), "重庆");
Set<Student> keySet = studentHashMap.keySet();
for (Student key : keySet) {
String value = studentHashMap.get(key);
System.out.println(key.toString() + "......" + value);
}
}
}
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student student = (Student) o;
return student.age == age && Objects.equals(student.name, name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
4. LinkedHashMap
HashMap
保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,若要保证有序还要速度很快,可以使用 HashMap
的子类 LinkedHashMap
,它是链表和哈希表组合的一个数据存储结构
package top.midworld.basic.map_stu;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.Set;
public class LinkedHashMapDemo {
public static void main(String[] args) {
LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<String, String>();
linkedHashMap.put("rose", "北京");
linkedHashMap.put("lila", "深圳");
linkedHashMap.put("john", "重庆");
Set<Entry<String, String>> entrySet = linkedHashMap.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println("key: " + entry.getKey() + " value: " + entry.getValue());
}
/*
key: rose value: 北京
key: lila value: 深圳
key: john value: 重庆
*/
}
}
5. 示例
计算字符串每个字符出现的次数
import java.util.HashMap;
// 查找字符串中字符出现的次数
public class MapFindStr {
public static void main(String[] args) {
String title = "Hello";
findStr(title);
}
public static void findStr(String title) {
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
for (int i = 0; i < title.length(); i++) {
char key = title.charAt(i);
if (!hashMap.containsKey(key)) {
hashMap.put(key, 1);
} else {
Integer cnt = hashMap.get(key);
hashMap.put(key, ++cnt);
}
}
System.out.println(hashMap); // {e=1, H=1, l=2, o=1}
}
}