Replace RowOperation.initialValue() and rowAggregator() by collect(Collector)

Lukas Eder lukas.eder at gmail.com
Wed Oct 25 14:17:54 UTC 2017


In this email, I will make two suggestions:

- Replacing initialValue() and rowAggregator() by collect(Collector)
- Improving the API to avoid the need for unidiomatic type witnesses

While playing around with the ADBA API, it struck me that the
RowOperation.initialValue() and rowAggregator() methods are not as
versatile as they could be. In particular, the mechanism reminded me of the
java.util.stream.Collector API where:

- RowOperation.initialValue() corresponds to Collector.supplier()
- RowOperation.rowAggregator() corresponds to Collector.accumulator()

And these two Collector methods don't have any correspondence in ADBA:

- Collector.combiner()
- Collector.finisher()

If we think of this "row aggregation" as an act of collecting all rows into
a target type, we might be able to find some more interesting features
where the Stream API and the new ADBA API can work together, even if ADBA
is asynchronous, push-oriented and Stream is synchronous, pull-oriented.

So, we could have: <A, R> RowOperation<R> collect(Collector<? super Row, A,
R>)

Note that I made this method suggestion generic as one thing that has
always bothered me in the examples were the not-so-idiomatic type witnesses
in examples like this one:

conn
    .<List<Integer>>rowOperation(sql)
    .set("target", 42, JdbcType.NUMERIC)
    .initialValue( () -> new ArrayList<>() )
    .rowAggregator( (list, row) -> {
        list.add(row.get("id", Integer.class));
        return list;
    } )
    .submit();

We could have, instead:

conn
    .rowOperation(sql)
    .set("target", 42, JdbcType.NUMERIC)
    .collect(Collector.of(
        () -> new ArrayList<Integer>(),
        (list, row) -> { ... }, // unchanged
        (list1, list2) -> { ... }
    ))
    .submit();

I understand that there isn't a complete match between the two paradigms.
In particular, the Collector.combiner() doesn't make much sense in the
absence of parallelism, but the Collector.finisher() could be quite useful
in some situations where the intermediate, mutable accumulator is something
like int[], i.e. not a type that we want to return to the calling operation.

Thoughts?


More information about the jdbc-spec-discuss mailing list