java - 合并 Java 流

标签 java java-stream collectors

我有很大的版本化文档流,按文档 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;
            }
        }
    });

这是 DocumentGroupedDocument 类:

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/

相关文章:

Java错误: first type: double,第二种类型:字符串

java - 非托管扩展 TransactionEventHandler Neo4j

java - Java 8 Stream 中的 forEach 与 forEachOrdered

java - 如何从文件系统中获取文件属性流?

Java groupingBy : sum multiple fields

Java 流 : Replacing groupingBy and reducing by toMap

java - 确定使用了哪种 DateTimePattern 模式 joda

java - 获取验证码 session 的图像

java - 避免使用 Java 流进行多线程处理

Java 8 FlatMap - 在嵌套表单中添加项目并使用 FlatMap 检索对象