53
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaでTupleが欲しくなったときメモ

Last updated at Posted at 2017-09-03

Javaでもラムダ式やStream APIなど比較的モダンな機能が取り入れられ、処理結果を2つ以上の値として返したい場合が増えてきています。
その方法として一つとして思いつくのが、他言語ではよく用意されているTupleです。
ところが、Javaには標準APIとしてTupleが用意されているないため、ちょっと調べたときのメモです。

Tupleとは

タプル(tuple)

タプルとは、順序付けられた複数の要素で構成される組。もとは数学の概念だが、いくつかのプログラミング言語にはタプルという名称のデータ型が用意されている。

タプル型の仕様は言語によって異なるが、複数の異なる型のデータやオブジェクトなどを格納でき、配列のように各要素に通し番号(添字)が割り振られ、これによって要素を識別するようなデータ構造を表すことが多い。また、LISPなどの関数型言語では二分木の構造になっているデータ型をタプルという。

こちらはe-Wordsからの引用で、このあたりは言語や実装によっても違うのですが、ここで言うTupleは任意の数の要素、型をまとめる為のデータ構造です。

なぜ標準APIにTupleがないのか

Does Java SE 8 have Pairs or Tuples?

オラクルのJava、OpenJDK開発者の方の回答が参考になります。(一部抜粋と超要約)

Java SEでPair(Tuple)クラスを持つことが提案され、少なくとも1回は拒否されました。しかし、他のライブラリやアプリケーションで複数の実装が存在していて必要性は理解できます。ただし、Pairのような構造を標準APIとして提供すると、抽象化(クラス)を使わず、複雑なデータ構造をPairsやコレクションで表現したくなります。(Pair<List<String>,List<Pair<String,List<Boolean>>>>, Map<Double,List<Pair<QueryTuple,Map<StatType,Number>>>>)

また、命名規則の問題やStream APIのような環境では、オブジェクト用のPairだけでなくプリミティブとの組み合わせのPairが必要になります。(ObjIntPair, ObjLongPair, ObjDoublePair, IntObjPair, IntIntPair...)

などなど、将来的に実装の可能性はあるものの標準APIとして追加は決まっていないのが現状のようです。

ということで、他のパラダイムも含まれてるとは言え、オブジェクト指向言語のJavaでTupleが欲しくなったときは、適切な抽象化(クラス)をすることが現時点の方向性のようです。

ライブラリを使用する

Javaの方針とは言えそれでも欲しい場合もあると思います。
javafx.util.Pairを使うという方法もありますが、パッケージがjavafxだったり、Pairしか用意されていないなどもあり、外部のライブラリを使うのも手だと思います。

  • Commons Lang

    PairとTripleを提供。多くのシステムやライブラリで採用されている為、意図的に追加しなくても使用できる場合もある。
  • javatuples

    1〜10までのTupleを提供。基本的にTupleの為のライブラリのため余計なクラスの追加がない。
  • Reactor

    2〜8までのTupleを提供。Spring 5からは標準のdependencyとして追加される。
  • Javaslang

    0〜8までのTupleを提供
  • Functional Java

    0〜8までのTuple(P)を提供
  • jOOλ

    1〜16までのTupleを提供

比較的、関数指向の強いライブラリで提供されているケースが多いです。

注意が必要なのは、ライブラリによって、Tupleにもミュータブルなもとのイミュータブルなものがあると言うことです。
特にイミュータブルな性質のものは、Collectorのaccumulatorなどミュータブルな性質を想定しているAPIでは使用できないのできないので注意が必要です。
また、ライブラリによってはTuple以外のクラスも追加されるので安易に導入すると、管理が複雑になる可能性もあります。*1

実装する

ライブラリによる追加は楽な反面、課題*1も抱えているため機能性を求めない単純なTupleであれば、Lombokなどで簡単に実装してしまうという方法もあります。

@Data(staticConstructor = "of")
public class Pair<A, B> {
    private final A left;
    private final B right;
}

まとめ

ということで、JavaでTupleが欲しくなった場合には、

  1. クラスなどで表現できないか検討する
  2. 最小限の機能でよければ自作のTupleで代用する
  3. 本格的に使用するなら、ライブラリを検討する

と考えると良さそうです。

53
38
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?