Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

245
Vistas
Agregar valores en una lista por grupo múltiple y calcular el porcentaje de distribución en java 8

Tengo un caso de uso como este en el que necesito agregar valores en una lista por grupo múltiple pero luego calcular el porcentaje de distribución de cada uno de esos valores y crear una nueva lista.

Un ejemplo de lista de elementos:

 week1 source1 destination1 100 week1 source1 destination2 200 week1 source2 destination1 200 week1 source2 destination2 100 week2 source1 destination1 200 week2 source1 destination2 200

A partir de esto, quiero agrupar por semana y fuente y calcular la cantidad total y luego distribuir el porcentaje según la cantidad.

Como ejemplo, la cantidad total para la semana 1 desde la fuente 1 es 300, que va al destino 1 (100) y al destino 2 (200). Ahora el porcentaje de distribución es para la semana 1 del origen 1 al destino 1 es 33.33% y para la semana 1 del origen 1 al destino 2 al 66.66%

Por ejemplo, la salida sería:

 week1 source1 destination1 33.33% week1 source1 destination2 66.66% week1 source2 destination1 66.66% week1 source2 destination2 33.33% week2 source1 destination1 50% week2 source1 destination2 50%

¿Cómo puedo lograr este resultado usando flujos de Java 8?

Digamos que tengo una lista de estos objetos como Lista en el objeto "registros":

 public class Record { private String sourceNode; private String destinationNode; private String weekIndex; private String quantity; } Map<String, Map<String, List<Record>>> RecordsGroupByWeekAndSource = records.stream() .collect(Collectors.groupingBy(Record::getWeekIndex, Collectors.groupingBy(Record::getSourceNode)));

Esto me daría el grupo de artículos por semana y fuente. Pero tendré que iterar este mapa nuevamente para calcular la cantidad total en cada lista que reside dentro del mapa del objeto del mapa. Pero, ¿hay alguna manera de que pueda hacer este cálculo de porcentaje dentro de la colección groupingBy?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Puede crear un mapa con clave: week+source y valor como cantidad total. CollectingAndThen se puede utilizar el mapa y crear la lista resultante:

 // Value Objects: @Data @AllArgsConstructor class Records { String week, source, destination; int quantity; } @Data @AllArgsConstructor class Distribution { String week, source, destination; float pctDist; public Distribution(Records r) { this.week = r.getWeek(); this.source = r.getSource(); this.destination = r.getDestination(); } } import static java.util.stream.Collectors.*; public class SO { public static void main(String[] args) { List<Record> recordList = List.of( new Record("week1", "source1", "destination1", 100), new Record("week1", "source1", "destination2", 200), new Record("week1", "source2", "destination1", 200), new Record("week1", "source2", "destination2", 100), new Record("week2", "source1", "destination1", 200), new Record("week2", "source1", "destination2", 200)); Function<Map<String, Integer>, List<Distribution>> distExtractor = totalQuantityMap -> recordList.stream().map(r -> getDistribution(r,totalQuantityMap)).collect(toList()); List<Distribution> result = recordList.stream().collect(collectingAndThen(groupingBy(r -> r.getWeek() + r.getSource(), summingInt(Record::getQuantity)), distExtractor)); // print the result result.forEach((rec) -> System.out.println(rec.week + "\t" + rec.source + "\t" + rec.destination + "\t" + rec.pctDist)); } private static Distribution getDistribution(Record r, Map<String, Integer> weekAndSourceToTotalQuantityMap) { int total = weekAndSourceToTotalQuantityMap.get(r.getWeek() + r.getSource()); float pctDist = (r.getQuantity() * 100) / total; var dist = new Distribution(r); dist.setPctDist(pctDist); return dist; } }

Producción:

 // Precision can be worked upon in getDistribution method week1 source1 destination1 33.0 week1 source1 destination2 66.0 week1 source2 destination1 66.0 week1 source2 destination2 33.0 week2 source1 destination1 50.0 week2 source1 destination2 50.0
over 4 years ago · Santiago Trujillo Denunciar

0

Puedes lograrlo usando stream dos veces:

  1. En la primera colección, puede agrupar por y hacer suma
  2. Transmita sus registros nuevamente y use el resultado de la suma del primer paso para calcular el porcentaje

Código de muestra:

 import java.util.*; import java.util.stream.*; class Record { public String week; public String source; public String destination; public Integer qty; Record(String week, String source, String destination, Integer qty) { this.week = week; this.source = source; this.destination = destination; this.qty = qty; } } public class Main { public static void main(String[] args) { List<Record> records = new ArrayList<>(); records.add(new Record("w1", "hyd", "kur", 10)); records.add(new Record("w1", "hyd", "gwd", 20)); records.add(new Record("w2", "hyd", "kur", 40)); records.add(new Record("w2", "hyd", "gwd", 10)); Map<String, Map<String, Integer>> sums = records .stream() .collect(Collectors.groupingBy(rec -> rec.week, Collectors.groupingBy(rec -> rec.source, Collectors.summingInt(rec->rec.qty)))); records = records .stream() .map(rec -> { rec.qty = rec.qty*100 / sums.get(rec.week).get(rec.source); return rec; }).collect(Collectors.toList()); records.forEach((rec)->System.out.println(rec.week+"\t"+rec.source+"\t"+rec.destination+"\t"+rec.qty)); } }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda