# Java 元组 – 使用 Java 中的元组

> 原文： [https://howtodoinjava.com/java/basics/java-tuples/](https://howtodoinjava.com/java/basics/java-tuples/)

在本 Java 教程中，我们将学习 **Java 元组** – 通用数据结构，以及如何在 Java 程序中使用元组。 默认情况下，元组在 Java 编程语言中不作为数据结构出现，因此我们将使用一个不错的第三方库`javatuples`。

```java
Table of Contents

1\. What is tuple
2\. Tuple in Java
3\. Introduction of Javatuples 
4\. Common Operations on Javatuples
5\. Conclusion
```

## 1\. 什么是元组？

元组可以看作是*有序的不同类型的对象*的集合。 这些对象不一定以任何方式相互关联，但是它们总的来说将具有一定的意义。

例如，`["Sajal Chakraborty", "IT Professional", 32]`可以是一个元组，其中该元组中的每个值都没有任何关系，但是整个值集在应用程序中可能具有某些意义。 例如，给定元组可以代表具有姓名，部门和年龄的员工数据。

让我们来看更多 *java 元组示例*。

```java
["Java", 1.8, "Windows"]
["Alex", 32, "New York", true]
[3, "Alexa", "howtodoinjava.com", 37000]

```

## 2\. Java 中的元组

Java 没有任何这样的内置数据结构来支持元组。 无论何时需要，我们显然都可以创建一个类似于元组的类。

同样，在 Java 中，可以使用列表或数组来编写元组特性的一部分，但这些不允许我们通过设计保存不同类型的数据类型。 因此，可以说在 Java 中使用标准数据结构的异构元组是不可能的。

#### 2.1 元组与列表/数组的比较

通常将元组与列表进行比较，因为它看起来非常像一个列表。 但是它们在某些方面有所不同。

1.  元组是可以包含异构数据的对象。 列表旨在存储单一类型的元素。
2.  在所有数据结构中，元组被认为是最快的，并且它们消耗的内存量最少。
3.  虽然数组和列表是可变的，这意味着您可以更改其数据值并修改其结构，但元组是不可变的。
4.  像数组一样，元组的大小也是固定的。 这就是为什么元组旨在完全替换数组的原因，因为它们在所有参数上都更有效率。
5.  如果您有一个在生命周期内仅分配一次的数据集，并且其值不应再次更改，则需要一个元组。

## 3\. `javatuples`库

#### 3.1 `javatuples` maven 依赖

`javatuples`库存在于 Maven 中央存储库中，我们可以添加此依赖项以使用该库。

```java
<dependency>
	<groupId>org.javatuples</groupId>
	<artifactId>javatuples</artifactId>
	<version>1.2</version>
</dependency>

```

#### 3.2 `javatuples` - 类

Java 元组支持最大为`10`的元组，并且对于每种大小，它都提供了如下的元组实现。

*   `Unit`（一个元素）
*   `Pair`（两个元素）
*   `Triplet`（三个元素）
*   `Quartet`（四个元素）
*   `Quintet`（五个元素）
*   `Sextet`（六个元素）
*   `Septet`（七个元素）
*   `Octet`（八个元素）
*   `Ennead`（九个元素）
*   `Decade`（十个元素）

除了上述类之外，它还提供了另外两个类来方便表示对。 大部分与`Pair`相同，但语法更详细。

1.  `KeyValue`
2.  `LabelValue`

#### 3.3 `javatuples` – 特性

*不同类型的 Java 元组*是：

1.  输入安全
2.  不可变
3.  可迭代的
4.  可序列化
5.  可比（实现`Comparable`）
6.  实现`equals()`和`hashCode()`
7.  实现`toString()`

## 4\. `javatuples`的常见操作

#### 4.1 创建元组

###### 4.1.1 工厂方法

元组对象是通过每个元组类提供的**工厂方法`with()`** 构造的。 例如，我们可以使用创建`Pair`的元组。

```java
Pair<String, Integer> pair = Pair.with("Sajal", 12);
```

###### 4.1.2 构造器

我们还可以使用`Pair`的**构造器**。

```java
Pair<String, Integer> person = new Pair<String, Integer>("Sajal", 12);
```

###### 4.1.3 集合或可迭代对象

我们可以从`Collection`或`Iterable`创建元组，前提是该集合具有确切数量的对象。 在这种情况下，请记住，集合中的项目数应与我们要创建的元组的类型相匹配。

```java
//Collection of 4 elements will create Quartet
List<String> listOf4Names = Arrays.asList("A1","A2","A3","A4");

Quartet<String, String, String, String> quartet = Quartet.fromCollection(listOf4Names);

System.out.println(quartet);

//Create pair with items starting from the specified index.
List<String> listOf4Names = Arrays.asList("A1","A2","A3","A4");

Pair<String, String> pair1 = Pair.fromIterable(listOf4Names, 2);

System.out.println(pair1);

```

程序输出。

```java
[A1, A2, A3, A4]
[A3, A4]

```

同样，我们可以根据需要创建任何元组类的对象。

#### 4.2 检索值

###### 4.2.1 `getValueX()`方法

我们可以使用其索引的`getValueX()`方法从元组中获取值，其中`'X'`表示元组内部的元素位置。 例如`getValue0()`，`getValue1()`等。

```java
Pair<String, Integer> pair = Pair.with("Sajal", 12);

System.out.println("Name : " + pair.getValue0());
System.out.println("Exp : " + pair.getValue1());

```

程序输出：

```java
Name : Sajal
Exp : 12

```

请注意，这些获取方法是类型安全的。 这意味着编译器已经基于用于初始化元组的元素值知道方法的返回类型。

###### 4.2.2 `getValue(int index)`方法

元组还有另一种类型不安全的方法`getValue(int index)`。 因此，在分配变量时，需要将值转换为期望的类型。

```java
Pair<String, Integer> pair = Pair.with("Sajal", 12);

System.out.println("Name : " + pair.getValue(0));
System.out.println("Exp : " + pair.getValue(1));

```

程序输出：

```java
Name : Sajal
Exp : 12

```

类`KeyValue`和`LabelValue`的方法分别为`getKey()`/`getValue()`和`getLabel()`/`getValue()`。

#### 4.3 设定值

创建元组后，我们可以设置值。 我们可以通过`setAtX()`方法执行此操作，其中`'X'`是我们要设置值的索引位置。

```java
Pair<String, Integer> pair = Pair.with("Sajal", 12);

//Modify the value
Pair<String, Integer> modifiedPair = pair.setAt0("Kajal");

System.out.println(pair);
System.out.println(modifiedPair);

```

程序输出：

```java
[Sajal, 12]
[Kajal, 12]

```

> 请注意，元组是不可变的。 因此，`setAt()`方法返回具有修改后值的相同类型的元组。 原始元组不变。

#### 4.4 添加或删除元素

###### 4.4.1 `add()`方法

我们还可以在元组中添加元素，这将返回与元素数量匹配的新元组类型。 例如，如果我们将元素值添加到`Pair`，那么我们将获得一个`Triplet`对象作为回报。

元组的末尾添加了新元素。

```java
Pair<String, Integer> pair = Pair.with("Sajal", 12);

Triplet<String, Integer, String> triplet = pair.add("IT Professional");

System.out.println(pair);
System.out.println(triplet);

```

程序输出：

```java
[Sajal, 12]
[Sajal, 12, IT Professional]

```

我们也可以将一个元组对象添加到另一个元组中。 它将根据添加后存在的元素数返回元组的类型。

```java
Triplet<String, String, String> triplet = Triplet.with("Java", "C", "C++");
Quartet<String, String, String, String> quartet = triplet.addAt1("Python");

Septet septet = quartet.add(triplet);   //3 + 4 = 7

System.out.println(triplet);
System.out.println(quartet);
System.out.println(septet);

```

程序输出：

```java
[Java, C, C++]
[Java, Python, C, C++]
[Java, Python, C, C++, Java, C, C++]

```

###### 4.4.2 `join()`方法

默认情况下，新元素添加到元组的末尾。 但是我们也可以使用`addAtX()`方法在元组的其他位置添加元素。

```java
Triplet<String, String, String> triplet = Triplet.with("Java", "C", "C++");
Quartet<String, String, String, String> quartet = triplet.addAt1("Python");

System.out.println(triplet);
System.out.println(quartet);

```

程序输出：

```java
[Java, C, C++]
[Java, Python, C, C++]

```

#### 4.5 将元组转换为集合或数组

每个元组类提供`asList()`和`toArray()`方法，它们分别返回`List`和`Array`。

```java
//Convert to list
Quartet<String, Integer, String, Double> quartet1 = Quartet.with("A1",1,"A3",2.3);

List<Object> quartletList = quartet1.toList();

System.out.println(quartletList);

//Convert to array
Object[] quartletArr = quartet1.toArray();

System.out.println(Arrays.toString(quartletArr));

```

程序输出：

```java
[A1, 1, A3, 2.3]
[A1, 1, A3, 2.3]

```

> 请注意，元组可以包含异构类型，因此相应的结果类型将为`List<Object>`或`Object[]`。

#### 4.6 迭代

`javatuples`中的所有元组类都实现`Iterable`接口，因此可以与集合或数组相同的方式对其进行迭代。

```java
Quartet<String, Integer, String, Double> quartet1 = Quartet.with("A1",1,"A3",2.3);

for(Object obj : quartet1) {
	System.out.println(obj);
}

```

程序输出：

```java
A1
1
A3
2.3

```

#### 4.7 Java 元组中的更多操作

所有元组类都有以下实用方法，例如集合，我们可以根据需要使用它们。

*   **`contains()`** – 如果该元组包含指定的元素，则返回`true`。
*   **`containsAll()`** – 如果该元组包含所有指定的元素，则返回`true`。
*   **`indexOf()`** – 返回指定元素首次出现的索引。
*   **`lastIndexOf()`** – 返回指定元素最后一次出现的索引。

元组还提供`hashCode()`，`equals()`和`compareTo()`方法的通用实现，这些方法可以很好地处理包装程序和字符串类。

## 5\. Java 元组 - 总结

在此 **Java 元组教程**中，我们了解了如何通过`javatuple`库在 Java 中使用元组。 因此，如果您对存储*固定数量的异构元素*的数据结构有任何要求，则可以使用此库。 它非常简单，易于使用并提供良好的性能。

[下载源码](https://howtodoinjava.com/wp-content/uploads/2018/10/javaTuples.zip)

学习愉快！

参考文献：

[`Javatuples`的官方页面](https://www.javatuples.org/index.html)