1. 概述
元组(Tuple)是一种可以包含多个元素的集合,这些元素之间可能有关联也可能无关。简单来说,元组可以看作是匿名对象。
例如,["RAM", 16, "Astra"]
就是一个包含三个元素的元组。
本教程将快速介绍一个超轻量级库 javatuples,它让我们能轻松操作基于元组的数据结构。
2. 内置的 Javatuples 类
该库提供了 10 个核心类,基本覆盖了所有元组使用场景:
✅ 基础元组类:
Unit<A>
(单元素)Pair<A,B>
(双元素)Triplet<A,B,C>
(三元素)Quartet<A,B,C,D>
(四元素)Quintet<A,B,C,D,E>
(五元素)Sextet<A,B,C,D,E,F>
(六元素)Septet<A,B,C,D,E,F,G>
(七元素)Octet<A,B,C,D,E,F,G,H>
(八元素)Ennead<A,B,C,D,E,F,G,H,I>
(九元素)Decade<A,B,C,D,E,F,G,H,I,J>
(十元素)
⚠️ 特殊语义类:
KeyValue<A,B>
(键值对)LabelValue<A,B>
(标签值对)
根据官方文档:所有 javatuples 类都是类型安全且不可变的,并实现了
Iterable
、Serializable
和Comparable
接口。
3. 添加 Maven 依赖
在 pom.xml
中添加依赖:
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
<version>1.2</version>
</dependency>
最新版本可查看 Maven 中央仓库。
4. 创建元组
创建元组非常简单粗暴:
方式一:构造器
Pair<String, Integer> pair = new Pair<String, Integer>("A pair", 55);
方式二:静态工厂方法(推荐)
Triplet<String, Integer, Double> triplet = Triplet.with("hello", 23, 1.2);
从集合创建
List<String> listOfNames = Arrays.asList("john", "doe", "anne", "alex");
Quartet<String, String, String, String> quartet
= Quartet.fromCollection(collectionOfNames);
⚠️ 踩坑提醒:集合元素数量必须与元组阶数匹配!比如上面的四元素列表无法创建 Quintet
(需要5个元素)。
从数组创建
String[] names = new String[] {"john", "doe", "anne"};
Triplet<String, String, String> triplet2 = Triplet.fromArray(names);
指定起始索引创建低阶元组
Pair<String, String> pairFromList = Pair.fromIterable(listOfNames, 2); // 取索引2和3
5. 获取元组值
类型安全方式(推荐)
通过 getValueX()
方法(X 从0开始):
Quartet<String, Double, Integer, String> quartet
= Quartet.with("john", 72.5, 32, "1051 SW");
String name = quartet.getValue0(); // 无需类型转换
Integer age = quartet.getValue2();
assertThat(name).isEqualTo("john");
assertThat(age).isEqualTo(32);
非类型安全方式
String name = (String) quartet.getValue(0); // 需要强制类型转换
Integer age = (Integer) quartet.getValue(2);
特殊说明:
KeyValue
和LabelValue
类有专属方法getKey()/getValue()
和getLabel()/getValue()
。
6. 修改元组值
由于元组不可变,所有修改操作都会返回新实例:
Pair<String, Integer> john = Pair.with("john", 32);
Pair<String, Integer> alex = john.setAt0("alex"); // 返回新元组
assertThat(john.toString()).isNotEqualTo(alex.toString()); // 原实例不变
7. 添加和删除元素
添加单个元素(自动升阶)
Pair<String, Integer> pair1 = Pair.with("john", 32);
Triplet<String, Integer, String> triplet1 = pair1.add("1051 SW");
assertThat(triplet1.contains("john")); // contains() 方法很实用
assertThat(triplet1.contains(32));
assertThat(triplet1.contains("1051 SW"));
合并两个元组
Pair<String, Integer> pair1 = Pair.with("john", 32);
Pair<String, Integer> pair2 = Pair.with("alex", 45);
Quartet<String, Integer, String, Integer> quartet2 = pair1.add(pair2);
assertThat(quartet2.containsAll(pair1)); // containsAll() 检查包含关系
assertThat(quartet2.containsAll(pair2));
指定位置插入
Pair<String, Integer> pair1 = Pair.with("john", 32);
Triplet<String, String, Integer> triplet2 = pair1.addAt1("1051 SW");
assertThat(triplet2.indexOf("john")).isEqualTo(0);
assertThat(triplet2.indexOf("1051 SW")).isEqualTo(1);
assertThat(triplet2.indexOf(32)).isEqualTo(2);
批量添加元素
Pair<String, Integer> pair1 = Pair.with("john", 32);
Quartet<String, Integer, String, Integer> quartet1 = pair1.add("alex", 45);
assertThat(quartet1.containsAll("alex", "john", 32, 45));
删除元素(自动降阶)
Pair<String, Integer> pair1 = Pair.with("john", 32);
Unit<Integer> unit = pair1.removeFrom0(); // 删除第一个元素
assertThat(unit.contains(32));
8. 转换为 List/Array
转换为 List
Quartet<String, Double, Integer, String> quartet
= Quartet.with("john", 72.5, 32, "1051 SW");
List<Object> list = quartet.toList(); // 固定返回 List<Object>
assertThat(list.size()).isEqualTo(4);
转换为数组
Object[] array = quartet.toArray(); // 固定返回 Object[]
assertThat(array.length).isEqualTo(4);
9. 总结
Javatuples 是个简单粗暴的解决方案:
- ✅ 类型安全且不可变
- ✅ 语义清晰(如
Pair.with()
比new Pair<>()
更优雅) - ✅ 支持与集合/数组互操作
- ❌ 元素数量固定(无法动态扩容)
完整示例代码见 GitHub 仓库,包含更多实用场景。