如何在 arraylist 中查找具有计数和重复值总数的重复值

How to find duplicate values with counts and total amount of duplicate values in 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. 将每个字符串拆分为一个名称和一个值。
  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);

自从 2014 年 3 月 Java 8 发布以来,Java 提供 Stream API 允许按集合元素分组并收集一些统计数据。

因此,输入的字符串应该分成几部分:名称和金额用破折号分隔 -,按字符串名称分组,并且应该收集 double 金额的统计信息。

使用Collection::stream, String::split, Collectors.groupingBy (with the Supplier and downstream collector), Collectors.summarizingDouble returning the 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 确保元素出现在插入顺序中(因为它们出现在输入列表中)。