Как найти повторяющиеся значения с подсчетами и общим количеством повторяющихся значений в arraylist

#java #string #arraylist

Вопрос:

У меня есть список данных с количеством, я хочу разделить повторяющиеся данные с этим количеством и этой общей суммой.

 ArrayList<String> al=new ArrayList<String>();
al.add("aa-10.00");
al.add("bb-15.00");
al.add("aa-20.00");
al.add("aa-30.00");
al.add("bb-10.00");

Output data amount count
        aa  60.00    3
        bb  25.00    2
 

Комментарии:

1. Что вы пробовали до сих пор?

Ответ №1:

Начиная с выпуска Java 8 в марте 2014 года, Java предоставляет Stream API, который позволяет группировать коллекции по элементам и собирать некоторые статистические данные.

Итак, входные строки должны быть разделены на части: имя и сумма, разделенные тире - , сгруппированы по имени строки, и статистика должна быть собрана для double суммы.

Используя Collection::stream , String::split , Collectors.groupingBy (с поставщиком и нижестоящим сборщиком), Collectors.summarizingDouble DoubleSummaryStatistics можно реализовать следующее решение:

 List<String> al = Arrays.asList(
    "aa-10.00", "bb-15.00", "aa-20.00", "aa-30.00", "bb-10.00"
);

Map<String, DoubleSummaryStatistics> stats = al
    .stream()
    .map(s -> s.split("-")) // Stream<String[]>
    .collect(Collectors.groupingBy(
        arr -> arr[0],
        LinkedHashMap::new,
        Collectors.summarizingDouble(arr -> Double.parseDouble(arr[1]))
    ));

System.out.println("data  amount  count");
stats.forEach((name, stat) -> System.out.printf("%4s  %6.2f  =%n", 
    name, stat.getSum(), stat.getCount()
));
 

Вывод:

 data  amount  count
  aa   60.00    3
  bb   25.00    2
 

LinkedHashMap гарантирует, что элементы отображаются в порядке вставки (как они появились во входном списке).

Ответ №2:

Идеи для решения этой проблемы заключаются в следующем:

  1. Разделите каждую символьную строку на имя и значение.
  2. Соберите статистику по каждой символьной строке. Суммируйте и подсчитайте символы с одинаковым именем.
  3. Сохраните результат на карте.
  4. Выведите результат статистики.
 ArrayList<String> al=new ArrayList<>();
al.add("aa-10.00");
al.add("bb-15.00");
al.add("aa-20.00");
al.add("aa-30.00");
al.add("bb-10.00");

// Map<data name such as "aa", Pair<sum, count> >
Map<String, Pair<Double, Integer>> result = new HashMap<>();
al.forEach(record -> {
    // split data by "-", and split aa-10.00 to "aa" and "10.00"
    String [] splitRecord = record.split("-");
    // if already exsit, sum and cardinality
    if (result.containsKey(splitRecord[0])) {
        result.put(splitRecord[0], new Pair<>(Double.valueOf(splitRecord[1])   result.get(splitRecord[0]).first(), result.get(splitRecord[0]).second()   1));
    } else {
        result.put(splitRecord[0], new Pair<>(Double.valueOf(splitRecord[1]), 1));
    }
});

System.out.println(result);
 

Комментарии:

1. Этот ответ был бы еще лучше с объяснением того, как он решает проблему.

2. Спасибо за предоставленное решение. в этом классе for Pair, какой оператор импорта нам нужно выполнить, я попробовал с помощью javafx.util. Не могли бы вы помочь мне решить эту проблему, но при первом () методе возникает ошибка.

3. Это могут быть разные реализации класса Pair. Вы можете проверить методы вашей пары, такие как getKey(), GetValue() , left() и right(), и найти похожие методы для получения значений из пары.