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

Posted

技术标签:

【中文标题】如何在arraylist中查找具有计数和重复值总数的重复值【英文标题】:How to find duplicate values with counts and total amount of duplicate values in arraylist 【发布时间】:2021-12-06 01:44:45 【问题描述】:

我有一个带有数量的数据列表,我想用那个计数和那个总数量来分离重复的数据。

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】:

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

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

使用Collection::streamString::splitCollectors.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 确保元素按插入顺序出现(就像它们出现在输入列表中一样)。

【讨论】:

【参考方案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);

【讨论】:

这个答案会更好,解释一下如何解决问题。 感谢您提供解决方案。在这个对于我们需要采用哪个导入语句的 Pair 类中,我尝试使用 javafx.util.Pair 但在 first() 方法时抛出错误,你能帮我解决这个问题吗? 可能是Pair类的不同实现。您可以查看您的 Pair 的方法,例如 getKey()、getValue()、left() 和 right(),并找到类似的方法从 Pair 中获取值。

以上是关于如何在arraylist中查找具有计数和重复值总数的重复值的主要内容,如果未能解决你的问题,请参考以下文章

获取Java中arrayList中重复值的计数而不影响arrayList的顺序[重复]

如何使用PHP [重复]显示提交的单选按钮值的计数

仅当重复电子邮件或电话时,Mysql 计数总数

查找指定列的重复行[重复]

SQL查找不同值计数,2次重复值计数,3次重复值计数等

如何在 Spark Scala 中的 Schema RDD [从案例类中创建] 中查找重复项以及相应的重复计数?