Java Tuple

2025年5月10日 | 阅读 12 分钟

元组(Tuple)是一个固定大小且有序的元素列表。与数组或列表不同,元组可以包含任何类型的元素,并且是不可变的,这意味着一旦创建,元组的大小和元素就无法更改。通常在方法返回多个值或需要将异构值存储在一起时使用元组。这些对象本身没有连接,但当它们被集体考虑时具有意义。在本节中,我们将讨论元组的定义、特性、大小以及操作。我们还将讨论Java 中的元组实现

什么是元组?

一般而言,元组是一个有序的对象集合。在元组中,数据以对象的形式存储在一个单独的字节数组中。它包含用方括号 [] 括起来的逗号分隔的值。与列表数据结构不同,元组是不可变的。一个元组可以包含多个元组。它也可以被视为一个匿名对象。

元组的特性

元组包含以下特性:

  • 类型安全保证强制执行数据类型,这使得程序更加健壮。
  • 可迭代性使我们能够遍历元组的所有元素。
  • 不可变性保证一旦创建元组,其内容就不能被更改,这使得该元组更加稳定。
  • 序列化支持确保元组能够无缝地转换为格式化的存储或传输格式。
  • 它实现了 toString()、equals() 和 hashCode() 等方法,使其功能更强大、应用更广泛。
  • 此外,该类还实现了 Comparable 接口,以实现元组之间的比较操作。

元组示例

让我们看以下示例。

上面的元组是一个四元组,因为它有四个元素(对象)。我们注意到每个对象都是不同类型的。但当我们将它作为一个整体来看时,它具有特定的含义。上面的元组代表了一个员工的数据,如姓名、性别、年龄和职位。

让我们看一些其他的元组示例。

Java 中的元组

在 Java 中,元组是一种泛型数据结构,它将每个元素视为一个对象,并将这些对象存储在一个单独的字节数组中。换句话说,我们也可以说元组是不同类型对象的有序集合

Java 具有模拟元组功能的能力。然而,List 和 Array 结构内置的功能专门用于存储相同类型的元素。因此,使用标准 Java 数据结构(如 List 或 Array)来实现异构元组通常是不现实的。由于元组能够接受不仅相同类型的元素,还能接受不同类型的元素,因此 Java 中缺乏元组数据结构再次强调了拥有一个能够管理集合中各种类型异构元素的结构的需求。

请注意,Java 编程中默认不存在元组数据结构。但我们可以使用名为 javatuples 的第三方库来实现元组数据结构。

在进行实现之前,我们将首先下载 javatuples.jar 文件。并将此文件添加到项目路径中。

我们也可以在 pom.xml 文件中使用以下依赖项来实现 Java 中的元组数据结构。

让我们实现一个元组并创建一个简单的 Java 元组程序。

Javatuples 库

javatuples 库包含与元组大小相对应的元组类。元组的大小可能不同。一个元组最多可以包含10个元素。每个元组的实现都不同。类层次结构如下。

Java 元组类

Tuple 是 org.javatuples 包中所有其他元组子类的抽象基类。此外,Tuple 类中的所有方法都是 public 和 final 的。此外,Tuple 类实现了 Iterable 和 Serializable 接口,分别支持迭代和序列化。下表总结了 Tuple 类的方法。

方法语法描述
contains()public final boolean contains(java.lang.Object value)它检查元组是否包含特定元素。
containsAll()public final boolean containsAll(java.util.Collection<?> collection)如果此元组包含指定集合(List/Array)的所有元素,则返回 true。
equals()public final boolean equals(java.lang.Object obj)它重写了 Object 类中的 equals() 方法。
getSize()public abstract int getSize()它返回元组的大小。
getValue()public final java.lang.Object getValue(int pos)可以通过返回一个对象的方法来获取元组中特定位置的值。然而,这种方法可能会导致类型安全性的丢失,而类型安全性是使用 getValueX() 方法最有价值的特性之一。
hashCode()public final int hashCode()它返回字符串的哈希码。它重写了 Object 类的 hashCode() 方法。
indexOf()public final int indexOf(java.lang.Object value)它返回此字符串中指定子字符串第一次出现的位置索引。
iterator()public final java.util.Iterator<java.lang.Object> iterator()它按正确的顺序返回此元组中元素的迭代器。
lastIndexOf()public final int lastIndexOf(java.lang.Object value)它返回此字符串中指定子字符串最后一次出现的位置索引。
toArray()public final java.lang.Object[] toArray()它将元组转换为数组。
toString()public final java.lang.String toString()它返回对象的字符串表示形式。重写了 Object 类的 toString() 方法。
toList()public final java.util.List<java.lang.Object> toList()它将元组转换为列表。

直接已知的子类

元组大小元组类名示例
一个元素UnitUnit<1>
两个元素PairPair<1,2>
三个元素TripletTriplet<1,2,3>
四个元素QuartetQuartet<1,2,3,4>
五个元素QuintetQuintet<1,2,3,4,5>
六个元素SextetSextet<1,2,3,4,5,6>
七个元素SeptetSeptet<1,2,3,4,5,6,7>
八个元素OctetOctet<1,2,3,4,5,6,7,8>
九个元素EnneadEnnead<1,2,3,4,5,6,7,8,9>
十个元素DecadeDecade<1,2,3,4,5,6,7,8,9,10>

此外,`javatuples` 库还提供了两个补充类:`KeyValue<A, B>` 和 `LabelValue<A, B>`。这些类与 Pair 类相似,因此它们具有相同的功能,尽管它们的语义不同。

每个元组类都实现了以下三个接口:

  • Iterable
  • Comparable
  • Serializable

元组的实现

在 Java 中实现元组非常简单。它包括实例化与预期大小相同的元组类。

TupleExample.java

输出

The details of the employee are: [Sophia, Female, 22, Marketing Manager]

元组操作

可以对元组执行以下操作:

  • 创建元组
  • 获取值
  • 设置值
  • 添加元素
  • 迭代元组
  • 将元组转换为列表
  • 在元组中搜索

创建元组

创建元组有三种方法:

  • 使用 with() 方法
  • 使用构造函数
  • 使用集合

让我们看看以上三种创建元组的方法。

使用 with() 方法

with() 方法属于元组引用的类,通常在 javatuples 库中找到。with() 方法的一个主要优点是它允许创建一个新元组,其元素被修改,同时保持元组的基本不变性。该方法属于 org.javatuples.Pair 包。

语法

示例

上面的 Pair 类对象创建了一个包含两个值的元组。让我们为此创建一个 Java 程序。

CreateTupleExample1.java

输出

[9086651, Dell Laptop]

使用构造函数

在这种情况下,我们根据要求创建类的构造函数。

语法

示例

让我们创建一个 Java 程序来使用构造函数创建元组。

CreateTupleExample2.java

输出

[91237, Mac Book Air, 88490.0, 8-Core CPU, 4]

使用集合

javatuples 库有一个名为 fromCollection() 的方法,可以从集合生成元组。此外,它还允许用户使用 fromArray() 方法从数组创建元组。必须考虑到收集的项目和数组应具有与正在创建的元组相同的类型和值。此外,集合数组的类应对应于 Tuple,并且其长度应等于元组的基数。

集合/数组的类型必须与 Tuple 相同,并且集合/数组中的值数量必须与 Tuple 类匹配。

语法

示例

CreateTupleExample3.java

输出

[C, C++, Java, Python, Scala, Ruby, PHP, COBOL]
[One, Two, Three, Four, Five, Six]

获取值

javatuples 库提供了一个方便的方法 getValueX(),可以轻松地通过给定索引从元组中获取项。其中,X 是元组中目标对象的索引,从 0 开始编号。

示例

GetValueExample.java

输出

[Andrew]

设置值

正如我们上面讨论的,元组是不可变的。因此,它们一旦创建就不能被修改。为了克服这个问题,Javatuples 库提供了 setValueX() 方法。其中 X 是我们要设置特定值的索引值。该方法会创建一个带有在指定索引处添加的新值的元组副本,并返回相同的元组。

示例

SetValueExample.java

输出

[67, 68]

添加值

有两种方法可以向元组添加值:

  • 在元组末尾
  • 在特定索引处

在元组末尾

javatuples 库提供了 add() 方法来向元组添加对象。它将对象添加到元组末尾,并返回一个新元组,该元组与元素数量匹配。

假设我们有一个包含两个元素的元组,并且有必要向元组添加另一个项。在这种情况下,Pair 元组结构无法提供 3 元素属性。因此,每当尝试向 Pair 元组添加元素时,它都会自动转换为 Triplet 元组。让我们通过一个例子来演示。

AddElementInTuple.java

输出

[Jack, 46]
[Jack, 46, Finance Professional]

我们也可以将一个元组添加到另一个元组。这会增加新生成的元组中的元素数量。因此,它会根据添加后的元素数量返回元组的类型。

AddTuplesExample.java

输出

[Mango, Grapes, Papaya]
[Mango, Banana, Grapes, Papaya]
[Mango, Banana, Grapes, Papaya, Mango, Grapes, Papaya]

在指定索引处

默认情况下,新元素会添加到元组的末尾。但我们可以使用 addX() 方法在指定索引处添加元素。

AddAtIndexExample.java

输出

[MCA, M.Sc., MBBS]
[MCA, M.Sc., M.Tech, MBBS]

搜索元素

javatuples 库在 Tuple 类中提供了一个名为 contains() 的方便方法来搜索元素。如果找到元素,它返回布尔值 true,否则返回 false。让我们通过一个例子来探索。

SearchingElementExample.java

输出

true
false

将元组转换为集合或数组

元组到集合/数组的转换可能在许多方面非常有用,例如将元组数据与现有的 Java 集合统一,或使用基于数组的算法处理元组。在 Java 中,元组主要提供有助于完成此过渡过程的方法,从而使数据结构具有互操作性。让我们看一个例子。

TupleToCollection.java

输出

[Dog, 12, German Shepherd, 23.89]
[Dog, 12, German Shepherd, 23.89]

请注意,元组可以包含异构类型,因此结果类型将分别为 List<Object>Object[]

迭代元组

如前所述,Java 不像许多其他编程语言那样提供内置的元组类型;您可以使用多种技术来模拟其行为,例如数组或集合,或创建自己的类。

在 Java 中迭代元组的行为在很大程度上取决于您的元组数据结构。如果您正在为元组创建数组或集合,则可以使用循环和迭代器进行遍历。所有元组类都实现了 Iterable 接口。因此,我们可以像迭代集合或数组一样迭代元组。

IterateTuple.java

输出

Dell
5600.0
34
Digital Solutions

元组与列表/数组的比较

Java Tuple
元组列表
它是一组用圆括号括起来的逗号分隔的值。它是一组用方括号括起来的逗号分隔的值。
圆括号是可选的方括号是必需的
它是不可变的它是可变的
它需要更少的内存。它需要更多的内存。
它有更少的工厂方法。它有更多的工厂方法。
它具有固定长度。它具有可变长度。
它存储异构数据。它存储同构数据。
它适用于大量数据。它适用于少量数据。
它可以存储在列表中它可以存储在元组内部
与列表相比,它更快与元组相比,它更慢
它表示为 t1 = (1, 2, 3, 4, 5)它表示为 l1 = [1, 2, 3, 4, 5]