Map:成对的“键值对”对象,即一个key以及与此键对应的一条信息作为value
例子:
Map<Integer,List<String>>,
如果我们存的每个同学的信息想更完整些比如同学A的语文95、数学98、英语100,那么我们可以这么声明Map<String,Map<String,Integer>>
案例:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String args[]) {
// 首先声明一个Map,录入每个同学的一门课成绩
Map<String, Integer> oneGrade = new HashMap<String, Integer>();
oneGrade.put("小明", 98);
oneGrade.put("小红", 95);
System.out.println("Map<string,Integer>: ");
System.out.println(oneGrade);
// 其次我们想给每个同学录入更多的成绩
Map<String, List<Integer>> manyGrades = new HashMap<String, List<Integer>>();
// 录入小明的几科成绩
List<Integer> tmp = new ArrayList<Integer>();
tmp.add(98);
tmp.add(96);
tmp.add(93);
manyGrades.put("小明", tmp);
// 录入小红的几科成绩
tmp.clear();
tmp.add(95);
tmp.add(99);
tmp.add(100);
manyGrades.put("小红", tmp);
System.out.println("Map<String,List<Integer>>: ");
System.out.println(manyGrades);
// 再次我们想保留每个同学究竟哪门课的了多少分的具体信息
Map<String, Map<String, Integer>> detailGrades = new HashMap<String, Map<String, Integer>>();
//录入小明的具体每门课程的成绩
Map<String,Integer> tmp1 = new HashMap<String, Integer>();
tmp1.put("语文", 98);
tmp1.put("数学", 96);
tmp1.put("英语", 93);
detailGrades.put("小明", tmp1);
//录入小红的具体每门课的成绩
tmp1.clear();
tmp1.put("语文", 95);
tmp1.put("数学", 99);
tmp1.put("英语", 100);
detailGrades.put("小红", tmp1);
System.out.println("Map<String,Map<String,Integer>>: ");
System.out.println(detailGrades);
}
}/* Output:
Map<string,Integer>:
{小明=98, 小红=95}
Map<String,List<Integer>>:
{小明=[95, 99, 100], 小红=[95, 99, 100]}
Map<String,Map<String,Integer>>:
{小明={语文=95, 英语=100, 数学=99}, 小红={语文=95, 英语=100, 数学=99}}
*///:~
Map接口
Map接口的具体实现有三个HashMap,TreeMap和LinkedHashMap(Map接口还有WeakHashMap、ConcurrentHashMap、IdentityHashMap等实现,在多线程编程中会用到ConrrentHashMap,另外两个转为特殊问题设计不常用就暂不总结了):
HashMap:Map基于散列表的实现(它取代了Hashtable)。插入和查询键值对的开销是固定的。可以通过构造器设置容量和负载因子,以调整容器的性能。
LinkedHashMap:类似于HashMap,但是迭代遍历它时,取得“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点;而在迭代访问时反而更快,因为它使用链表维护内部次序。
TreeMap:基于红黑树的实现。查看“键”或“键值树”时,它们会被排序(次序由Comparable或Comparator决定)。TreeMap的特点在于,所得到的结果是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树。
ConcurrentHashMap:一种线程安全的Map,它不涉及同步加锁。
// Map方法总结:--------------------------------------------------
Map<Integer, String> map= new HashMap<Integer, String>();
Map<Integer, String> testData = new HashMap<Integer, String>();
// 添加元素
testData.put(3, "A0"); testData.put(2, "B1");
map.putAll(testData); 添加testData到map
// 删除
map.remove(2); 删除key为2的该对key和value
map.clear(); 清空
// 是否为空
map.isEmpty()
// 已容纳多少
map.size()
// 是否包含某个key
map.containsKey(3) 是否包含值为3的key
// 是否包含某个value
map.containsValue("F0") 是否包含字符串"F0"
// 根据key求value
map.get(3) 求key为3的value值
// 返回map存储的多个key的Set集合
map.keySet()
// 返回多个value的值
map.values()
如果Map中的key是自己写的类,一定要注意key类里面多了好几个方法用于比较
Map中如果想按照顺序存储,得用TreeMap,而TreeMap得实现Comparable接口
import java.util.Map;
import java.util.TreeMap;
class MyClass implements Comparable<MyClass> {
private static int counter = 0;
public int id;
public MyClass() {
id = ++counter;
}
@Override
public String toString() {
return "自定义类" + id;
}
@Override
public boolean equals(Object obj) {
return obj instanceof MyClass && id == ((MyClass) obj).id;
}
@Override
public int hashCode() {
return id;
}
@Override
public int compareTo(MyClass o) {
return (this.id == o.id ? 0 : (this.id < o.id ? -1 : 1));
}
}
public class TestMap {
public static void main(String[] args) {
Map<MyClass, String> testTreeMap = new TreeMap<MyClass, String>();
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass();
MyClass mc3 = new MyClass();
testTreeMap.put(mc1, "NO.1");
testTreeMap.put(mc3, "NO.3");
testTreeMap.put(mc2, "NO.2");
System.out.println(testTreeMap);
}
}/*
{自定义类1=NO.1, 自定义类2=NO.2, 自定义类3=NO.3}
*///:~