Агрегация данных в Java с использованием Collections Framework
Давайте рассмотрим проблему, прежде чем понять, что такое агрегация данных. Вам дается ежедневное потребление различных видов конфет сладкоежкой. Вход дается следующим образом.
Входная таблица:
Желаемая выходная таблица:
Выше приведены сводные данные. Теперь давайте разберемся, что такое агрегация данных?
Что такое агрегация данных?
Давайте разберемся на примере. Например, во входной таблице нам дано количество потребления различных видов конфет каждый день. Например, 28 августа 2022 года волонтер съел только 2 вида конфет: KitKat и Hershey's. Принимая во внимание, что 29 августа 2022 года волонтер съел 4 вида конфет: KitKat, Skittles, Alpen Liebe и Cadbury. Теперь нам также дается количество потребления. Например, самая съеденная конфета 29 августа 2022 года — это Cadbury. Принимая во внимание, что самой съеденной конфетой 28 августа 2022 года является KitKat. Однако, глядя на входную таблицу, мы не можем прямо ответить на следующий вопрос: какие конфеты самые популярные каждый день (или даже какие конфеты популярны в целом)?
Теперь, похоже, глядя на приведенную выше входную таблицу, мы можем ответить на вопрос, немедленно просматривая данные для совпадения дат. Но представьте, мы проводим опрос на месяц или квартал и теперь представляем еще 100 марок конфет, чтобы волонтер мог выбрать и съесть. Объем данных будет расти так быстро, что ответить на вопрос, просто взглянув на таблицу, будет практически невозможно. Существует даже другая возможность, когда данные разбросаны так, что данные, собранные за определенную дату, не отображаются последовательно, как показано в таблице ввода выше. В этом случае было бы еще сложнее напрямую смотреть на необработанные данные и отвечать.
Теперь, чтобы эффективно ответить на такие статистические вопросы, нам нужно организовать наши данные. Нам нужно классифицировать данные таким образом, чтобы, глядя на наши преобразованные данные, мы могли сразу же ответить на вопрос: какие конфеты более популярны каждый день? Например, глядя на данные после агрегирования, мы можем сказать, что 28 августа больше съедено KitKat, а 29 августа больше съедено Cadbury, просто взглянув на столбец под каждой датой. Не только это, но теперь мы также можем ответить на следующие вопросы:
- В какой день тот или иной вид конфет был съеден больше? (Глядя на ряд этих конфет)
- Какие конфеты популярны в целом? (Посмотрев на последнюю колонку «Всего»).
- В какой день было больше всего съедено конфет? (Глядя на последнюю строку «Всего»)
Например,
- Альпенлибе съели больше 27 и 29 августа.
- Kitkat, с другой стороны, является самой популярной конфетой.
- 29 августа оказалось днем, когда было съедено больше всего конфет. Может быть, мы можем объявить его «Днем конфет» .
Таким образом, мы испытываем преимущества агрегирования данных. Это метод обобщения данных, которые у нас есть, с целью их анализа, что делает необработанные данные более значимыми. Теперь мы находимся в более эффективном положении, чтобы ответить на вышеуказанные вопросы.
Постановка задачи
Нам необходимо преобразовать заданную входную таблицу потребления конфет в конкретную дату в агрегированную таблицу, в которой данные, собранные для каждой конфеты, должны быть объединены в значение за день. (См. выходную таблицу выше). Ниже приведен код для вышеуказанной проблемы:
Java
import java.util.*; class CandyConsumption { String date; String candy; int consumption; CandyConsumption(String date, String candy, int consumption){ this .date = date; this .candy = candy; this .consumption = consumption; } public String toString(){ StringBuffer str = new StringBuffer(); str.append( date ); str.append( " " ); str.append( String.valueOf( candy ) ); str.append( " " ); str.append( String.format( "%20s" , String.valueOf( consumption ) )); return str.toString() ; } public static void main(String[] args){ CandyConsumption[] cc = new CandyConsumption[ 9 ]; cc[ 0 ] = new CandyConsumption( "27-08-2022" , "skittles" , 20 ); cc[ 1 ] = new CandyConsumption( "27-08-2022" , "Kitkat" , 10 ); cc[ 2 ] = new CandyConsumption( "27-08-2022" , "Alpenliebe" , 20 ); cc[ 3 ] = new CandyConsumption( "28-08-2022" , "Kitkat" , 30 ); cc[ 4 ] = new CandyConsumption( "28-08-2022" , "Hershey"s" , 25 ); cc[ 5 ] = new CandyConsumption( "29-08-2022" , "Kitkat" , 30 ); cc[ 6 ] = new CandyConsumption( "29-08-2022" , "skittles" , 15 ); cc[ 7 ] = new CandyConsumption( "29-08-2022" , "Alpenliebe" , 20 ); cc[ 8 ] = new CandyConsumption( "29-08-2022" , "Cadbury" , 45 ); // Before Aggregation System.out.println( "Date Candy Consumption" ); for ( int i = 0 ; i < cc.length ; i++ ) { System.out.println(cc[i]) ; } System.out.println(); System.out.println(); System.out.println( "After Aggregation" ); System.out.println(); // After aggregation aggregate(cc); } public static void aggregate(CandyConsumption[] cc){ // Key => Candy Column (a/c to output table) | // Value = Another HashMap which maps each date // to the amount of candies consumed on that date HashMap<String, HashMap<String, Integer>> map = new HashMap<>(); // An arraylist to store unique dates ArrayList<String> dates = new ArrayList<>(); // HashMap to calculate total consumption datewise // Key => Date | Value => Total number of // candies consumed on that Date HashMap<String, Integer> consumptionDatewise = new HashMap<>(); // HashMap to calculate total consumption candywise // Key => Candy | Value => Total number of candies // consumed of that Candy type HashMap<String, Integer> consumptionCandywise = new HashMap<>(); // Populate map HashMap for ( int i= 0 ;i<cc.length;i++){ String date = cc[i].date; String candy = cc[i].candy; int consumption = cc[i].consumption; if (!map.containsKey(candy)){ map.put(candy, new HashMap<>()); } map.get(candy).put(date, consumption); // Let"s also populate the dates // arraylist simultaneously if (!dates.contains(date)){ dates.add(date); } // Let"s also populate the // consumptionDatewise hashmap if (!consumptionDatewise.containsKey(date)){ consumptionDatewise.put(date, 0 ); } consumptionDatewise.put(date, consumptionDatewise.getOrDefault(date, 0 ) + consumption); } // We have calculated total consumption datewise. // Let"s now calculate the total consumption // of each candy for (String candy : map.keySet()){ HashMap<String, Integer> candyVal = map.get(candy); int total = 0 ; for (String date : candyVal.keySet()){ total += candyVal.get(date); } consumptionCandywise.put(candy, total); } // We are done with all the necessary pre-processing. // Let"s start printing. // Let"s print the Header Line first System.out.print(String.format( "%-15s" , "Candy/Date" )); for (String date : dates){ System.out.print(date + " " ); } System.out.println( "Total" ); // Printing the rest of the table for (String candy : map.keySet()){ // System.out.printf("%-4s", candy); System.out.print(String.format( "%-15s" , candy)); HashMap<String, Integer> candyVal = map.get(candy); for ( int I = 0 ; I < dates.size(); i++){ if (!candyVal.containsKey(dates.get(i))) System.out.print( "0" + " " ); else System.out.print(candyVal.get(dates.get(i)) + " " ); } // Finally printing the total candywise System.out.println(consumptionCandywise.get(candy)); } // Printing the Total consumption datewise :- Last Line System.out.print(String.format( "%-15s" , "Total" )); int total = 0 ; for ( int i= 0 ;i<dates.size();i++){ int candiesOnDate = consumptionDatewise.get(dates.get(i)); total += candiesOnDate; System.out.print(candiesOnDate + " " ); } System.out.println(total); } } |
Выход:
Date Candy Consumption 27-08-2022 skittles 20 27-08-2022 Kitkat 10 27-08-2022 Alpenliebe 20 28-08-2022 Kitkat 30 28-08-2022 Hershey"s 25 29-08-2022 Kitkat 30 29-08-2022 skittles 15 29-08-2022 Alpenliebe 20 29-08-2022 Cadbury 45 After Aggregation Candy/Date 27-08-2022 28-08-2022 29-08-2022 Total Kitkat 10 30 30 70 Cadbury 0 0 45 45 Alpenliebe 20 0 20 40 Hershey"s 0 25 0 25 skittles 20 0 15 35 Total 50 55 110 215