JavaRush /Java 博客 /Random-ZH /有关地图界面的最常见问题的解答

有关地图界面的最常见问题的解答

已在 Random-ZH 群组中发布
你好!今天我们将回答有关地图的最常见问题,但首先,让我们记住它是什么。 有关地图界面最常见问题的解答 - 1映射是一种包含一组键值对的数据结构。它的数据结构类似于字典,这就是它通常被称为的原因。同时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进行排序

对映射进行排序也是编程中相当常见的操作。您可以通过多种方式执行此操作:
  1. 将 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));
  2. 使用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 个主要实现。他们每个人都有自己的特点:
  1. 元素的顺序。 HashMap并且Hashtable不保证项目将按照添加顺序存储。此外,它们不保证元素的顺序不会随着时间的推移而改变。反过来,TreeMap它保证按照元素添加的顺序或按照给定的比较器存储元素。

  2. 有效值。 HashMap允许你有一个键和一个空值,HashTable不。如果比较器允许,TreeMap 只能使用 null 值。如果不使用比较器(通过按添加顺序存储对),则不允许使用 null。

  3. 同步。HashTable同步,其余不同步。如果map不会被不同的线程访问,建议使用HashMap而不是HashTable。

以及实现的一般比较:
哈希映射 哈希表 树形图
元素顺序 是的
null 作为值 是的 并不真地
线程安全 是的
搜索元素的算法复杂度 复杂度(1) 复杂度(1) O(logn)
底层数据结构 哈希表 哈希表 红黑树

5. 如何创建双向地图

有时有必要使用键和值都是唯一的数据结构,即映射将包含键-键对。此数据结构允许您在地图上创建“反向视图/搜索”。也就是说,我们可以通过值找到一个键,这种数据结构称为双向映射,不幸的是,JDK不支持这种结构。但幸运的是,它的实现可以在 Apache Common Collections 或 Guava 库中找到。在那里它分别被称为 BidiMap 和 BiMap。这些实现对键和值的唯一性施加了限制。这创建了一对一的关系。

6. 如何创建空地图

创建空地图有两种方法:
  1. 普通对象初始化:

    Map<Integer, String> emptyMap = new HashMap<>();
  2. 创建一个不可变的空映射:

    Map<Integer, String> emptyMap =  Collections.emptyMap();
当我们尝试向这样的地图添加数据时,我们将收到: UnsupportedOperationException异常。在本文中,我们研究了您在使用地图界面时可能遇到的最常见问题。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION