一起读源码1. Java 中元组 Tuple
Posted smile-yan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起读源码1. Java 中元组 Tuple相关的知识,希望对你有一定的参考价值。
问题描述
使用 Java 做数据分析、机器学习的时候,常常需要对批量的数据进行处理,如果需要处理的数据的维度不超过10时,可以考虑使用 org.javatuples 提供的 Tuple 类工具。支持 1 - 10 的多维数据处理,支持数据泛型。除了常见的 Integer / String / Long / Double 还可以是自定义的数据类型。
总体分析
如图所示,总共 13 个类,13个接口。
先看接口非常简单,附带自己的泛型 X,然后提供一个自己的方法 X getValue0() … X getValue9() … getValue … getKey … getLabel.
所有的类的父类为抽象类 Tuple,注意该方法并没有包含任何泛型,而是实现了常见的三个接口:
- Iterable
- Serializable
- Comparable
接下来要出场的子类就根据实际情况实现多个接口,返回对应的值。具体内容如下表所示:
类名 | 参数数目 |
---|---|
Unit | 1 |
Pair | 2 |
KeyValue | 2 |
LabelValue | 2 |
Triplet | 3 |
Quartet | 4 |
Quintet | 5 |
Sextet | 6 |
Septet | 7 |
Octet | 8 |
Ennead | 9 |
Decade | 10 |
父类 Tuple
Tuple 是一个抽象类,具有两个成员变量,如下:
private final Object[] valueArray;
private final List<Object> valueList;
私有变量外部不能直接访问,这两个变量的主要作用应该是用于 Iterable 遍历。
接着看 Tuple 对这个接口的实现:
public final Iterator<Object> iterator()
return this.valueList.iterator();
比较容易理解,把 Tuple 的 iterator 转移给它内部变量完成。
同样地看一下 contains 方法,这个同样容易理解:如果待查变量为 null 则直接返回 false,否则逐个遍历看看是不是相等。
public final boolean contains(final Object value)
for (final Object val : this.valueList)
if (val == null)
if (value == null)
return true;
else
if (val.equals(value))
return true;
return false;
接下来看一下其中的 indexOf 方法,也就是找到数据对应的索引:
public final int indexOf(final Object value)
int i = 0;
for (final Object val : this.valueList)
if (val == null)
if (value == null)
return i;
else
if (val.equals(value))
return i;
i++;
return -1;
这个我认为不合理的地方就是最后的返回 -1 ,应该定义一个常量,NOT_FOUNT = -1 更加合适。其他的没有什么可以解释的。
类似地看一下 lastIndexOf ,这个只是倒过来遍历一次。
到目前为止还不知道成员变量 valueArray 的作用,看下源码发现,主要是用于Tuple转换为 Array 和 getValue 时使用(遍历链表时间复杂度为 O ( N ) O(N) O(N) 而此时根据索引读数据时间复杂度为 O ( 1 ) O(1) O(1))。
public final Object[] toArray()
return this.valueArray.clone();
public final Object getValue(final int pos)
if (pos >= getSize())
throw new IllegalArgumentException(
"Cannot retrieve position " + pos + " in " + this.getClass().getSimpleName() +
". Positions for this class start with 0 and end with " + (getSize() - 1));
return this.valueArray[pos];
子类以 Pair 为例
构造函数只提供了一个 ,即全参数构造函数
public Pair(
final A value0,
final B value1)
super(value0, value1);
this.val0 = value0;
this.val1 = value1;
内部变量 final A value1 和 final B value2 是 final 类型的,因此如果希望更新它们的值不能直接 set 而是需要重新 new Pair,当然在 Pair 类中已经提供了。
public <X> Pair<X,B> setAt0(final X value)
return new Pair<X,B>(
value, this.val1);
public <X> Pair<A,X> setAt1(final X value)
return new Pair<A,X>(
this.val0, value);
而其他的方法比较有意思的是从 Pair 到 Triplet 等等更高维度的,都有提供这些方法。方法同样是 return new Triplet … 这类的。
总结
作为读源码的开端,特别选了一个简单的、也挺好用的。希望能够帮到大家~~
Smileyan
2022.7.28 19:56
以上是关于一起读源码1. Java 中元组 Tuple的主要内容,如果未能解决你的问题,请参考以下文章