gpt4 book ai didi

java - 使用Java 8 Streams完成消除循环

转载 作者:行者123 更新时间:2023-12-02 22:35:07 24 4
gpt4 key购买 nike

我有一个需要根据特定条件进行映射的文档对象列表。有一个实用函数,可以接受任意 2 种文档类型,并确定它们是否匹配多个标准,例如文档类型、它们是否共享任何作者等。该代码可以工作,但我想使用 Java Streams 来解决它如果可能的话。

我目前使用以下代码解决了这个问题:

  class Document{
private String genre;
private List<Author> authors;
private String isbn;
private boolean paperBack;
...
}

我还使用了一个库实用程序,该实用程序具有一个在给定一系列匹配条件和一对文档的情况下返回 true 的函数。它只是返回一个 boolean 值。

   boolean matchesOnCriteria(Document doc1, Document doc2, Criteria criteria){
...
}

这是用于查找符合所提供条件的书籍的匹配代码

     DocumentUtils utils = DocumentUitls.instance();
Criteria userCriteria = ...
List<Pair> matches = new ArrayList<>();

List<Document> documents = entityManager.findBy(.....);

for(Document doc1 : documents){
for(Documents doc2 : documents){
if(!doc1.equals(doc2){
if (utils.matchesOnCriteria(doc1,doc2, userCriteria)) {
Pair<Document> p = new Pair(doc1,doc2);
if(!matches.contains(p)){
matches.add(p);
}
}
}
}
}
}

如何使用 Streams 执行此操作?

最佳答案

使用 Steam::reduce 的以下解决方案的想法很简单:

  1. 将合格的文档对分组到 Map<Document, List<Document>>具有所有可能的可接受的组合。假设奇数和偶数文档是成对的:

    D1=[D3, D5], D2=[D4], D3=[D1, D5], D4=[D2], D5[D1, D3]  // dont mind the duplicates 
  2. 使用 Stream::reduce您可以通过以下步骤实现:

    • 将条目转换为 Pair<> ,

      D1-D3, D1-D5, D2-D4, D3-D1, D1-D5, D4-D2, D5-D1, D5-D3
    • 将这些项目保存到 Set保证相等的对出现一次( D1-D3 = D3-D1 )。条件Pair必须覆盖 Object::equalsObject:hashCode并根据现有的两个文件实现平等。

      D1-D3, D1-D5, D3-D5, D2-D4
    • 将特定集合减少(合并)为单个集合 Set<Pair<Document>> .

Map<Document, List<Document>> map = documents.stream()
.collect(Collectors.toMap( // Collected to Map<Document, List<Document>>
Function.identity(), // Document is the key
d1 -> documents.stream() // Value are the qualified documents
.filter(d2 -> !d1.equals(d2) &&
utils.matchesOnCriteria(d1,d2, userCriteria)
.collect(Collectors.toList()))); // ... as List<Document>

Set<Pair<Document>> matches = map.entrySet().stream().reduce( // Reduce the Entry<Dokument, List<Document>>
new HashSet<>(), // ... to Set<Pair<>>
(set, e) -> {
set.addAll(e.getValue().stream() // ... where is
.map(v -> new Pair<Document>(e.getKey(), v)) // ... the Pair of qualified documents
.collect(Collectors.toSet()));
return set;
},
(left, right) -> { left.addAll(right); return left; }); // Merge operation

条件!matches.contains(p)是多余的,有更好的方法来确保不同的值。要么使用 Stream::distinct 或收集流至Set这是一个无序的不同集合。

了解更多信息 Baeldung's: remove all duplicates .

关于java - 使用Java 8 Streams完成消除循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59760455/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com