2.7. java.util.Collection。データ集合の祖先インタフェース。

Collectionはデータ集合を扱うクラスが実現するインタフェースになっています。

ですので、集合を扱い系の以下のようなクラスはこれを実現しています。

ArrayList、HashListなど。

Collectionには集合を扱うのに必須なメソッドが定義※されていますので、これから見ていきたいと思います。

※:Collectionはインタフェースなので、基本的にはメソッドの実装はありません。実装は、子クラスが実現します。

※:こういう実装のないメソッドを抽象メソッドと言います。

2.7.1. クラス図へ変換

では、早速クラス図にしてみましょう。

UML変換くんを実行。

> touml .\java\util\Collection.java -o d:\temp\

> touml .\java\lang\Iterable.java -o d:\temp\

※java1.8コード

※「-o d:temp」はクラス図の出力先です。

2.7.1.1. パッケージ図

../_images/java.util.Collection.image001.jpg

パッケージ図はこれです。

Collectionはutil内にあり、関連するpackageはこんな感じでした。

2.7.2. 継承を眺めてみる

2.7.2.1. Collection。ターゲットのクラス

../_images/java.util.Collection.image002.jpg

2.7.2.1.1. Iterableインタフェースを継承しています。

Iterableインタフェースはイテレーター(iterator)を処理する機能を持つクラスが実現するインタフェースになります。

Collectionは要素の集まりを扱いますので、イテレーターが必要になります。

※iterator:反復子、繰り返し処理に使うもの(= iterate:繰り返す +or:使うもの)

2.7.2.2. Iterable。親のインタフェース

../_images/java.util.Collection.image003.jpg

これは、何も継承していないのでこれで最後です。

2.7.3. フィールドを眺めてみる。

../_images/java.util.Collection.image004.jpg

Collectionにフィールドはありませんでした。

2.7.4. メソッドを眺めてみる。

2.7.4.1. Collection

2.7.4.1.1. size

~size():int
~isEmpty():boolean

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

seizeは集合の要素の数を返し、isEmptyは集合の要素が空かどうかを返します。

2.7.4.1.2. contains

~contains(o:Object):boolean

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

引数oにセットされた要素が集合内にあるかどうかをチェックして結果を返します。

2.7.4.1.3. iterator

~iterator():Iterator<E>

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

イテレーターを返します。

iterator :繰り返し処理に使うもの、反復子。(iterate:繰り返す +or:使うもの)

2.7.4.1.4. toArray

~toArray():Object[]<T>
~toArray(a:T[]):T

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

集合を配列で返します。

2.7.4.1.5. add

~add(e:E):boolean

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

末尾に引数E(集合の要素)を挿入します。

2.7.4.1.6. remove

~remove(o:Object):boolean

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

引数で指定したoを集合から削除します。

2.7.4.1.7. containsAll

~containsAll(c:Collection<?>):boolean

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

引数cの集合が内部の集合にあるかチェックします。

2.7.4.1.8. addAll

~addAll(c:Collection<?extends E>):boolean

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

引数の集合cを内部配列に追加します。

2.7.4.1.9. removeAll

~removeAll(c:Collection<?>):boolean
~retainAll(c:Collection<?>):boolean
~clear():void

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

removeAllは引数cの集合を内部配列からすべて削除します。

retainAllは逆に、引数cの集合以外を内部配列からすべて削除します。

clearは、集合をすべて削除します。

2.7.4.1.10. removeIf

+removeAll(c:Collection<?>):boolean

引数cの集合を内部配列からすべて削除しています。

2.7.4.1.11. retainAll

~removeIf(filter:Predicate<?super E>):boolean

これは、defaultメソッドですので、処理が実装されています。

※defaultメソッドはjava1.8から追加された機能で、インタフェースに実装を書けます。

引数Eでオーバーライドした処理の内容を元に、集合から要素を削除します。

引数のfilter:Predicate<?super E>は関数型のインタフェースです。

Predicateのtestメソッドをオーバーライドして要素をチェックする処理を書きます。

※boolean test(T t);

2.7.4.1.12. equals

~equals(o:Object):boolean
~hashCode():int

抽象メソッドなので実装はありません。子クラスがオーバーライドします。

equalsは自分と引数oが同じかどうかチェックします。

hashCodeメソッドもチェックに利用します。例o.hashCode() == this.hashCode()

ちなみに、hashCodeは自インスタンスのハッシュ値を返します。

hashCodeは「hash:切り刻んだ+Code:コード」で、対象を切り刻んでそこから代表値を作り出しコード(数値)にしたものです。

※ハッシュ処理はいろいろなものがあるので調べてみると面白いと思います。

2.7.4.1.13. spliterator

~spliterator():Spliterator<E>

これは、defaultメソッドですので、処理が実装されています。

※defaultメソッドはjava1.8から追加された機能で、インタフェースに実装を書けます。

イテレーターの一種である、スプリッテレーターを返します。

Spliteratorsクラスのstaticメソッドを使って次のようにスプリッテレーターを作成して返却します。

「return Spliterators.spliterator(this, 0)」

※Spliteratorsクラスは、Spliterator関連の実装処理をまとめたもので、Spliteratorなどで使われています。

イテレーターの一種です。イテレーターが扱う集合を簡単に分(split)けられます。分割したものを並列処理したりするときに便利です。

2.7.4.1.14. stream

~stream():Stream<E>
~parallelStream():Stream<E>

これは、defaultメソッドですので、処理が実装されています。

Streamを返します。

※内部では、StreamSupportクラスのstaticメソッドを呼んでいます。

※stream()
※ return StreamSupport.stream(spliterator(), false);
※parallelStream()
※ return StreamSupport.stream(spliterator(), true);

2.7.5. まとめ

Collectionは集合を扱うクラスのインタフェースです。

集合クラスたち(ArrayList、HashList)はこれを実現しています。

調査していて面白かったのは、defaultメソッド内では、Spliterators、StreamSupportクラスにstaticメソッドを使っていたことです。

実処理を別クラスのstaticメソッドにすべて任せてしまうという実装方法もありなのですね。