Apache CommonsコレクションOrderedMap
1. 概要
Apache Commons Collections libraryは、Javaコレクションフレームワークを補完する便利なクラスを提供します。
この記事では、java.util.Mapを拡張するインターフェースOrderedMapを確認します。
2. メーベン依存
最初に行う必要があるのは、pom.xmlにMaven依存関係を追加することです。
org.apache.commons
commons-collections4
4.1
ライブラリの最新バージョンはMaven Central repositoryにあります。
3. OrderedMapプロパティ
簡単に言えば、OrderedMapインターフェースを実装するマップは次のとおりです。
-
セットはソートされていませんが、キーのセットの順序を維持します
-
次の方法で両方向に反復できます:firstKey()とnextKey()、またはlastKey()とpreviousKey()
-
MapIteratorでトラバースできます(ライブラリによっても提供されます)
-
要素を検索、変更、削除、または置換するメソッドを提供します
4. OrderedMapの使用
テストクラスでランナーのOrderedMapとその年齢を設定しましょう。 ライブラリで提供されるOrderedMap実装の1つであるLinkedMapを使用します。
まず、マップをロードして値の順序を確認するために使用するランナーと年齢の配列を設定しましょう。
public class OrderMapUnitTest {
private String[] names = {"Emily", "Mathew", "Rose", "John", "Anna"};
private Integer[] ages = {37, 28, 40, 36, 21};
private LinkedMap runnersLinkedMap;
//...
}
それでは、マップを初期化しましょう。
@Before
public void createRunners() {
this.runnersLinkedMap = new LinkedMap<>();
for (int i = 0; i < RUNNERS_COUNT; i++) {
runners.put(this.names[i], this.ages[i]);
}
}
4.1. 順方向反復
フォワードイテレータがどのように使用されるかを見てみましょう。
@Test
public void givenALinkedMap_whenIteratedForwards_thenPreservesOrder() {
String name = this.runnersLinkedMap.firstKey();
int i = 0;
while (name != null) {
assertEquals(name, names[i]);
name = this.runnersLinkedMap.nextKey(name);
i++;
}
}
最後のキーに到達すると、メソッドnextKey()はnull値を返すことに注意してください。
4.2. 後方反復
最後のキーから始めて、繰り返してみましょう。
@Test
public void givenALinkedMap_whenIteratedBackwards_thenPreservesOrder() {
String name = this.runnersLinkedMap.lastKey();
int i = RUNNERS_COUNT - 1;
while (name != null) {
assertEquals(name, this.names[i]);
name = this.runnersLinkedMap.previousKey(name);
i--;
}
}
最初のキーに到達すると、previousKey()メソッドはnullを返します。
4.3. MapIteratorの例
次に、配列namesおよびagesで定義されているランナーの順序を保持する方法を示すために、use the mapIterator() method to obtain a MapIteratorを使用します。
@Test
public void givenALinkedMap_whenIteratedWithMapIterator_thenPreservesOrder() {
OrderedMapIterator runnersIterator
= this.runnersLinkedMap.mapIterator();
int i = 0;
while (runnersIterator.hasNext()) {
runnersIterator.next();
assertEquals(runnersIterator.getKey(), this.names[i]);
assertEquals(runnersIterator.getValue(), this.ages[i]);
i++;
}
}
4.4. 要素を削除する
最後に、an element can be removed by index or by objectがどのようになっているのかを確認しましょう。
@Test
public void givenALinkedMap_whenElementRemoved_thenSizeDecrease() {
LinkedMap lmap
= (LinkedMap) this.runnersLinkedMap;
Integer johnAge = lmap.remove("John");
assertEquals(johnAge, new Integer(36));
assertEquals(lmap.size(), RUNNERS_COUNT - 1);
Integer emilyAge = lmap.remove(0);
assertEquals(emilyAge, new Integer(37));
assertEquals(lmap.size(), RUNNERS_COUNT - 2);
}
5. 提供された実装
現在、ライブラリのバージョン4.1には、OrderedMapインターフェイスの2つの実装(ListOrderedMapとLinkedMap)があります。
ListOrderedMapは、java.util.Listを使用してキーセットの順序を追跡します。 これはOrderedMapのデコレータであり、静的メソッドListOrderedMap.decorate(Map map)を使用して任意のMapから作成できます。
LinkedMapはHashMapに基づいており、双方向反復およびOrderedMapインターフェイスの他のメソッドを許可することで改善されています。
Both implementations also provide three methods that are outside the OrderedMap interface:
-
asList() –マップの順序を保持するタイプList<K>(Kはキーのタイプ)のリストを取得します
-
get(int index) –インターフェイスで提供されるメソッドget(Object o)とは対照的に、位置indexで要素を取得します
-
indexOf(Object o) –順序付けられたマップ内のオブジェクトoのインデックスを取得します
OrderedMapをLinkedMapにキャストして、asList()メソッドを使用できます。
@Test
public void givenALinkedMap_whenConvertedToList_thenMatchesKeySet() {
LinkedMap lmap
= (LinkedMap) this.runnersLinkedMap;
List listKeys = new ArrayList<>();
listKeys.addAll(this.runnersLinkedMap.keySet());
List linkedMap = lmap.asList();
assertEquals(listKeys, linkedMap);
}
次に、LinkedMap実装のメソッドindexOf(Object o)およびget(int index)の機能を確認できます。
@Test
public void givenALinkedMap_whenSearchByIndexIsUsed_thenMatchesConstantArray() {
LinkedMap lmap
= (LinkedMap) this.runnersLinkedMap;
for (int i = 0; i < RUNNERS_COUNT; i++) {
String name = lmap.get(i);
assertEquals(name, this.names[i]);
assertEquals(lmap.indexOf(this.names[i]), i);
}
}
6. 結論
このクイックチュートリアルでは、OrderedMapインターフェースとその主要なメソッドおよび実装を確認しました。
詳細については、the JavaDoc of the Apache Commons Collections libraryを参照してください。
いつものように、この記事の完全なテストクラスには、LinkedMapとListOrderedMapの両方を使用した同様のテストケースが含まれており、GitHub projectからダウンロードできます。