如何查找数组列表中重复值的计数和重复值的总数



我有一个带有amount的数据列表,我想将重复的数据与计数和总金额分开。

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

自2014年3月Java 8发布以来,Java提供了流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  %3d%n", 
name, stat.getSum(), stat.getCount()
));

输出:

data  amount  count
aa   60.00    3
bb   25.00    2

LinkedHashMap确保元素按照插入顺序出现(就像它们在输入列表中出现一样)。

处理这个问题的思路如下:

  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);