什么是元组?

元组可以看作是不同类型对象的有序集合。
这些对象不一定以任何方式相互关联,但它们共同具有某种意义。

例如,["Jack Ma", "IT Professional", 54]可以是一个元组,其中元组中的每个值都没有任何关系,但是这整套值在应用程序中可能具有某种意义。
例如,给定元组可能代表具有姓名、部门和年龄的员工数据。

更多的 Java 元组示例:

[``"Java"``, 1.8, ``"Windows"``]``[``"JackLi"``, 32, ``"New York"``, ``true``]``[3, ``"Alexa"``, ``"onitroad.com"``, 37000]

Java 中的元组

Java 没有任何这样的内置数据结构来支持元组。
在需要时,我们可以创建一个可以充当元组的类。

此外,在 Java 中,元组功能的一部分可以使用 List或者 Array来编写,但它们不允许我们按设计保存不同类型的数据类型。
所以我们可以说使用标准数据结构的异构元组在 Java 中是不可能的。

元组与列表/数组的比较

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

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

Javatuples 库

javatuples Maven 依赖

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

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

javatuples - 类

Javatuples 支持大小高达“10”的元组,并且对于每个大小,它都提供了如下所示的元组实现。

  • Unit(一个元素)
  • Pair(两个元素)
  • Triplet(三个元素)
  • Quartet(四个元素)
  • Quintet(五个元素)
  • Sextet(六个元素)
  • Septet(七个元素)
  • Octet(八个元素)
  • Ennead(九个元素)
  • Decade(十个元素)

在上述类之上,它提供了另外两个类,以便于表示对。
他们与“Pair”大致相同,但语法更冗长。

  • KeyValue
  • LabelValue

Java 元组示例 - 常见操作

创建元组

工厂方法

元组对象由每个元组类提供的工厂方法with()构造。
例如,我们可以使用创建一个 Pair元组。

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

构造函数

我们也可以使用 Pair的构造函数。

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

集合或者可迭代

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

//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` `a 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);

输出:

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

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

获取值

getValue() 方法

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

Pair<String, Integer> pair = Pair.with(``"Sajal"``, 12);``System.out.println(``"Name : "` `+ pair.getValue0());``System.out.println(``"Exp : "` `+ pair.getValue1());

输出:

Name : Sajal``Exp : 12

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

getValue(int index) 方法

元组有另一种非类型安全的方法 getValue(int index)。
因此,当我们分配给变量时,我们需要将值转换为预期的类型。

Pair<String, Integer> pair = Pair.with(``"Sajal"``, 12);``System.out.println(``"Name : "` `+ pair.getValue(0));``System.out.println(``"Exp : "` `+ pair.getValue(1));

输出:

Name : Sajal``Exp : 12

KeyValueLabelValue分别具有getKey()/getValue() 和getLabel()/getValue() 方法。

设定值

我们可以在创建元组后在元组中设置值。
我们可以通过 setAtX()方法来做到这一点,其中 'X'是我们想要设置值的索引位置。

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);

输出:

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

请注意元组是不可变的。
所以setAt()方法返回具有修改值的相同类型的元组。
原始元组不变。

添加和删除元素

add() 方法

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

在元组的末尾添加了一个新元素。

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);

输出:

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

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

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, C, C++]``[Java, Python, C, C++]``[Java, Python, C, C++, Java, C, C++]

addAt() 方法

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

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, C, C++]``[Java, Python, C, C++]

将元组转换为集合或者数组

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

//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));

输出:

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

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

迭代值

所有元组类都实现了Iterable接口,因此它们可以像集合或者数组一样被迭代。

Quartet<String, Integer, String, Double> quartet1 = Quartet.with(``"A1"``,1,``"A3"``,2.3);``for``(Object obj : quartet1) {``  ``System.out.println(obj);``}

输出:

A1``1``A3``2.3

java元组中的更多操作

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

  • contains() - 如果此元组包含指定的元素,则返回 true
  • containsAll() - 如果此元组包含所有指定的元素,则返回 true
  • indexOf() - 返回指定元素第一次出现的索引。
  • lastIndexOf() - 返回指定元素最后一次出现的索引。

元组还提供了 hashCode() 、 equals() 和 compareTo() 方法的通用实现。

参考