Java中的元组Tuple
1. 概念
Java中的Tuple是一种数据结构,可存放多个元素,每个元素的数据类型可不同。Tuple与List集合类似,但是不同的是,List集合只能存储一种数据类型,而Tuple可存储多种数据类型。
可能你会说,Object类型的List实际也是可以存储多种类型的啊?但是在创建List的时候,需要指定元素数据类型,也就是只能指定为Object类型,获取的元素类型就是Object,如有需要则要进行强转。而Tuple在创建的时候,则可以直接指定多个元素数据类型。
Tuple具体是怎么的数据结构呢?
元组(tuple)是关系数据库中的基本概念,关系是一张表,表中的每行(即数据库中的每条记录)就是一个元组,每列就是一个属性。 在二维表里,元组也称为行。
以上是百度百科中的"元组"概念,我们将一个元组理解为数据表中的一行,而一行中每个字段的类型是可以不同的。这样我们就可以简单理解Java中的Tuple数据结构了。
2. 使用
2.1 依赖Jar包
Maven坐标如下:
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
<version>1.2</version>
</dependency>
引入相关依赖后,可以看出jar包中的结构很简单,其中的类主要是tuple基础类、扩展的一元组、二元组…十元组,以及键值对元组;接口的作用是提供【获取创建各元组时传入参数值】的方法。
2.2 基本使用
2.2.1 直接调用
以下以三元组为例,部分源码如下:
package org.javatuples;
import java.util.Collection;
import java.util.Iterator;
import org.javatuples.valueintf.IValue0;
import org.javatuples.valueintf.IValue1;
import org.javatuples.valueintf.IValue2;
/**
* <p>
* A tuple of three elements.
* </p>
*
* @since 1.0
*
* @author Daniel Fernández
*
*/
public final class Triplet<A,B,C>
extends Tuple
implements IValue0<A>,
IValue1<B>,
IValue2<C> {
private static final long serialVersionUID = -1877265551599483740L;
private static final int SIZE = 3;
private final A val0;
private final B val1;
private final C val2;
public static <A,B,C> Triplet<A,B,C> with(final A value0, final B value1, final C value2) {
return new Triplet<A,B,C>(value0,value1,value2);
}
我们一般调用静态方法with,传入元组数据,创建一个元组。当然了,也可以通过有参构造、数组Array、集合Collection、迭代器Iterator来创建一个元组,直接调用相应方法即可。
但是,我们可能记不住各元组对象的名称(Unit、Pair、Triplet、Quartet、Quintet、Sextet、Septet、Octet、Ennead、Decade),还要背下单词…因此,我们可以自定义一个工具类,提供公共方法,根据传入的参数个数,返回不同的元组对象。
2.2.2 自定义工具类
package com.superchen.demo.utils;
import org.javatuples.Decade;
import org.javatuples.Ennead;
import org.javatuples.Octet;
import org.javatuples.Pair;
import org.javatuples.Quartet;
import org.javatuples.Quintet;
import org.javatuples.Septet;
import org.javatuples.Sextet;
import org.javatuples.Triplet;
import org.javatuples.Unit;
/**
* ClassName: TupleUtils
* Function:
* <p>
* Tuple helper to create numerous items of tuple. the maximum is 10.
* if you want to create tuple which elements count more than 10, a new class would be a better choice.
* if you don't want to new a class, just extends the class {@link org.javatuples.Tuple} and do your own implemention.
* </p>
* date: 2019/9/2 16:16
*
* @version 1.0.0
* @author Chavaer
* @since JDK 1.8
*/
public class TupleUtils{
/**
* <p>Create a tuple of one element.</p>
*
* @param value0
* @param <A>
*
* @return a tuple of one element
*/
public static <A> Unit<A> with(final A value0) {
return Unit.with(value0);
}
/**
* <p>Create a tuple of two elements.</p>
*
* @param value0
* @param value1
* @param <A>
* @param <B>
*
* @return a tuple of two elements
*/
public static <A, B> Pair<A, B> with(final A value0, final B value1) {
return Pair.with(value0, value1);
}
/**
* <p>Create a tuple of three elements.</p>
*
* @param value0
* @param value1
* @param value2
* @param <A>
* @param <B>
* @param <C>
*
* @return a tuple of three elements
*/
public static <A, B, C> Triplet<A, B, C> with(final A value0, final B value1, final C value2) {
return Triplet.with(value0, value1, value2);
}
}
以上的TupleUtils中提供了with的重载方法,调用时根据传入的参数值个数,返回对应的元组对象。
2.2.3 示例代码
若有需求:
现有pojo类Student、Teacher、Programmer,需要存储pojo类的字节码文件、对应数据库表的主键名称、对应数据库表的毕业院校字段名称,传到后层用于组装sql。
可以再定义一个对象类,但是如果还要再添加条件字段的话,又得重新定义…所以我们这里直接使用元组Tuple实现。
public class TupleTest {
public static void main(String[] args) {
List<Triplet<Class, String, String>> roleList = new ArrayList<Triplet<Class, String, String>>();
/*
三元组,存储数据:对应实体类字节码文件、数据表主键名称、数据表毕业院校字段名称
*/
Triplet<Class, String, String> studentTriplet = TupleUtils.with(Student.class, "sid", "graduate");
Triplet<Class, String, String> teacherTriplet = TupleUtils.with(Teacher.class, "tid", "graduate");
Triplet<Class, String, String> programmerTriplet = TupleUtils.with(Programmer.class, "id", "graduate");
roleList.add(studentTriplet);
roleList.add(teacherTriplet);
roleList.add(programmerTriplet);
for (Triplet<Class, String, String> triplet : roleList) {
System.out.println(triplet);
}
}
}
存储数据结构如下: