Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

274
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.

over 4 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 Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!