• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
    • Questions
    • Teachers
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

180
Views
Coleccionista de Java tee una lista de entradas

Estoy tratando de implementar un colector simple, que toma una lista de colectores y simultáneamente recopila valores de formas ligeramente diferentes a las de una secuencia.

Es bastante similar a Collectors.teeing , pero se diferencia en que

  1. Recibe una lista de coleccionistas en lugar de solo dos
  2. Requiere que todos los coleccionistas produzcan un valor del mismo tipo

La firma de tipo que quiero tener es

 public static <T, R> Collector<T, ?, List<R>> list( final List<Collector<T, ?, R>> downstreamCollectors);

Una forma de crear un colector de este tipo sería emparejar recursivamente los colectores en T, así:

 public static <T, R> Collector<T, ?, List<R>> list( final List<Collector<T, ?, R>> downstreamCollectors) { return listrec( Collectors.collectingAndThen(downstreamCollectors.get(0), List::of), downstreamCollectors.stream().skip(1).toList()); } private static <T, R> Collector<T, ?, List<R>> listrec( final Collector<T, ?, List<R>> teedCollectors, final List<Collector<T, ?, R>> downstreamCollectors) { if (downstreamCollectors.size() == 0) { return teedCollectors; } else { return listrec( teeing( teedCollectors, downstreamCollectors.get(0), (l, s) -> Stream.concat(l.stream(), Stream.of(s)).toList()), downstreamCollectors.stream().skip(1).toList()); } }

Algo se siente un poco "apagado" con esta solución, así que estoy tratando de crear el colector yo mismo, algo como:

 public static <T, R> Collector<T, ?, List<R>> list2( final List<Collector<T, ?, R>> downstreamCollectors) { return Collector.of( () -> downstreamCollectors.stream().map(c -> c.supplier().get()).toList(), (accumulators, t) -> IntStream.range(0, downstreamCollectors.size()) .forEach( i -> downstreamCollectors.get(i).accumulator().accept(accumulators.get(i), t)), (accumulator1, accumulator2) -> IntStream.range(0, downstreamCollectors.size()) .mapToObj( i -> downstreamCollectors .get(i) .combiner() .apply(accumulator1.get(i), accumulator2.get(i))) .toList(), accumulators -> IntStream.range(0, downstreamCollectors.size()) .mapToObj(i -> downstreamCollectors.get(i).finisher().apply(accumulators.get(i))) .toList()); }

Debido al comodín ilimitado en el tipo de acumulador de los recopiladores posteriores, esto no se compila. Cambiando la firma de tipo a

 public static <T, A, R> Collector<? super T, ?, List<R>> list2( final List<Collector<? super T, A, R>> downstreamCollectors);

resuelve el problema, pero desafortunadamente hace que el método sea mucho menos útil ya que los recopiladores posteriores (como los recopiladores integrados de java.util.stream.Collectors ) normalmente tendrían un comodín ilimitado en el tipo de acumulador.

¿Hay otra forma de implementar esto, manteniendo el comodín en la firma del método?

Estoy usando OpenJDK 17.0.2.

about 3 years ago · Santiago Trujillo
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error