私は、JDBCの結果セットからインスタンスフラットデ正規化構造の着信オブジェクトを持っています。入ってくるオブジェクトは、私は、ネストされた子のコレクションを持つ親オブジェクトのリストにデータを変換するので、つまりオブジェクトグラフ、または正規化されたリスト、繰り返しデータのロードがあります、結果セットを反映しています。
入ってくるオブジェクトのクラスは、次のようになります。
class IncomingFlatItem {
String clientCode;
String clientName;
String emailAddress;
boolean emailHtml;
String reportCode;
String reportLanguage;
}
私は1つのクライアントのクライアントのための電子メールアドレスオブジェクトのリストを含むオブジェクト、およびレポートオブジェクトのリストに集約したいのですが、各クライアントのために複数のオブジェクトが含まれて入ってくるデータはそう。
だから、Clientオブジェクトは、次のようになります。
class Client {
String clientCode;
String clientName;
Set<EmailAddress> emailAddresses;
Set<Report> reports;
}
不思議なことに、私は、このために、既存の答えを見つけることができません。私は、ストリームをネストまたはストリームをチェーンで探していますが、私は最もエレガントなアプローチを見つけるしたいと私は間違いなくforループを回避したいです。
言及したすべての回答者に感謝Collectors.groupingBy()
。これは私が使用できるストリームを設定するための鍵でしたreduce()
。私は誤って私が使用することができるはずと信じていたreduce
ずに、問題を解決するために自分自身でgroupingBy
。
また、流暢なAPIを作成するための提案に感謝します。私が追加IncomingFlatItem.getEmailAddress()
とIncomingFlatItem.getReport()
流暢にからドメインオブジェクトをつかむIncomingFlatItem
-ともすでにネストされたその電子メールやレポートとの適切なドメインオブジェクトに全体の平らなアイテムを変換する方法:
public Client getClient() {
Client client = new Client();
client.setClientCode(clientCode);
client.setClientName(clientName);
client.setEmailAddresses(new ArrayList());
client.getEmailAddresses().add(this.getEmailAddress());
client.setReports(new ArrayList<>());
client.getReports().add(this.getReport());
return client;
}
私はまた、作成されたビジネスIDをベース.equals()
と.hashCode()
上の方法Client
、EmailAddress
およびReport
@SamuelPhilipによって推奨されているように
最後にドメインオブジェクトのために、私が作成.addReport(Report r)
し、.addEmail(EmailAddress e)
私の上Client
に子オブジェクトを追加し、クラス、Client
既に存在している場合ではありません。私は不時着Set
のためのコレクション型をList
ドメインモデルの標準であるためList
とSets
への変換の多くを意味しているだろうLists
。
だからと、ストリームコードとラムダは簡潔に見えます。
3つのステップがあります。
- マップ
IncomingFlatItems
へClients
- グループ
Clients
(に大きく依存クライアントによるマップへClient.equals()
) - 1に、各グループを減らします
Client
だから、これは機能的なアルゴリズムは次のとおりです。
List<Client> unflatten(List<IncomingFlatItem> flatItems) {
return flatItems.parallelStream()
.map(IncomingFlatItem::getClient)
.collect(Collectors.groupingByConcurrent(client -> client))
.entrySet().parallelStream()
.map(kvp -> kvp.getValue()
.stream()
.reduce(new Client(),
(client1, client2) -> {
client1.getReports()
.forEach(client2::addReport);
client1.getEmailAddresses()
.forEach(client2::addEmail);
return client2;
}))
.collect(Collectors.toList());
}
私は本当に理解する前に私が原因接線にオフに行くまでに長い時間がかかったreduce
-私が使用している間私のテストに合格した解決策を見つけた.stream()
が、完全に失敗し.parallelStream()
、ここで、したがって、その使用。私が使用していたCopyOnWriteArrayList
としても、それ以外の場合は、ランダムに倒れるでしょうConcurrentModificationExceptions