LoginSignup
44
52

More than 5 years have passed since last update.

Java の Pair について考える

Last updated at Posted at 2016-01-08

背景

Java で Key と Value だけを持つデータが必要な場合は何を使いますか?Map でできないことはありません。が、あまりスマートなやり方でもありません。
Pair の実装が Java SE にない(わけではありませんが、あまり知られていません)ので、OSS を含めて調べてみました。

AbstractMap.SimpleEntry

実は 1.6 から標準に Pair の機能を提供する API がありました。Entry の実装です。名前が長ったらしいですね。

インスタンス作成

new AbstractMap.SimpleEntry(key, value)

キー・値の取り出し

Key は getKey() で、Value は getValue() で可能

値の変更

setValue メソッドで Value のみ変更可能

備考

AbstractMap には SimpleImmutableEntry というのもあります。こちらだと、setValue メソッドを実質無効にした、要素の変更が不可能な Entry を扱うことができます。setValue メソッドを呼び出すと UnsupportedOperationException が発生します。この実装はうれしいのでしょうか?

名前が長い件については、下記のようにラップしてやれば解決できます。

Pair.java
 public class Pair<K, V> extends AbstractMap.SimpleEntry<K, V> {
    /** serialVersionUID. */
    private static final long serialVersionUID = 6411527075103472113L;

    public Pair(final K key, final V value) {
        super(key, value);
    }
 }

テストコード

  1. Pair (AbstractMap.SimpleEntry)
  2. ImmutablePair (AbstractMap.SimpleImmutableEntry)

javafx.util.Pair

JavaFX 2.0 以降のライブラリに含まれている Pair の実装です。上記の SimpleEntry とほぼ同じ使い方が可能です。ただし値を入れ替えることはできません。

テストコード

Pair

Pair (Eclipse Collections)

Eclipse Collections は昨年のクリスマスプレゼントです。Key と Value で別々の型を使いたい時はこちらを使います。
swap メソッドで Key と Value の入れ替えができるのが面白いです。

インスタンス作成

Tuples.pair(key, value)

キー・値の取り出し

Key は getOne() で、Value は getTwo() で可能

値の変更

不可、そもそもメソッドが存在しません。間違って呼び出して Exception が発生することもありません。

なお、putというメソッドが存在します。これは Pair に値を設定するのではなく、引数で渡した Map に Pair が持つ Key と Value を入れる、というメソッドです。引数で渡した Map が unmodifiable だと Exception が発生します。

ほか

swap メソッドで key と value を入れ替えた Pair を取得できます。

テストコード

Pair (Eclipse Collections)

Twin (Eclipse Collections)

Key と Value で同じ型の場合はこちらを用います。

インスタンス作成

Tuples.twin(key, value)

キー・値の取り出し

Key は getOne() で、Value は getTwo() で可能

値の変更

不可、そもそもメソッドが存在しません。間違って呼び出して Exception が発生することもありません。

なお、putというメソッドが存在するが、これは Twin に値を設定するのではなく、引数で渡した Map に Twin が持つ Key と Value を入れる、というメソッドです。引数で渡した Map が unmodifiable だと Exception が発生します。

ほか

swap メソッドで key と value を入れ替えた Twin を取得できます。

テストコード

Twin

org.apache.commons.lang3.tuple.Pair

Apache Commons Collections に用意されています。インスタンスを作るのにファクトリメソッドを使わせたり、MutableかImmutableか選べたり、
値の取り出し方に幅を持たせてあったりと、丁寧な作りをしています。

インスタンス作成

  1. Pair.of(key, value)
  2. MutablePair.of(key, value)

キー・値の取り出し

Key は getKey() か getLeft() で、Value は getValue() か getRight() で可能

値の変更

MutablePair は setValue() メソッドにより値だけ変更可能

Pair ないし ImmutablePair は変更不可、setValue() メソッドをコールすると UnsupportedOperationException が発生します。

テストコード

  1. ImmutablePair
  2. MutablePair

比較表

実装 インスタンス作成 変更 値の取り出し
AbstractMap.SimpleEntry new getValue
AbstractMap.SimpleImmutableEntry new × getValue
javafx.util.Pair new × getValue
Eclipse Collections Pair Tuples.pair × getTwo
Eclipse Collections Twin Tuples.twin × getTwo
Apache Commons Collections MutablePair of getValue/getRight
Apache Commons Collections ImmutablePair of × getValue/getRight

まとめ

OSS の利用申請が面倒等の理由がなければ、Eclipse Collections か Apache Collections を使っておけばよさそうです。

リンク

GitHub Repository(pair_verification)

44
52
2

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
44
52