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

242
Views
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 answers
Answer question

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 Report

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 Report
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!