ストリームを使用して、あまりエレガントでないコードをリファクタリングしようとしています。私は文字列とMyObjectsを含むHashMapを持っており、現在はそのようにforループを使用して、それを反復処理:私はIDのみを気にしているのでストリームを使用したグループ化に基づいて、コレクションで2つの異なる機能を実行するにはどうすればよいですか?
Map<String, MyObject> map = new HashMap<>();
Map<String, MyObject> objectsToAdd = new HashMap<>();
for(MyObject object : map.values()){
String idToAdd = object.getConnectedToId();
if(StringUtils.isEmpty(idToAdd) {
continue;
}
if(idToAdd.substring(0,1).equals("i")){ // connected to an ICS
MyObject newObject = service1.someMethod(idToAdd);
if(newObject != null) {
objectsToAdd.put(newObject.getId(), newObject);
}
} else if (idToAdd.substring(0,1).equals("d")){ // connected to a device
MyObject newObject = service2.someMethod(idToAdd);
if(newObject != null) {
objectsToAdd.put(newObject.getId(), newObject);
}
}
}
map.putAll(objectsToAdd);
、私が続く、IDのみを取得するにはマップの操作を使用して開始しました空のフィルタを削除するフィルタ操作
次の部分は私が問題を抱えています。
map.values().stream()
.map(myObject -> myObject.getConnectedToId()) // get a map of all the ids
.filter(StringUtils::isNotEmpty) // filter non empty ones
.collect(
Collectors.mapping(
MyObject::getId,
Collectors.toList())),
Collectors.groupingBy(
s -> s.substring(0,1));
このリンクストリームコレクターを使用して削減を手伝ってくれました:私はグループの項目は、IDの最初の文字に基づいて、私はこれで終わったが、ことができるように、私が試した最初のものは、コレクターgroupingBy操作を使用していましたStream Reduction
このコードには少なくとも次の2つの問題があります.1)収集はterminal operationで終了し、まだ完了していません.2)元のオブジェクトはまだ必要ですが、現在はconnectedToIdsのマップ。
Q1)IDの最初の文字に基づいてオブジェクトをグループ化できる中間操作はありますか?
Q2)コレクションをIDだけに縮小することなくこれを行うにはどうすればよいですか?
Q3)最後に、コレクションがグループ化されると(2つになります)、元のコードのように各グループで別々の機能を実行するにはどうすればよいですか?
最終解決(おかげで助けを& @Flownを@Holgerする)
Map<Character, Function<String, MyObejct>> methodMapping = new HashMap<>();
methodMapping.put('i', service1::method1);
methodMapping.put('d', service2::method2);
Map<String, MyObject> toAdd = map.values().stream().map(MyObject::getConnectedToId)
.filter(StringUtils::isNotEmpty)
.map(id -> methodMapping.getOrDefault(id.charAt(0), i -> null).apply(id))
.filter(Objects::nonNull)
.collect(Collectors.toMap(MyObject::getId, Function.identity(), (mo1, mo2) -> mo2));
map.putAll(toAdd);
同時変更例外を回避するために実行している間、それは一時的なマップ内のオブジェクト最初の記憶しておく必要がありますストリーム操作を完了したら、最後のマップに追加します。
私はマップのキーが 'MyObject'の' id'だとしますか?私。 – Flown
はい、HashMapのキーはMyObjectのIDです。わかりやすさのために質問にマイナーな編集を加えました。idToAddはオブジェクトのIDではなくmyObjectのconnectedToIdです。 – Kristina