Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #33860
| From | Sebastian <news@seyweiler.dyndns.org> |
|---|---|
| Newsgroups | comp.lang.java.programmer |
| Subject | Re: stream filter twice |
| Date | 2016-02-22 00:13 +0100 |
| Organization | albasani.net |
| Message-ID | <nadgbe$mj$1@news.albasani.net> (permalink) |
| References | <04334e10-3bad-49dc-87d8-dc2f00f90807@googlegroups.com> <nabaej$1rfq$1@gioia.aioe.org> <ditn2rF45nnU1@mid.individual.net> |
Am 21.02.2016 12:58, schrieb Robert Klemme:
> On 21.02.2016 04:20, Arne Vajhøj wrote:
>
>> What is your goal? To produce easily understandable code? To save
>> a few micro seconds?
>
> That is really the first question to answer.
>
>> If the first then I think you current code is fine.
>>
>> If the second then you will need to be creative.
>>
>> Here is my attempt to be creative:
>
> I'm a bit more old fashioned, maybe that's why I do not find the
> advantage of streams so big here. I was also considering, we might not
> know how large the initial collection is. So the cost of iterating
> twice could be significant. So:
[code snipped]
I also assume that iterating twice would lead to unacceptable runtime.
The excellent library jool (https://github.com/jOOQ/jOOL) has what they
call "combining collectors". These are higher-order collectors that
apply a number of other collectors simultaneously to a stream and return
a tuple (in our case a pair) of results.
The collector to be applied would have to be a filtering collector. Java
8 does not have one, but there will be such a beast in Java 9, see here:
https://bugs.openjdk.java.net/browse/JDK-8144675
You can use these two elements to get a solution that is very similar to
Eric's idea of abusing groupingBy:
Collector<T, ?, Tuple2<List<T>, List<T>>> filtering = Tuple.collectors(
filtering(filter, toList()), filtering(anotherFilter, toList()));
Tuple2<List<T>,List<T>> filtered = mycoll.stream().collect(filtering);
return !filtered.v1.isEmpty() ? filtered.v1 : filtered.v2;
It shares with Eric's idea the advantages of being parallelizable, which
would be more difficult with Arne's and Robert's suggestions, and using
official or well-established libraries.
-- Sebastian
PS: I append the very bare bones of the necessary parts from JDK 9 and
the jool library (this will work, akthough the original code is a bit
different, please look at the sources cited above for the real thing).
public static <T, A, R> Collector<T, A, R> filtering(
Predicate<? super T> predicate,
Collector<? super T, A, R> downstream) {
return Collector.of(
downstream.supplier(),
(r, t) -> { if (predicate.test(t)) {
downstream.accumulator().accept(r, t);
}},
downstream.combiner(),
downstream.finisher());
}
public static interface Tuple {
static <T1, T2> Tuple2<T1, T2> tuple(T1 v1, T2 v2) {
return new Tuple2<>(v1, v2);
}
static <T, A1, A2, D1, D2>
Collector<T, Tuple2<A1, A2>, Tuple2<D1, D2>>
collectors(Collector<T, A1, D1> collector1,
Collector<T, A2, D2> collector2) {
return Collector.<T, Tuple2<A1, A2>, Tuple2<D1, D2>> of(
() -> tuple(
collector1.supplier().get(),
collector2.supplier().get()),
(a, t) -> {
collector1.accumulator().accept(a.v1, t);
collector2.accumulator().accept(a.v2, t);
} ,
(a1, a2) -> tuple(
collector1.combiner().apply(a1.v1, a2.v1),
collector2.combiner().apply(a1.v2, a2.v2)),
a -> tuple(
collector1.finisher().apply(a.v1),
collector2.finisher().apply(a.v2))
);
}
}
public static class Tuple2<T1, T2> implements Tuple {
public final T1 v1;
public final T2 v2;
public Tuple2(T1 v1, T2 v2) {
this.v1 = v1;
this.v2 = v2;
}
}
Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Find similar | Unroll thread
stream filter twice Philipp Kraus <philipp.kraus.flashpixx@gmail.com> - 2016-02-20 04:28 -0800
Re: stream filter twice Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-02-20 08:16 -0500
Re: stream filter twice Arne Vajhøj <arne@vajhoej.dk> - 2016-02-20 22:20 -0500
Re: stream filter twice Robert Klemme <shortcutter@googlemail.com> - 2016-02-21 12:58 +0100
Re: stream filter twice Arne Vajhøj <arne@vajhoej.dk> - 2016-02-21 09:52 -0500
Re: stream filter twice Sebastian <news@seyweiler.dyndns.org> - 2016-02-22 00:13 +0100
csiph-web