今月も先月に引き続き、今月もJava SE 7におけるコアライブラリの変更点について紹介していきます。
今回取りあげるのは次の4つのカテゴリです。
- コレクション
- Concurrency Utilities
- Logging API
- Management
これ以外にもjava.util.zipパッケージなどの変更がありますが、今回は省略させていただきました。
コレクション
コレクションでは、使いやすさやパフォーマンス向上が図られています。また、Concurrency Utilitiiesに関連したコレクションクラスが追加されていますが、それはConcurrency Utilitiesの章で紹介します。
空のイテレータ
Collectionsクラスに空のイテレータを返すメソッドが追加されました。
- emptyIterator
- emptyListIterator
- emptyEnumeration
空のイテレータは使い道がないように感じますが、コレクションクラスを自作した場合などに使えそうです。
イテレータのパフォーマンス向上
ArrayListクラスなどのクラスはLinkedListクラスなどに比べて、イテレーションが遅いというのが今までの通説でした。しかし、それもJava SE 7で覆されるようです。
例えば、ArrayListクラスで返されるIteratorインタフェースの実装クラスのnextメソッドは次のようになっています。
public E next() {
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
これに対し、Java SE 6でのnextメソッドはAbstractListクラスとArrayListクラスの両方にまたがって実装されています。見やすいように一緒に示しました。
private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
}
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
public E next() {
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
両方のコードを見比べてみると、すぐにわかるのが例外処理がなくなっているということです。Java SE 6ではRangeCheckメソッドでレンジのチェックをし、IndexOutOfBoundsException例外スローします。nextメソッドではこの例外をキャッチし、新たにNoSuchElement例外をスローしています。しかし、これは無駄な例外処理です。
また、Java SE 7はnextメソッドの中で、Java SE 6のgetメソッド、RangeCheckメソッドに相当する処理を行ってしまっています。これはメソッドをインライン展開したことになり、ここでも処理速度の向上を見込めます。
小さな変更ではありますが、このような変更を積み重ねることでパフォーマンスを向上させているのです。
これまではパフォーマンスが気になって拡張for文を使わなかった方たちにも、拡張for文が受け入れられていくのではないでしょうか。
ソートのパフォーマンス向上
CollectionsクラスとArraysクラスのsortメソッドもパフォーマンスが向上しました。
Javaでは、ソートのアルゴリズムとしてマージソートが採用されてきました。これに対し、Java SE 7ではDual-Pivot Quicksortに変更されています。
Dual-Pivot Quicksortのコードを実装したのは、 Vladimir Yaroslavskiy氏とJoshua Bloch氏です。
また、オブジェクトのソートにはTimsortが採用されています。こちらもJoshua Bloch氏が実装を行っています。
Dual-Pivot QuicksortはQuicksortを改良したソートで、Timsortはマージソートを改良したソートです。ここではソートのアルゴリズムの詳細は示しませんが、既存のソートに比べて2倍以上のパフォーマンスが向上しているようです。
ソートのアルゴリズムに関してはDual-Pivot Quicksort、およびWikipediaのTimsortの項を参照してください。