Using Pairs in Java – 在Java中使用对子

最后修改: 2017年 9月 14日

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

1. Overview

1.概述

In this quick tutorial, we discuss the highly useful programming concept known as a Pair. Pairs provide a convenient way of handling simple key to value association, and are particularly useful when we want to return two values from a method.

在这个快速教程中,我们将讨论被称为Pair的非常有用的编程概念。Pair为处理简单的键值关联提供了一种方便的方式,当我们想从一个方法中返回两个值时,它尤其有用。

A simple implementation of a Pair is available in the core Java libraries. Beyond that, certain third-party libraries such as Apache Commons and Vavr have exposed this functionality in their respective APIs.

Pair的简单实现在核心Java库中可用。除此之外,某些第三方库,如Apache Commons和Vavr,也在其各自的API中公开了这一功能。

2. Core Java Implementation

2.核心Java的实现

2.1. The Pair Class

2.1.配对

We can find the Pair class in the javafx.util package. The constructor of this class takes two arguments, a key and its corresponding value:

我们可以在javafx.util包中找到Pair类。这个类的构造函数需要两个参数,一个键和其对应的值。

Pair<Integer, String> pair = new Pair<>(1, "One");
Integer key = pair.getKey();
String value = pair.getValue();

This example illustrates a simple Integer to String mapping using the Pair concept.

这个例子说明了一个简单的IntegerString的映射,使用了Pair概念。

As shown, the key in the pair object is retrieved by invoking a getKey() method, while the value is retrieved by calling getValue().

如图所示,pair对象中的键是通过调用getKey()方法检索的,而值是通过调用getValue()来检索的。

2.2. AbstractMap.SimpleEntry and AbstractMap.SimpleImmutableEntry

2.2.AbstractMap.SimpleEntryAbstractMap.SimpleImmutableEntry

SimpleEntry is defined as a nested class inside the AbstractMap class. To create an object of this type we can provide a key and value to the constructor:

SimpleEntry被定义为AbstractMap类中的一个嵌套类。为了创建这种类型的对象,我们可以向构造函数提供一个键和值。

AbstractMap.SimpleEntry<Integer, String> entry 
  = new AbstractMap.SimpleEntry<>(1, "one");
Integer key = entry.getKey();
String value = entry.getValue();

The key and value can be accessed through standard getter and setter methods.

可以通过标准的getter和setter方法访问键和值。

Additionally, the AbstractMap class also contains a nested class that represents an immutable pair, the SimpleImmutableEntry class:

此外,AbstractMap类还包含一个表示不可变对的嵌套类,即SimpleImmutableEntry类。

AbstractMap.SimpleImmutableEntry<Integer, String> entry
  = new AbstractMap.SimpleImmutableEntry<>(1, "one");

This works in a similar way to the mutable pair class, except the value of the pair cannot be changed. Attempting to do so will result in an UnsupportedOperationException.

这与可变对类的工作方式类似,只是不能改变对的值。试图这样做将导致一个不支持操作的异常

3. Apache Commons

3.Apache Commons

In the Apache Commons library, we can find the Pair class in the org.apache.commons.lang3.tuple package. This is an abstract class, so it cannot be instantiated directly.

在Apache Commons库中,我们可以在org.apache.commons.lang3.tuple包中找到Pair类。这是一个抽象类,所以它不能直接实例化。

Here we can find two sub-classes representing immutable and mutable pairs, ImmutablePair and MutablePair.

在这里,我们可以找到两个代表不可变和可变对的子类:ImmutablePairMutablePair。

Both implementations have access to key/value getter/setter methods:

这两种实现都可以访问键/值getter/setter方法。

ImmutablePair<Integer, String> pair = new ImmutablePair<>(2, "Two");
Integer key = pair.getKey();
String value = pair.getValue();

Unsurprisingly, an attempt to invoke setValue() on the ImmutablePair results in an UnsupportedOperationException.

令人惊讶的是,试图对ImmutablePair 调用setValue()的结果是UnsupportedOperationException。

However, the operation is entirely valid for a mutable implementation:

然而,该操作对于一个可变的实现是完全有效的。

Pair<Integer, String> pair = new MutablePair<>(3, "Three");
pair.setValue("New Three");

4. Vavr

4.梵克雅宝

In the Vavr library, the pair functionality is provided by the immutable Tuple2 class:

在Vavr库中,配对功能是由不可变的Tuple2类提供的。

Tuple2<Integer, String> pair = new Tuple2<>(4, "Four");
Integer key = pair._1();
String value = pair._2();

In this implementation, we can’t modify the object after creation, so mutating methods are returning a new instance that includes the provided change:

在这个实现中,我们不能在创建后修改对象,所以变异方法会返回一个包括所提供的改变的新实例。

tuplePair = pair.update2("New Four");

5. Alternative I – Simple Container Class

5.替代方案一–简单的容器类

Either by user preference or in the absence of any of the aforementioned libraries, a standard workaround for the pair functionality is creating a simple container class that wraps desired return values.

无论是出于用户的偏好,还是在没有上述任何库的情况下,对功能的标准变通方法是创建一个简单的容器类来包装所需的返回值。

The biggest advantage here is an ability to provide our name, which helps in avoiding having the same class representing different domain objects:

这里最大的优势是能够提供我们的名字,这有助于避免让同一个类代表不同的领域对象。

public class CustomPair {
    private String key;
    private String value;

    // standard getters and setters
}

6. Alternative II – Arrays

6.备选方案二–阵列

Another common workaround is by using a simple array with two elements to achieve similar results:

另一个常见的解决方法是通过使用一个有两个元素的简单数组来实现类似的结果。

private Object[] getPair() {
    // ...
    return new Object[] {key, value};
}

Typically, the key is located at index zero of the array, while its corresponding value is located at index one.

通常情况下,键位于数组的索引0,而其对应的值位于索引1。

7. Conclusion

7.结论

In this article, we discussed the concept of Pairs in Java and the different implementations available in core Java as well as other third-party libraries.

在这篇文章中,我们讨论了Java中Pairs的概念以及核心Java和其他第三方库中的不同实现。

As always, the code for this article is available on GitHub.

一如既往,本文的代码可在GitHub上获得