One of the missing Streams API features is the "split" transform, for example, as defined in Clojure . Let's say I want to play the Hibernate fetch connection: I want to issue one SQL SELECT statement to get such objects from the result:
class Family { String surname; List<String> members; }
I release:
SELECT f.name, m.name FROM Family f JOIN Member m on m.family_id = f.id ORDER BY f.name
and I get a flat stream of records (f.name, m.name) . Now I need to convert it to a stream of Family objects, with a list of its members inside. Suppose I already have Stream<ResultRow> ; Now I need to convert it to Stream<List<ResultRow>> , and then act on it with a mapping transformation that turns it into Stream<Family> .
The semantics of the conversion are as follows: continue to compile the stream in List until the provided discriminator function continues to return the same value; as soon as the value changes, emit List as an element of the output stream and start collecting a new List .
I hope I can write such code (I already have a resultStream method):
Stream<ResultRow> dbStream = resultStream(queryBuilder.createQuery( "SELECT f.name, m.name" + " FROM Family f JOIN Member m on m.family_id = f.id" + " ORDER BY f.name")); Stream<List<ResultRow> partitioned = partitionBy(r -> r.string(0), dbStream); Stream<Family> = partitioned.map(rs -> { Family f = new Family(rs.get(0).string(0)); f.members = rs.stream().map(r -> r.string(1)).collect(toList()); return f; });
Of course, I expect the resulting stream to remain lazy (not materialized), because I want to be able to process the result set of any size without affecting any O (n) memory restrictions. Without this important requirement, I would be pleased with the provided collector groupingBy .
java java-8 java-stream
Marko Topolnik Feb 06 '15 at 10:12 2015-02-06 10:12
source share