一 Map 其实本质是键值对(key-value)
在Java中,Map是一个接口.其具体的实现类有
HashMap、Hashtable、Properties、LinkedHashMap、IdentityHashMap、TreeMap、WeakHashMap、ConcurrentHashMap
还有一个用于帮助我们实现自己的Map类的抽象类AbstractMap,还有其他不常见的.
二 常用实现类的区别
- HashMap 根据键的HashCode 值存储数据,根据键可以直接获取它的值,访问速度很快.最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非同步的。
- TreeMap 根据键的某种排序存储,默认是升序,也可以指定其他比较器.不允许key的值为null,非同步.
- Hashtable 与HashMap不同的是key 和 value 都不能为Null, 是同步的.
- LinkedHashMap 与HashMap相比,保留了插入的顺序.用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。
Hashtable是即将废弃的类,以后如果需要线程安全推荐使用ConcurrentHashMap
三 常用的API
方法 | 作用 |
---|---|
clear() | 清空Map |
remove(Object key) | 从 Map 中删除键和关联的值 |
put(Object key, Object value) | 将key与value相关联,如果没有key就添加 |
putAll(Map t) | 将t 中的所有映射复制到此 map |
entrySet() | 返回 Map 中所包含映射的 Set 视图。Set 中的每个元素都是一个 Map.Entry 对象,可以使用 getKey() 和 getValue() 方法(还有一个 setValue() 方法)访问后者的键元素和值元素 |
keySet() | 返回 Map 中所包含键的 Set 视图。删除 Set 中的元素还将删除 Map 中相应的映射(键和值) |
values() | 返回 map 中所包含值的 Collection 视图。删除 Collection 中的元素还将删除 Map 中相应的映射(键和值) |
get(Object key) | 返回与指定键关联的值 |
containsKey(Object key) | 是否包含key |
containsValue(Object value) | 是否包含value |
isEmpty() | 是否为空 |
size() | 键值对数 |
四 遍历Map的四种方式,以HashMap为例
以下四种方式速度递增,所以推荐第四种方式.
- 增强for循环 + keySet()
- 增强for循环 + entrySet()
- 迭代器 + keySet()
- 迭代器 + entrySet()
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
map.put(4, "d");
map.put(5, "e");
map.put(5, "d");
System.out.println("map = " + map);
System.out.println(" ----------------------- ");
//第一种方式,使用增强for循环 + keySet()
for (Integer key: map.keySet()) {
System.out.println(key + ":" + map.get(key));
}
System.out.println(" ----------------------- ");
//第二种方式,使用增强for循环 + entrySet()
for (Map.Entry<Integer, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
System.out.println(" ----------------------- ");
//使用第三种方式,使用迭代器 + keySet()
Iterator<Integer> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
Integer key = iterator.next();
System.out.println(key + ":" + map.get(key));
}
System.out.println(" ----------------------- ");
//使用第四种方式,使用迭代器 + entrySet()
Iterator<Map.Entry<Integer, String>> iterator1 = map.entrySet().iterator();
while (iterator1.hasNext()) {
Map.Entry<Integer, String> entry = iterator1.next();
System.out.println(entry.getKey() + ":" + entry.getValue() );
}
System.out.println(" ----------------------- ");
}
}
五 给Map排序,并设计自己的比较器
对于HashMap LinkedHashMap Hashtable
import java.util.*;
public class Test {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("a", "c");
map.put("d", "b");
map.put("c", "a");
map.put("b", "d");
// 通过ArrayList构造函数把map.entrySet()转换成list
List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(map.entrySet());
//通过比较器实现排序,这里比较方法还是String的compareTo方法
Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
@Override
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
//打印看看
for (Map.Entry<String, String> mapping : list) {
System.out.println(mapping.getKey() + ":" + mapping.getValue());
}
}
}
a:c
b:d
c:a
d:b
对于TreeMap,由于它本身就已经是排好序的,默认是升序,可以直接修改它的比较器函数来实现自己想要的排序
import java.util.*;
public class Test {
public static void main(String[] args) {
//定义一个降序的比较器
Map<String, String> map = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
map.put("a", "c");
map.put("d", "b");
map.put("c", "a");
map.put("b", "d");
for (String key : map.keySet()) {
System.out.println(key + ":" + map.get(key));
}
}
}
d:b
c:a
b:d
a:c
如果想根据Map中的value来排序,由于TreeMap没有定义与value比较的相关的构造方法,所以可以统一按照以下方法:
import java.util.*;
public class Test {
public static void main(String[] args) {
Map<String, String> map = new TreeMap<>();
map.put("a", "c");
map.put("d", "b");
map.put("c", "a");
map.put("b", "d");
// 通过ArrayList构造函数把map.entrySet()转换成list
List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(map.entrySet());
//通过比较器实现排序,按照value的降序排序.
Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
@Override
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
//打印看看
for (Map.Entry<String, String> mapping : list) {
System.out.println(mapping.getKey() + ":" + mapping.getValue());
}
}
}