JavaRush /Java 博客 /Random-ZH /Java 中的 HashMap - 它是什么样的映射?

Java 中的 HashMap - 它是什么样的映射?

已在 Random-ZH 群组中发布
你好!今天我们要讲的是另一种数据结构——Map。它的官方俄语名称是“关联数组”,但并不经常使用。更常见的选项是“字典”、“地图”或(最常见的)俚语“地图”:) 在 Map 内部,数据以“键”-“值”格式存储,即成对存储。键和值都可以是任何对象——数字、字符串或其他类的对象。

Map 与其他数据结构有何不同

之前,我们研究了元素单独存储的数据结构。在数组或ArrayList / LinkedList中,我们存储一定数量的元素。但是如果我们的任务稍微改变怎么办?例如,假设我们面临创建 100 人列表的任务,其中将存储该人的全名和护照号码。原则上来说,这并不是那么困难。例如,您可以将两者放入一行并创建一个行列表,如下所示: “Anna Ivanovna Reshetnikova,4211 717171。” 但这个解决方案有两个缺点。首先,我们可能需要护照搜索功能。而采用这种存储信息的格式,就会出现问题。其次,没有什么可以阻止我们创建两个具有相同护照号码的不同人。这是我们解决方案最严重的缺点。这种情况应该完全排除;没有两个人的护照号码相同。在这里,Map 及其声明的功能可以为我们提供帮助(以“键”-“值”格式将数据存储在一对中)。让我们看一下最常见的Map实现——Java HashMap类HashMap——这是什么样的映射? - 1

在 Java 中创建 HashMap 并使用该类

这个实现的创建非常简单:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

}
在这里,我们创建了一个字典,其中元素将以“数字字符串”格式存储。数字将是键,字符串将是值。我们还指出了我们将拥有什么类型的键 ( Integer) 以及我们将拥有什么类型的值 ( String)。为什么会这样呢?首先,HashMap 中的键始终是唯一的。这对我们来说非常有用,因为我们可以使用护照号码作为密钥并避免重复。带有全名的行将充当一个值(不同人的全名很容易重复,这对我们来说没有问题)。

将新对添加到 HashMap

这个任务看起来像这样:
public class Main {

   public static void main(String[] args) {
       HashMap<Integer, String> passportsAndNames = new HashMap<>();


       passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
       passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
       passportsAndNames.put(8082771, "Donald John Trump");
       System.out.println(passportsAndNames);

   }

}
该方法就是用于此目的put()。此外,HashMap 有一个重写的方法toString(),因此可以将其打印到控制台。输出将如下所示: {212133=Lidiya Arkadyevna Bublikova,8082771=Donald John Trump,162348=Ivan Mikhailovich Serebryakov}

HashMap键的特点

现在让我们检查一下这些键是否真的是唯一的?让我们尝试添加一个带有映射中 已有键的新元素:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");
   passportsAndNames.put(162348, "Viktor Mikhailovich Stychkin");//repeat key

   System.out.println(passportsAndNames);

}
输出: {212133=Lidiya Arkadyevna Bublikova,8082771=Donald John Trump,162348=Viktor Mikhailovich Stychkin} 如您所见,前一个带有键 162348 的元素已被覆盖。“钥匙”被称为钥匙是有原因的。HashMap 中的值是通过键来访问的(但反之则不然——键不能通过值来获取,因为值可以重复)。这在获取元素以及从 HashMap 中删除元素的示例中可以清楚地看到:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   String lidiaName = passportsAndNames.get(212133);
   System.out.println(lidiaName);


   passportsAndNames.remove(162348);
   System.out.println(passportsAndNames);

}
为了从字典中获取一个值或删除一个值对,我们必须将与该值对应的唯一键准确地传递给get()方法。HashMap 中没有像数组或列表中那样的数字索引- 值是通过键访问的。控制台输出: Lidiya Arkadyevna Bublikova {212133=Lidiya Arkadyevna Bublikova,8082771=唐纳德·约翰·特朗普}remove()

检查键和值是否存在

ArrayListLinkedList类中,我们可以检查列表是否包含特定元素。 HashMap还允许您执行此操作,并且对于该对的两个部分:它具有方法containsKey()(检查键是否存在)和containsValue()(检查值是否存在)。
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");


   System.out.println(passportsAndNames.containsKey(11111));
   System.out.println(passportsAndNames.containsValue("Donald John Trump"));

}
输出: 假真

获取所有键和值的列表

HashMap的另一个方便的特性是你可以分别获取所有键和所有值的列表。为此,使用方法keySet()values()
public class Main {

   public static void main(String[] args) {

       HashMap<Integer, String> passportsAndNames = new HashMap<>();

       passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
       passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
       passportsAndNames.put(8082771, "Donald John Trump");

       Set<Integer> keys = passportsAndNames.keySet();
       System.out.println("Keys: " + keys);

       ArrayList<String> values = new ArrayList<>(passportsAndNames.values());
       System.out.println("Values: " + values);

   }

}
键被提取到集合中Set。它的特点是它不能包含重复元素。现在要记住的主要事情是,可以将所有键的列表从 HashMap 中取出到一个单独的集合中。在示例中,我们将值保存为 normal ArrayList。控制台输出: 键:[212133, 8082771, 162348] 值:[Lidiya Arkadyevna Bublikova, Donald John Trump, Ivan Mikhailovich Serebryakov] 方法size()执行的clear()操作与我们之前的结构完全相同:第一个返回数字元素在当前的字典中,第二个删除所有元素。
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   System.out.println(passportsAndNames.size());
   passportsAndNames.clear();
   System.out.println(passportsAndNames);

}
输出: 3 {} 要检查我们的 HashMap 是否至少有一个元素,我们可以使用以下方法isEmpty()
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   if (!passportsAndNames.isEmpty()) {

       System.out.println(passportsAndNames);

   }

}
输出: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Ivan Mikhailovich Serebryakov} 现在我们只有在初步验证后才会输出到控制台:)

将两张地图合并为一张

另一个有趣的点是两张地图可以合并为一张。有一个方法可以做到这一点putAll()我们在第一个HashMap上调用它,将第二个 HashMap 作为参数传递,第二个 HashMap 中的元素将添加到第一个:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();
   HashMap<Integer, String> passportsAndNames2 = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   passportsAndNames2.put(917352, "Alexey Andreevich Ermakov");
   passportsAndNames2.put(925648, "Maxim Olegovich Arkharov");


   passportsAndNames.putAll(passportsAndNames2);
   System.out.println(passportsAndNames);

}
输出: {917352=Alexey Andreevich Ermakov, 212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 925648=Maxim Olegovich Arkharov, 162348=Ivan Mikhailovich Serebryakov} 护照AndNames2 的所有元素都被复制到护照AndNames。现在让我们看一个更复杂的例子。即,在循环中迭代 HashMap。
for (Map.Entry entry: passportsAndNames.entrySet()) {

   System.out.println(entry);

}
接口Map.Entry只是指字典中的键值对。该方法entrySet()返回 HashMap 中所有对的列表(因为我们的映射仅包含这样的 Entry 对,所以我们迭代对,而不是单独的键或值)。结论: 212133=Lidiya Arkadyevna Bublikova 8082771=Donald John Trump 162348=Ivan Mikhailovich Serebryakov 保存这篇文章以供将来使用:https://habr.com/ru/post/128017/ 现在阅读它还为时过早,但在将来,当您开始使用 HashMap 时,它将帮助您从内部理解这种数据结构的工作原理。另外,不要忘记查看有关 HashMap 的Oracle官方文档。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION