Map 基本特性:
Map 接口框架图如下:
其中最常见的实现类就是 HashMap,介绍一波。
HashMap 基于哈希表实现,不保证存储顺序,具体使用看代码:
public static void main(String[] args) {
//通过 HashMap 创建 map 对象
Map map = new HashMap<>();
//向 Map 添加键值对
map.put("a", "rat");
map.put("b", "cat");
map.put("b", "dog");
map.put("c", "rat");
map.put(null, null);
map.put(null, null);
//map 打印
System.out.println("map: " + map);
System.out.println("map 中是否有键 a: " + map.containsKey("a"));
System.out.println("map 中是否有值 null: " + map.containsValue(null));
System.out.println("map 中 a 的值为:" + map.get("a"));
map.remove(null);
System.out.println("删除 null 后的map:" + map);
}
打印结果:
map: {null=null, a=rat, b=dog, c=rat}
map 中是否有键 a: true
map 中是否有值 null: true
map 中 a 的值为:rat
删除 null 后的map:{a=rat, b=dog, c=rat}
TreeMap 是基于红黑树实现,用来保存一个有序的键值对 (key-value) 集合,有两种排序方式,默认是自然排序,还可以定制排序。先看自然排序:
public static void main(String[] args) {
//通过 TreeMap 创建 map 对象
Map map = new TreeMap<>();
//向 Map 添加键值对
map.put("rat", "bob");
map.put("cat", "sam");
map.put("dog", "tim");
System.out.println(map);
}
打印结果:
{cat=sam, dog=tim, rat=bob}
可以看出结果是有序的,并且按照自然排序规则。如果不希望是自然排序,那么就可以定制排序:
public static void main(String[] args) {
//通过 TreeMap 创建 map 对象
Map map = new TreeMap<>(new Comparator() {
@Override
public int compare(String o1, String o2) {
//倒序
return o2.compareTo(o1);
}
});
//向 Map 添加键值对
map.put("rat", "bob");
map.put("cat", "sam");
map.put("dog", "tim");
System.out.println(map);
}
打印结果:
{rat=bob, dog=tim, cat=sam}
以匿名内部类的方式在有参构造器 TreeMap(Comparator comparator) 中传入 Comparator 参数,重写其中的 compare() 方法,按照倒序返回,结果如期而至,Map 的 key 都是倒序输出。
Map 是以键值对的方式来存储,那么只要获取所有的键 (key) 的集合,然后通过遍历键的集合去获取所有的值 (value),就完成了对 Map 的遍历,代码如下:
public static void main(String[] args) {
//通过 HashMap 创建 map 对象
Map map = new HashMap<>();
//向 Map 添加键值对
map.put("a", "rat");
map.put("b", "cat");
map.put("b", "dog");
map.put("c", "rat");
map.put(null, null);
map.put(null, null);
//通过 keySet 方法返回所有键组成的 set
Set keys = map.keySet();
//遍历 map
for (String key : keys) {
System.out.println("key:" + key + ",value:" + map.get(key));
}
}
打印如下:
key:null,value:null
key:a,value:rat
key:b,value:dog
key:c,value:rat
通过 Map 的 keySet() 方法获取所有键的 Set,然后通过 foreach 语句来遍历整个 Map。keySet() 方法只能获取键的 Set,Map 还有一个 entrySet() 方法,可以获取所有的键值对,然后直接遍历,这下就省事了:
public static void main(String[] args) {
//通过 HashMap 创建 map 对象
Map map = new HashMap<>();
//向 Map 添加键值对
map.put("a", "rat");
map.put("b", "cat");
map.put("b", "dog");
map.put("c", "rat");
map.put(null, null);
map.put(null, null);
//获取 map 的所有键值对
Set> entries = map.entrySet();
//遍历 map
for (Map.Entry entry : entries) {
System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue());
}
}
打印结果就不贴出来了,如上。上述代码使用的是 foreach 语法,使用迭代器也是可以的,创建迭代器的代价较小,因此这是个比较常用的方式,迭代器后面会做详细介绍,这里简单展示迭代器在 Map 遍历中的使用:
public static void main(String[] args) {
//通过 HashMap 创建 map 对象
Map map = new HashMap<>();
//向 Map 添加键值对
map.put("a", "rat");
map.put("b", "cat");
map.put("b", "dog");
map.put("c", "rat");
map.put(null, null);
map.put(null, null);
//获取 map 的所有键值并生成迭代器对象
Iterator> iterator = map.entrySet().iterator();
//map 遍历
while (iterator.hasNext()) {
Map.Entry next = iterator.next();
System.out.println("key:" + next.getKey() + ",value:" + next.getValue());
}
}
本文介绍了 Map 的两个实现类 HashMap 和 TreeMap,两者都是非线程安全的类。HashMap 适用于 Map 中插入、删除和定位元素,速度较快,建议多使用,如果需要排序的时候再使用 TreeMap。 文章还介绍三种 Map 的遍历方式,其中迭代器的方式比较常用,后面的章节会对迭代器做更详细的介绍。