I agree that f1 and f2 are unnecessary. I also noticed that toBoth is a binary form of `collectingAndThen`:
public static Collector<T, ?, R> collectingAndThen( Collector<T, ?, U> downstream, Function<U, R> finisher); So what about `collectionToBothAndThen`? public static Collector<T, ?, R> collectingToBothAndThen( Collector<T, ?, U1> downstream1, Collector<T, ?, U2> downstream2, BiFunction<U1, U2, R> finisher); Another options: collecting2 collectingToBoth biCollecting 2018-06-19 14:43 GMT+07:00 Peter Levart <peter.lev...@gmail.com>: > > > On 06/19/18 02:38, John Rose wrote: > >> unzipping( >> Function<? super T, T1> f1, // defaults to identity >> Collector<? super T1, ?, R1> c1, >> Function<? super T, T2> f2, // defaults to identity >> Collector<? super T2, ?, R2> c2, >> BiFunction<? super R1, ? super R2, ? extends R> finisher) >> { >> return toBoth(mapping(f1, c1), mapping(f2, c2)); >> } >> > > You don't need these f1 and f2 as arguments, because we already have a > Collectors.mapping(f1, c1) combinator. So you can write: > > unzipping( > mapping(f1, c1), > mapping(f2, c2) > finisher > ) > > But then unzipping is not really "unzipping". > > What's wrong with my initial proposal of Collectors.toBoth()? > > We already have some toXxx() methods (toList, toSet, toCollection, toMap, > ...), so toBoth seems to me as a natural extension of that naming principle: > > toBoth( > toMap() > toList() > combiner > ) > > But I'm open to other naming suggestions. > > I would also call the 3rd parameter 'combiner' rather than 'finisher', > because finisher is known as particular function that is bound to the > particular Collector. And this 3rd argument is not the resulting > collector's finisher - it is just a part of it. The real finisher of the > resulting Collector is composed of that function and finishers of > underlying collectors. > > Regards, Peter > >