我有很大的版本化文档流,按文档 ID 和版本排序。
例如Av1, Av2, Bv1, Cv1, Cv2
我必须将其转换为另一个 Stream,其记录按文档 ID 聚合。
A[v1, v2], B[v1], C[v1, V2]
这可以不使用 Collectors.groupBy()
来完成吗?我不想使用 groupBy()
因为它会在对它们进行分组之前将流中的所有项目加载到内存中。理论上,不需要将整个流加载到内存中,因为它是有序的。
最佳答案
这是我想出的解决方案:
Stream<Document> stream = Stream.of(
new Document("A", "v1"),
new Document("A", "v2"),
new Document("B", "v1"),
new Document("C", "v1"),
new Document("C", "v2")
);
Iterator<Document> iterator = stream.iterator();
Stream<GroupedDocument> result = Stream.generate(new Supplier<GroupedDocument>() {
Document lastDoc = null;
@Override
public GroupedDocument get() {
try {
Document doc = Optional.ofNullable(lastDoc).orElseGet(iterator::next);
String id = doc.getId();
GroupedDocument gd = new GroupedDocument(doc.getId());
gd.getVersions().add(doc.getVersion());
if (!iterator.hasNext()) {
return null;
}
while (iterator.hasNext() && (doc = iterator.next()).getId().equals(id)) {
gd.getVersions().add(doc.getVersion());
}
lastDoc = doc;
return gd;
} catch (NoSuchElementException ex) {
return null;
}
}
});
这是 Document
和 GroupedDocument
类:
class Document {
private String id;
private String version;
public Document(String id, String version) {
this.id = id;
this.version = version;
}
public String getId() {
return id;
}
public String getVersion() {
return version;
}
}
class GroupedDocument {
private String id;
private List<String> versions;
public GroupedDocument(String id) {
this.id = id;
versions = new ArrayList<>();
}
public String getId() {
return id;
}
public List<String> getVersions() {
return versions;
}
@Override
public String toString() {
return "GroupedDocument{" +
"id='" + id + '\'' +
", versions=" + versions +
'}';
}
}
请注意,生成的流是无限流。在所有组之后,将有无限数量的 null
。您可以在 Java 9 中使用 takeWhile
获取所有不为 null 的元素,或者查看此 post .
关于java - 合并 Java 流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55647767/