How to Create a New Entry in a Map – 如何在地图中创建一个新条目

最后修改: 2022年 2月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll discuss how to use Java’s built-in classes, third-party libraries, and our custom implementation to create an Entry object that represents a key-value association in a Map.

在本教程中,我们将讨论如何使用 Java 的内置类、第三方库和我们的自定义实现来创建一个 Entry 对象,该对象表示 Map 中的一个键值关联。

2. Using Java Built-in Classes

2.使用Java内置类

Java provides the Map.Entry interface with two simple implementations to create an Entry. Let’s take a look at them.

Java提供了Map.Entry接口,有两个简单的实现来创建Entry。让我们来看看它们。

2.1. Using AbstractMap.SimpleEntry

2.1.使用AbstractMap.SimpleEntry

The SimpleEntry class is a static nested class in the AbstractMap class. It provides two different constructors to initialize an instance:

SimpleEntry类是AbstractMap类中的一个静态嵌套类。它提供了两个不同的构造函数来初始化一个实例。

AbstractMap.SimpleEntry<String, String> firstEntry = new AbstractMap.SimpleEntry<>("key1", "value1");
AbstractMap.SimpleEntry<String, String> secondEntry = new AbstractMap.SimpleEntry<>("key2", "value2");
AbstractMap.SimpleEntry<String, String> thirdEntry = new AbstractMap.SimpleEntry<>(firstEntry);
thirdEntry.setValue("a different value");

assertThat(Stream.of(firstEntry, secondEntry, thirdEntry))
  .extracting("key", "value")
  .containsExactly(
    tuple("key1", "value1"),
    tuple("key2", "value2"),
    tuple("key1", "a different value"));

As we can see here, one of the constructors accepts the key and the value, while the other one accepts an Entry instance to initialize a new Entry instance.

正如我们在这里看到的,其中一个构造函数接受键和值,而另一个构造函数接受一个Entry实例来初始化一个新的Entry实例。

2.2. Using AbstractMap.SimpleImmutableEntry

2.2.使用AbstractMap.SimpleImmutableEntry

Just like with the SimpleEntry, we can use SimpleImmutableEntry to create entries:

就像使用SimpleEntry,我们可以使用SimpleImmutableEntry来创建条目。

AbstractMap.SimpleImmutableEntry<String, String> firstEntry = new AbstractMap.SimpleImmutableEntry<>("key1", "value1");
AbstractMap.SimpleImmutableEntry<String, String> secondEntry = new AbstractMap.SimpleImmutableEntry<>("key2", "value2");
AbstractMap.SimpleImmutableEntry<String, String> thirdEntry = new AbstractMap.SimpleImmutableEntry<>(firstEntry);

assertThat(Stream.of(firstEntry, secondEntry, thirdEntry))
  .extracting("key", "value")
  .containsExactly(
    tuple("key1", "value1"),
    tuple("key2", "value2"),
    tuple("key1", "value1"));

In contrast to SimpleEntry, SimpleImmutableEntry doesn’t allow us to change the value after initializing the Entry instance. If we try to change the value, it throws java.lang.UnsupportedOperationException.

SimpleEntry相比,SimpleImmutableEntry不允许我们在初始化Entry实例后改变其值。如果我们试图改变值,它会抛出java.lang.UnsupportedOperationException.

2.3. Using Map.entry

2.3.使用Map.entry

Since version 9, Java has a static method entry() in the Map interface to create an Entry:

从第9版开始,Java在Map接口中有一个静态方法entry()来创建一个Entry

Map.Entry<String, String> entry = Map.entry("key", "value");

assertThat(entry.getKey()).isEqualTo("key");
assertThat(entry.getValue()).isEqualTo("value");

We need to keep in mind that the entry created this way is also immutable and would lead to a java.lang.UnsupportedOperationException if we try to change the value after the initialization.

我们需要记住,这样创建的条目也是不可改变的,如果我们在初始化后试图改变值,将会导致java.lang.UnsupportedOperationException

3. Third-Party Libraries

3.第三方图书馆

Besides Java itself, there are a few popular libraries that provide nice ways to create entries.

除了Java本身,还有一些流行的库提供了很好的方法来创建条目。

3.1. Using Apache commons-collections4 Library

3.1.使用Apache commons-collections4

Let’s start by including our Maven dependency first:

让我们先把我们的Maven依赖性包括进来。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
</dependency>

We should mention that besides the Entry interface, the library also provides an interface called KeyValue:

我们应该提到,除了Entry接口,该库还提供了一个名为KeyValue:的接口。

Map.Entry<String, String> firstEntry = new DefaultMapEntry<>("key1", "value1");
KeyValue<String, String> secondEntry = new DefaultMapEntry<>("key2", "value2");

