今回はマップ (java.util.Map) について。 『Groovyイン・アクション』Chapter4 とGroovy JDKを参考にしています(一覧)。
- 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 146回
- この商品を含むブログ (121件) を見る
Generics は Map<K, V> に対して呼び出しています。
インスタンス生成
def map1 = ['a':1, 'b':2, 'c':3]; assert map1 instanceof LinkedHashMap; def map2 = ['a':1, 'b':2, 'c':3] as TreeMap; assert map2 instanceof TreeMap; //***** 空マップ ***** def emptyMap = [:]; assert emptyMap instanceof LinkedHashMap; assert emptyMap.size() == 0; //***** 文字列キーに対する略記法 ***** assert [a:1, b:2, c:3] == ['a':1, 'b':2, 'c':3]; x = 'a'; assert ['x':1] == [x:1]; assert ['a':1] == [(x):1]; //***** マップ展開演算子 ***** def map3 = [*:[a:1, b:2], c:3, ]; assert map3 == [a:1, b:2, c:3]; inmap = [a:1, b:2]; def map4 = [*:inmap, c:3]; assert map4 == [a:1, b:2, c:3];
クラスを指定しない場合は java.util.LinkedHashMap のインスタンスが返されます。 このため、暗黙の内にエントリの順序は保存されます。
値・エントリの取得と設定:get & put
メソッド名 | 返り値 | メソッド名 (Generics) |
返り値 (Generics) |
|
---|---|---|---|---|
get(Object, Object) | Object | get(K, V) | V | |
getAt(Object) | Object | getAt(K) | V | |
find(Closure) | Entry | find(Closure<Entry<K, V>, boolean>) find(Closure<K, V, boolean>) |
Entry<K, V> | |
putAt(Object, Object) | Object | putAt(K, V) | V | |
putAll(Collection) | Map | putAll(Collection<Entry<K, V>>) | Map<K, V> | |
plus(Map) plus(Collection) |
Map | plus(Map<K, V>) plus(Collection<Entry<K, V>>) |
Map<K, V> | |
leftShift(Entry) | Map | leftShift(Entry<K, V>) | Map<K, V> |
map = [a:1, b:2, c:3]; //***** get(), getAt() ***** assert map.get('a') == 1; assert map.get('a', 0) == 1; assert map['a'] == 1; assert map.a == 1; assert map.get('d') == null; assert map['d'] == null; assert map.d == null; assert map.get('d', 0) == 0; // デフォルト値の指定(設定) assert map.d == 0; //***** find() ***** found = map.find { entry -> entry.value < 2 }; assert found.key == 'a'; assert found.value == 1; found = map.find { key, value -> value < 2 }; assert found.key == 'a'; assert found.value == 1; //***** putAt() ***** map['d'] = 1; assert map.d == 1; map.d = 2; assert map.d == 2; map = ['a.b':1, 'package':2]; assert map.'a.b' == 1; assert map.'package' == 2; //***** plus(), leftShift() ***** map1 = [a:1, b:2, c:3]; map2 = [d:4, e:5]; map = map1 + map2; assert map == [a:1, b:2, c:3, d:4, e:5]; map3 = [f:6, g:7]; map3.each { entry -> map << entry }; assert map == [a:1, b:2, c:3, d:4, e:5, f:6, g:7];
- キーをプロパティのように扱えます(map.a とか)。
- find() の引数のクロージャは、宣言した変数の個数によって渡される値が異なります。 これは下記で見ていく、クロージャを引数として取る他のメソッドについても同じです。
- 1個のときは、エントリ (Map$Entry) オブジェクト
- 2個のときは、順にキーと値
boolean を返すメソッド
メソッド名 | 返り値 | メソッド名 (Generics) |
返り値 (Generics) |
|
---|---|---|---|---|
asBoolean() | boolean | |||
any(Closure) | boolean | any(Closure<Entry<K, V>, boolean>) any(Closure<K, V, boolean>) |
boolean | |
every(Closure) | boolean | every(Closure<Entry<K, V>, boolean>) every(Closure<K, V, boolean>) |
boolean |
//***** asBoolean() ***** map = [a:1]; if(map) assert true; else assert false; map = [:]; if(map) assert false; else assert true; //***** any(), every() ***** map = [a:1, b:2, c:3]; assert map.any { entry -> entry.value > 2 }; assert map.every { entry -> entry.key < 'd' };
- Collection 型と同様に、Map#asBoolean() も空なら false、そうでないなら true を返します。
- any(), every() の引数のクロージャも、find() と同様に、引数を2つにすれば「キーと値」が渡されます。
コレクション、Map を返すメソッド
メソッド名 | 返り値 | メソッド名 (Generics) |
返り値 (Generics) |
|
---|---|---|---|---|
each(Closure) | Map | each(Closure<Entry<K, V>, void>) each(Cosure<K, V, void>) |
Map<K, V> | |
eachWithIndex(Closure) | Map | eachWithIndex(Closure<Entry<K, V, int>, void>) each(Cosure<K, V, int, void>) |
Map<K, V> | |
collect(Closure) | List | collect(Closure<Entry<K, V>, R>) collect(Closure<K, V, R>) |
List<R> | |
collect(Collection, Closure) | Collection | collect(Collection<R>, Closure<Entry<K, V>, R>) collect(Collection<R>, Closure<K, V, R>) |
Collection<R> | |
findAll(Closure) | Map | findAll(Closure<Entry<K, V>, boolean>) findAll(Closure<K, V, boolean>) |
Map<K, V> | |
subMap(Collection) | Map | subMap<Collection<K>> | Map<K, V> | |
sort(Closure) | Map | sort(Closure<Entry<K, V>, Comparable<?>>) sort(Closure<Entry<K, V>, Entry<K, V>, int>) |
Map<K, V> | |
withDefault(Closure) | Map | |||
groupBy(Closure) | Map | groupBy(Closure<Entry<K, V>, R>) groupBy(Closure<K, V, R>) |
Map<R, Map<K, V>> | |
groupEntriesBy(Closure) | Map | groupEntriesBy(Closure<Entry<K, V>, R>) groupEntriesBy(Closure<K, V, R>) |
Map<R, Entry<K, V>> | |
asImmutable() | Map | |||
asSynchronized() | Map |
map = [a:1, b:2, c:3]; //***** each(), eachWithIndex() ***** store = []; map.each { entry -> store << [entry.key, entry.value] }; assert store == [['a', 1], ['b', 2], ['c', 3]]; store = []; map.each { key, value -> store << [key, value] }; assert store == [['a', 1], ['b', 2], ['c', 3]]; store = []; map.eachWithIndex { entry, i -> store << [entry.key, entry.value, i] }; assert store == [['a', 1, 0], ['b', 2, 1], ['c', 3, 2]]; store = []; map.eachWithIndex { key, value, i -> store << [key, value, i] }; assert store == [['a', 1, 0], ['b', 2, 1], ['c', 3, 2]]; //***** collect() ***** result = map.collect { entry -> entry.value*2 }; assert result == [2, 4, 6]; result = map.collect { key, value -> value*value }; assert result == [1, 4, 9]; //***** findAll() ***** result = map.findAll { key, value -> value < 3 }; assert result == [a:1, b:2]; //***** subMap() ***** result = map.subMap(['a', 'b']); assert result == [a:1, b:2]; set = ['a', 'b'] as Set; result = map.subMap(set); assert result == [a:1, b:2]; //***** sort() ***** map = [a:5, b:4, c:3, d:2, e:1]; result = map.sort{ entry -> entry.value }; assert result == [e:1, d:2, c:3, b:4, a:5]; result = map.sort{ a, b -> a.value <=> b.value }; assert result == [e:1, d:2, c:3, b:4, a:5]; //***** withDefault() ***** //map = [a:1, b:2].withDefault{ k -> k.toCharacter().isLowerCase() ? 10 : -10 }; //expected = [a:1, b:2, c:10, D:-10]; //assert expected.every{ e -> e.value == map[e.key] }; // //constMap = [:].withDefault{ 42 }; //assert constMap.foo == 42; //assert constMap.size() == 1; //***** groupBy() ***** map = [a:1,b:2,c:3,d:4,e:5,f:6]; result = map.groupBy { it.value % 2 }; assert result == [0:[b:2, d:4, f:6], 1:[a:1, c:3, e:5]]; n = 0; 0.upto(result.size()-1){ i -> n += result[i].size() }; assert n == map.size(); //***** groupEntriesBy() ***** result = [a:1,b:2,c:3,d:4,e:5,f:6].groupEntriesBy { it.value % 2 }; assert result.toString() == '[1:[a=1, c=3, e=5], 0:[b=2, d=4, f=6]]'; assert result[0]*.key == ['b', 'd', 'f']; assert result[0]*.value == [2, 4, 6]; assert result[1]*.key == ['a', 'c', 'e']; assert result[1]*.value == [1, 3, 5]; n = 0; 0.upto(result.size()-1){ i -> n += result[i].size() }; assert n == map.size();
- each(), eachWithIndex() は通常返り値の Map は使わないでしょう。
- withDefault() は Groovy JDK に載っているサンプルが動かなかったので無視。
その他のメソッド
メソッド名 | 返り値 |
---|---|
asType(Class) | Object |
toMapString() | String |
spread() | SpreadMap |
toSpreadMap() | SpreadMap |
- SpreadMap?