Map
オブジェクトの各エントリでマップ操作を実行しようとしています。
キーからプレフィックスを取り、値をあるタイプから別のタイプに変換する必要があります。私のコードはMap<String, String>
から構成エントリを取得し、Map<String, AttributeType>
に変換しています(AttributeType
は単なる情報を保持するクラスです。詳細はこの質問には関係ありません。)
Java 8 Streamsを使用して思いついたのは次のとおりです。
private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
int subLength = prefix.length();
return input.entrySet().stream().flatMap((Map.Entry<String, Object> e) -> {
HashMap<String, AttributeType> r = new HashMap<>();
r.put(e.getKey().substring(subLength), AttributeType.GetByName(e.getValue()));
return r.entrySet().stream();
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
インターフェースであるためMap.Entry
を構築できないと、単一のエントリMap
インスタンスが作成され、flatMap()
が使用されます。
より良い代替手段はありますか? forループを使用してこれを行う方が良いようです:
private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
Map<String, AttributeType> result = new HashMap<>();
int subLength = prefix.length();
for(Map.Entry<String, String> entry : input.entrySet()) {
result.put(entry.getKey().substring(subLength), AttributeType.GetByName( entry.getValue()));
}
return result;
}
このためにStream APIを避けるべきですか?または私が逃したより良い方法がありますか?
「古いforループ方法」をストリームに変換するだけです:
private Map<String, String> mapConfig(Map<String, Integer> input, String prefix) {
return input.entrySet().stream()
.collect(Collectors.toMap(
entry -> entry.getKey().substring(subLength),
entry -> AttributeType.GetByName(entry.getValue())));
}
質問は少し古いかもしれませんが、次のように単にAbstractMap.SimpleEntry <>を使用できます。
private Map<String, AttributeType> mapConfig(
Map<String, String> input, String prefix) {
int subLength = prefix.length();
return input.entrySet()
.stream()
.map(e -> new AbstractMap.SimpleEntry<>(
e.getKey().substring(subLength),
AttributeType.GetByName(e.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
他のペアのような値オブジェクトも機能します(ApacheCommonsペアタプルなど)。
Collectors APIの次の部分を作成してください。
<K, V> Collector<? super Map.Entry<K, V>, ?, Map<K, V>> toMap() {
return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue);
}
AbacusUtil による短いソリューションを次に示します。
Stream.of(input).toMap(e -> e.getKey().substring(subLength),
e -> AttributeType.GetByName(e.getValue()));