KeyValue<String, String> thirdEntry = new DefaultMapEntry<>(firstEntry);
KeyValue<String, String> fourthEntry = new DefaultMapEntry<>(secondEntry);

firstEntry.setValue("a different value");

assertThat(firstEntry)
  .extracting("key", "value")
  .containsExactly("key1", "a different value");

assertThat(Stream.of(secondEntry, thirdEntry, fourthEntry))
  .extracting("key", "value")
  .containsExactly(
    tuple("key2", "value2"),
    tuple("key1", "value1"),
    tuple("key2", "value2"));

The DefaultMapEntry class provides three different constructors. While the first one accepts the key-value pair, the second and the third accept the parameter type of Entry and KeyValue, respectively.

DefaultMapEntry类提供了三个不同的构造函数。第一个构造函数接受键值对,第二个和第三个构造函数分别接受EntryKeyValue的参数类型。

The UnmodifiableMapEntry class also behaves the same way:

UnmodifiableMapEntry类的行为也是如此。

Map.Entry<String, String> firstEntry = new UnmodifiableMapEntry<>("key1", "value1");
KeyValue<String, String> secondEntry = new UnmodifiableMapEntry<>("key2", "value2");

KeyValue<String, String> thirdEntry = new UnmodifiableMapEntry<>(firstEntry);
KeyValue<String, String> fourthEntry = new UnmodifiableMapEntry<>(secondEntry);

assertThat(firstEntry)
  .extracting("key", "value")
  .containsExactly("key1", "value1");

assertThat(Stream.of(secondEntry, thirdEntry, fourthEntry))
  .extracting("key", "value")
  .containsExactly(
    tuple("key2", "value2"),
    tuple("key1", "value1"),
    tuple("key2", "value2"));

However, as we can understand from its name, UnmodifiableMapEntry also doesn’t allow us to change the value after the initialization.

然而,正如我们从它的名字中可以理解的那样,UnmodifiableMapEntry也不允许我们在初始化后改变其值.

3.2. Using Google Guava Library

3.2.使用Google Guava库

Let’s first include our Maven dependency:

首先让我们包括我们的Maven依赖性。

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
 </dependency>

Now, let’s see how we can use the immutableEntry() method:

现在,让我们看看如何使用immutableEntry()方法。

Map.Entry<String, String> firstEntry = Maps.immutableEntry("key1", "value1");
Map.Entry<String, String> secondEntry = Maps.immutableEntry("key2", "value2");

assertThat(Stream.of(firstEntry, secondEntry))
  .extracting("key", "value")
  .containsExactly(
    tuple("key1", "value1"),
    tuple("key2", "value2"));

Since it creates an immutable entry, if we try to change the value, it throws java.lang.UnsupportedOperationException.

由于它创建了一个不可变的条目,如果我们试图改变值,它会抛出java.lang.UnsupportedOperationException.

4. Custom Implementation

4.定制实施

So far, we have seen a few options to create an Entry instance to represent a key-value association. These classes have been designed in a way that they must comply with the internal logic of the Map interface implementations such as HashMap

到目前为止,我们已经看到了一些创建Entry实例以表示键值关联的选项。这些类的设计方式是,它们必须符合Map接口实现的内部逻辑,例如HashMap

This means that as long as we comply with the same, we can create our own implementation of the Entry interface. First, let’s add a simple implementation:

这意味着,只要我们遵守,我们就可以创建我们自己的Entry接口的实现。首先,让我们添加一个简单的实现。

public class SimpleCustomKeyValue<K, V> implements Map.Entry<K, V> {

    private final K key;
    private V value;

    public SimpleCustomKeyValue(K key, V value) {
        this.key = key;
        this.value = value;
    }
    // standard getters and setters
    // standard equals and hashcode
    // standard toString
}

Finally, let’s see a few examples of usage:

最后,让我们看看几个使用的例子。

Map.Entry<String, String> firstEntry = new SimpleCustomKeyValue<>("key1", "value1");

Map.Entry<String, String> secondEntry = new SimpleCustomKeyValue<>("key2", "value2");
secondEntry.setValue("different value");

Map<String, String> map = Map.ofEntries(firstEntry, secondEntry);

assertThat(map)
  .isEqualTo(ImmutableMap.<String, String>builder()
    .put("key1", "value1")
    .put("key2", "different value")
    .build());

5. Conclusion

5.总结

In this article, we learned how we could use the existing options that Java gives and a few alternatives that some popular third-party libraries provide to create an Entry instance. Additionally, we also created a custom implementation and showed a few examples of usage.

在这篇文章中,我们学习了如何使用Java提供的现有选项以及一些流行的第三方库提供的一些替代方案来创建Entry实例。此外,我们还创建了一个自定义的实现,并展示了几个使用实例。

As always, the code for these examples is available over on GitHub.

一如既往,这些例子的代码可以在GitHub上获得