How to remove collection to a new stream from the middle of a java 8 stream?

I am working on Java 8 stream. And I need a 2 key group in a map. And then put these keys with their value into a new function.

Is there a way to skip Collector

and read it again?

graphs.stream()
    .map(AbstractBaseGraph::edgeSet)
    .flatMap(Collection::stream)
    .collect(Collectors.groupingBy(
        graph::getEdgeSource,
        Collectors.groupingBy(
            graph::getEdgeTarget,
            Collectors.counting()
        )
    ))
    .entrySet().stream()
    .forEach(startEntry ->
        startEntry.getValue().entrySet().stream()
            .forEach(endEntry ->
                graph.setEdgeWeight(
                    graph.addEdge(startEntry.getKey(), endEntry.getKey()),
                    endEntry.getValue() / strains
                )));

      

+3


source to share


1 answer


No, you must have some kind of intermediate data structure to accumulate counters. Depending on how your graph and edge classes are written, you might try to copy the abacus directly into the graph, but this will be less readable and more fragile.

Note that you can iterate over the intermediate map more accurately using Map#forEach

:

.forEach((source, targetToCount) -> 
    targetToCount.forEach((target, count) -> 
        graph.setEdgeWeight(graph.addEdge(source, target), count/strains)
    )
);

      



You can also collect counters in Map<List<Node>, Long>

instead Map<Node,Map<Node,Long>>

if you don't like the map-map approach:

graphs.stream()
    .map(AbstractBaseGraph::edgeSet)
    .flatMap(Collection::stream)
    .collect(groupingBy(
            edge -> Arrays.asList(
                graph.getEdgeSource(edge), 
                graph.getEdgeTarget(edge)
            ),
            counting()
    ))
    .forEach((nodes, count) -> 
        graph.setEdgeWeight(graph.addEdge(nodes.get(0), nodes.get(1)), count/strains)
    );

      

+3


source







All Articles