你好!今天我们将回答有关地图的最常见问题,但首先,让我们记住它是什么。 映射是一种包含一组键值对的数据结构。它的数据结构类似于字典,这就是它通常被称为的原因。同时Map是一个接口,在标准jdk中包含了主要的实现:Hashmap、LinkedHashMap、Hashtable、TreeMap。最常用的实现是 Hashmap,因此我们将在示例中使用它。这是地图的标准创建和填充的样子:
Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
这是通过键获取值的方法:
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
如果以上所有内容都清楚了,那么让我们继续回答常见问题!
0.如何迭代所有Map值
迭代值是您使用映射执行的最常见操作。所有键值对都存储在内部 Map.Entry 接口中,要获取它们,您需要调用entrySet()
. 它返回一组可以循环的对:
for(Map.Entry<Integer, String> entry: map.entrySet()) {
// get key
Integer key = entry.getKey();
// get value
String value = entry.getValue();
}
Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry<Integer, String> entry = itr.next();
// get key
Integer key = entry.getKey();
// get value
String value = entry.getValue();
}
1. 如何将Map转换为List
Map 接口有 3 个返回元素列表的方法:- keySet() - 返回一组键;
- value() - 返回值的集合;
- EntrySet() - 返回一组键值集。
ArrayList
,您会注意到有一个带有 Collection 类型参数的构造函数。由于 Set 是 Collection 的后代,因此上述所有方法的结果都可以传递给该类的构造函数ArrayList
。因此,我们将创建新列表并用以下值填充它们Map
:
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());
2.如何对map key进行排序
对映射进行排序也是编程中相当常见的操作。您可以通过多种方式执行此操作:-
将 Map.Entry 放入列表中并使用 Comparator对其进行排序。
在比较器中,我们将仅比较成对的键:
List
> list = new ArrayList(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() { @Override public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) { return o1.getKey() - o2.getKey(); } }); 如果您了解 lambda,则可以显着缩短此条目:
Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
-
使用
SortedMap
,或更准确地说,它的实现TreeMap
,它在其构造函数中采用 Comparator。该比较器将应用于映射键,因此键必须是实现该接口的类Comparable
:SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } });
当然,一切都可以使用 lambda 重写:
SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));
与第一种方法不同,使用 SortedMap,我们始终以排序的形式存储数据。
3. 如何对地图值进行排序
在这里,您应该使用类似于第一个键的方法 - 获取值列表并在列表中对它们进行排序:List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
@Override
public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
其 lambda 看起来像这样:
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));
4.HashMap、TreeMap、Hashtable有什么区别
如前所述,Map 接口有 3 个主要实现。他们每个人都有自己的特点:-
元素的顺序。
HashMap
并且Hashtable
不保证项目将按照添加顺序存储。此外,它们不保证元素的顺序不会随着时间的推移而改变。反过来,TreeMap
它保证按照元素添加的顺序或按照给定的比较器存储元素。 -
有效值。
HashMap
允许你有一个键和一个空值,HashTable
不。如果比较器允许,TreeMap 只能使用 null 值。如果不使用比较器(通过按添加顺序存储对),则不允许使用 null。 -
同步。仅
HashTable
同步,其余不同步。如果map不会被不同的线程访问,建议使用HashMap而不是HashTable。
哈希映射 | 哈希表 | 树形图 | |
---|---|---|---|
元素顺序 | 不 | 不 | 是的 |
null 作为值 | 是的 | 不 | 并不真地 |
线程安全 | 不 | 是的 | 不 |
搜索元素的算法复杂度 | 复杂度(1) | 复杂度(1) | O(logn) |
底层数据结构 | 哈希表 | 哈希表 | 红黑树 |
5. 如何创建双向地图
有时有必要使用键和值都是唯一的数据结构,即映射将包含键-键对。此数据结构允许您在地图上创建“反向视图/搜索”。也就是说,我们可以通过值找到一个键,这种数据结构称为双向映射,不幸的是,JDK不支持这种结构。但幸运的是,它的实现可以在 Apache Common Collections 或 Guava 库中找到。在那里它分别被称为 BidiMap 和 BiMap。这些实现对键和值的唯一性施加了限制。这创建了一对一的关系。6. 如何创建空地图
创建空地图有两种方法:-
普通对象初始化:
Map<Integer, String> emptyMap = new HashMap<>();
-
创建一个不可变的空映射:
Map<Integer, String> emptyMap = Collections.emptyMap();
UnsupportedOperationException
异常。在本文中,我们研究了您在使用地图界面时可能遇到的最常见问题。
还有什么要读的: |
---|
GO TO FULL VERSION