Guavaは、Maps.newHashMap()
などのJava型の優れたファクトリメソッドを提供します。
しかし、Java Mapsのビルダーもありますか?
HashMap<String,Integer> m = Maps.BuildHashMap.
put("a",1).
put("b",2).
build();
Java 9 Map
インターフェイスには以下が含まれているため:
Map.of(k1,v1, k2,v2, ..)
Map.ofEntries(Map.entry(k1,v1), Map.entry(k2,v2), ..)
。これらのファクトリメソッドの制限は次のとおりです。
null
sをキーおよび/または値として保持できません(nullを保存する必要がある場合は、他の答えを見てください)immutableマップを作成します-mutableマップが必要な場合は、copy- HashMapのような選択された可変マップのコンストラクターで、そこにMap.of(..)
のような結果を渡します
Map<Integer, String> map = new HashMap<>( Map.of(1,"a", 2,"b", 3,"c") );
HashMapにはそのようなものはありませんが、ビルダーでImmutableMapを作成できます。
final Map<String, Integer> m = ImmutableMap.<String, Integer>builder().
put("a", 1).
put("b", 2).
build();
また、可変マップが必要な場合は、HashMapコンストラクターにフィードするだけです。
final Map<String, Integer> m = Maps.newHashMap(
ImmutableMap.<String, Integer>builder().
put("a", 1).
put("b", 2).
build());
完全なビルダーではありませんが、イニシャライザーを使用します。
Map<String, String> map = new HashMap<String, String>() {{
put("a", "1");
put("b", "2");
}};
これは受け入れられた答えに似ていますが、私の見解では少し簡潔です:
ImmutableMap.of("key1", val1, "key2", val2, "key3", val3);
上記の方法にはいくつかのバリエーションがあり、静的で不変の不変マップを作成するのに最適です。
単純なマップビルダーを記述するのは簡単です。
public class Maps {
public static <Q,W> MapWrapper<Q,W> map(Q q, W w) {
return new MapWrapper<Q, W>(q, w);
}
public static final class MapWrapper<Q,W> {
private final HashMap<Q,W> map;
public MapWrapper(Q q, W w) {
map = new HashMap<Q, W>();
map.put(q, w);
}
public MapWrapper<Q,W> map(Q q, W w) {
map.put(q, w);
return this;
}
public Map<Q,W> getMap() {
return map;
}
}
public static void main(String[] args) {
Map<String, Integer> map = Maps.map("one", 1).map("two", 2).map("three", 3).getMap();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
これは非常にシンプルなものです...
public class FluentHashMap<K, V> extends Java.util.HashMap<K, V> {
public FluentHashMap<K, V> with(K key, V value) {
put(key, value);
return this;
}
public static <K, V> FluentHashMap<K, V> map(K key, V value) {
return new FluentHashMap<K, V>().with(key, value);
}
}
それから
import static FluentHashMap.map;
HashMap<String, Integer> m = map("a", 1).with("b", 2);
https://Gist.github.com/culmat/a3bcc646fa4401641ac6eb01f3719065 を参照してください
次を使用できます。
HashMap<String,Integer> m = Maps.newHashMap(
ImmutableMap.of("a",1,"b",2)
);
それほど上品で読みやすいものではありませんが、機能します。
HashMap
は変更可能です。ビルダーは必要ありません。
Map<String, Integer> map = Maps.newHashMap();
map.put("a", 1);
map.put("b", 2);
ここに私が書いたものがあります
import Java.util.Collections;
import Java.util.HashMap;
import Java.util.Map;
import Java.util.function.Supplier;
public class MapBuilder<K, V> {
private final Map<K, V> map;
/**
* Create a HashMap builder
*/
public MapBuilder() {
map = new HashMap<>();
}
/**
* Create a HashMap builder
* @param initialCapacity
*/
public MapBuilder(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
/**
* Create a Map builder
* @param mapFactory
*/
public MapBuilder(Supplier<Map<K, V>> mapFactory) {
map = mapFactory.get();
}
public MapBuilder<K, V> put(K key, V value) {
map.put(key, value);
return this;
}
public Map<K, V> build() {
return map;
}
/**
* Returns an unmodifiable Map. Strictly speaking, the Map is not immutable because any code with a reference to
* the builder could mutate it.
*
* @return
*/
public Map<K, V> buildUnmodifiable() {
return Collections.unmodifiableMap(map);
}
}
次のように使用します。
Map<String, Object> map = new MapBuilder<String, Object>(LinkedHashMap::new)
.put("event_type", newEvent.getType())
.put("app_package_name", newEvent.getPackageName())
.put("activity", newEvent.getActivity())
.build();
これは、特にテストフィクスチャのセットアップ中に、私が常に望んでいたものです。最後に、任意のMap実装を構築できるシンプルな流なビルダーを作成することにしました- https://Gist.github.com/samshu/b471f5a2925fa9d9b718795d8bbdfe42#file-mapbuilder-Java
/**
* @param mapClass Any {@link Map} implementation type. e.g., HashMap.class
*/
public static <K, V> MapBuilder<K, V> builder(@SuppressWarnings("rawtypes") Class<? extends Map> mapClass)
throws InstantiationException,
IllegalAccessException {
return new MapBuilder<K, V>(mapClass);
}
public MapBuilder<K, V> put(K key, V value) {
map.put(key, value);
return this;
}
public Map<K, V> build() {
return map;
}
しばらく前に同様の要件がありました。グアバとは何の関係もありませんが、流likeなビルダーを使用してMap
をきれいに構築できるように、このようなことができます。
Mapを拡張する基本クラスを作成します。
public class FluentHashMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 4857340227048063855L;
public FluentHashMap() {}
public FluentHashMap<K, V> delete(Object key) {
this.remove(key);
return this;
}
}
次に、ニーズに合ったメソッドで流れるようなビルダーを作成します。
public class ValueMap extends FluentHashMap<String, Object> {
private static final long serialVersionUID = 1L;
public ValueMap() {}
public ValueMap withValue(String key, String val) {
super.put(key, val);
return this;
}
... Add withXYZ to suit...
}
その後、次のように実装できます。
ValueMap map = new ValueMap()
.withValue("key 1", "value 1")
.withValue("key 2", "value 2")
.withValue("key 3", "value 3")