#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:
Идеи для решения этой проблемы заключаются в следующем:
- Разделите каждую символьную строку на имя и значение.
- Соберите статистику по каждой символьной строке. Суммируйте и подсчитайте символы с одинаковым именем.
- Сохраните результат на карте.
- Выведите результат статистики.
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(), и найти похожие методы для получения значений из пары.