java - 修剪这组数据的简单方法是什么? ( java )

标签 java json class arraylist

我正在练习使用 Java 中的简单 JSON 数据,但遇到了一些困难。

假设我是一名面包师,我有一些多年来我的各种产品的数据。例如,我有三种产品:蛋糕、百吉饼和 cookies 。我的数据每年收集一次,因此 JSON 数据集示例可能类似于:

[ {"name": "cake", "consumers": 200, "tastiness": 8.0}, {"name": "cake", "consumers": 220, "tastiness": 8.3}, {"name": "bagel", "consumers": 1000, "tastiness": 6.4}, {"name": "bagel", "consumers": 1200, "tastiness": 7.5}, {"name": "bagel", "consumers": 800, "tastiness": 5.7}, {"name": "cookie", "consumers": 500, "tastiness": 9.6} ]

正如您所看到的,有两个“cake”条目表示蛋糕已存在两年,三个“bagel”条目表示百吉饼已存在三年,等等。

我想压缩这些数据以获得每种产品的加权平均味道。例如,蛋糕的平均味道是 (8.0*200 + 8.3*220)/(200+220) = 8.157,所以我希望我的新集合包含一个值为 ("cake", 8.157) 的数据条目,除了百吉饼和 cookies 相应的平均美味之外。

解析 JSON 数据并提取我想要的值是微不足道的,但我正在努力的是提取/压缩具有相同名称的数据值并获得平均味道的最佳方法。

到目前为止,我已经考虑过为名称、consumerNumbers 和 tastiness 创建 arrayList,但我意识到这可能有点困惑和不方便。

我目前正在考虑创建一个名为“Product”的单独类,其属性为“name”、“consumers”和“tastiness”,然后创建一个单个 arrayList<Product> 。但是,我坚持如何最好地迭代产品的 arrayList 并获取具有相同名称的产品并计算加权平均值。

我知道可能存在一个非常简单的解决方案来解决我的问题,但目前我还没有找到它,所以任何帮助将不胜感激。谢谢:)

最佳答案

我认为您创建具有上述属性的容器类的想法是个好主意。

groupingBy 的组合和reducing来自java.util.stream.Collectors类,你可以实现这个。

我们首先定义一个类来保存我们的数据:

public class SugarStats {
    private String name;
    private long consumers;
    private double tastiness;

    // Constructor(name, consumers, tastiness) and getters left out for brevity
}

我们将使用这个容器类来计算平均值,因此我们将添加一个方法:

public double getAverageTastiness() {
    return this.tastiness / this.consumers;
}

此外,我假设已经完成从 JSON 到 POJO 的转换,并且您的数据如下所示:

List<SugarStats> stats = Arrays.asList(
    new SugarStats("cake", 200, 8.0),
    new SugarStats("cake", 220, 8.3),
    new SugarStats("bagel", 1000, 6.4),
    new SugarStats("bagel", 1200, 7.5),
    new SugarStats("bagel", 800, 5.7),
    new SugarStats("cookie", 500, 9.6));

然后我们将执行以下操作:

  1. 我们将流式传输列表:

    stats.stream()
    
  2. 然后我们将总结每个 SugarStats 的总美味分数。 ,而不是单个条目的分数:

    .map(t -> new SugarStats(t.getName(), t.getConsumers(), t.getConsumers() * t.getTastiness()))
    

    例如,cookie Sugarstats 实例现在的味道为 500 * 9.6 = 4800 .

  3. 然后我们收集结果,按名称分组。这通常会返回 Mapname作为 key 和 List<SugarStats>与所有值(value)观。但是,我们对List不感兴趣。 ,我们只对平均值感兴趣。因此,我们提供了一个减少下游收集器,它收集所有 SugarStats 并将它们组合起来,计算出消费者数量和味道的总数。

    例如,new SugarStats("cake", 200, 1600.0) + new SugarStats("cake", 220, 1826.0)将变成new SugarStats("cake", 420, 3426) .

    .collect(groupingBy(t -> t.getName(),
        reducing(
            new SugarStats("", 0, 0),
            (p1, p2) -> new SugarStats(
                p2.getName(),
                p1.getConsumers() + p2.getConsumers(),
                p1.getTastiness() + p2.getTastiness()
            )
        )
    ));
    

现在我们可以品尝到美味了:

result.values().stream()
    .forEach(t -> System.out.println(t.getName() + ": " + t.getAverageTastiness()));

Ideone example here .

关于java - 修剪这组数据的简单方法是什么? ( java ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57897008/

相关文章:

Javascript - 如果语句不起作用?

java - HashMap 新增内容 : how can I sort it?

java - 使用 MongoDB Java 驱动程序组合多个数组进行查询

php - 如何使用 PHP 删除 JSON 中的方括号

python - 使用 Python 生成 JSON 数据

c++ - 使用默认构造函数调用的网格类不工作 OpenGL C++

java - 快速迭代具有 5100 万个素数的数据结构

java - 创建一个循环,以便 ActionListener 在单击 Jbutton 时遍历图标列表

iphone - 如何解析Json对象

PHP:如何遍历动态数量的类