当前位置: 首页 > 知识库问答 >
问题:

如何分组收集器从数据创建一个新字段?

燕钟展
2023-03-14

我有这样的数据(地图列表):

{
    “name”: “Hello”,
    "source": “One”,
    "status": “Good”,
    “date”: "01-05-2021 7:35:58 PM"
},
{
    “name”: “Hello”,
    "source": “Two”,
    "status": “Good”,
    “date”: "01-05-2021 7:35:58 PM"
},
{
    “name”: “Goodbye”,
    "source": “Three”,
    "status": “Bad”,
    “date”: "01-05-2021 7:35:58 PM"
},
{
    “name”: “Goodbye”,
    "source": “Four”,
    "status": “Bad”,
    “date”: "01-05-2021 7:35:58 PM"
}

因此,我想按“名称”对这些数据进行分组,但也要创建一个新字段,它将“源”和“状态”字段收集到对象列表中。这意味着我还必须将内部数据映射到一个Java类(将这些单独的对象称为“SourceStatus”,我已经为其创建了一个类)。

{
    “name”: “Hello”,
    “sourceStatuses”: [
        {
            “source”: ”One”,
            “status”: ”Good”
        },
        {
            “source”: ”Two”,
            “status”: ”Good”
        }
    ],
    “status”: “Good”,
    “date”: "01-05-2021 7:35:58 PM"
},
{
    “name”: “Goodbye”,
    “sourceStatuses”: [
        {
            “source”: ”Three”,
            “status”: ”Bad”
        },
        {
            “source”: ”Four”,
            “status”: ”Bad”
        }
    ],
    “status” : “Bad,
    “date”: "01-05-2021 7:35:58 PM"
}

我知道groupingBy部分可以用Java的收集器(https://www.baeldung.com/java-groupingby-collector)非常直接地完成,但我不确定如何为我的用例实现结果集,在这里我不仅创建了一个新字段,而且还收集内部数据,然后将其映射到一个类。

编辑:“日期”和“状态”将是相同的所有项目具有相同的“名称”。

共有1个答案

牟黎昕
2023-03-14

GroupingBy收集器的键应该是另一个没有键“source”的可修改映射,值应该是SourceStatus类的列表,可以使用Collectors.Mapping收集器收集这些类。

注意:map用来表示一个键和一个最终结果。

我们假设,sourceStatus有一个自定义构造函数,它使用map 作为参数,以便在 集合中使用它。mapping: object>

public class SourceStatus {
    private String source;
    private String status;

    public SourceStatus(Map<String, Object> map) {
        this.source = (String) map.get("source");
        this.status = (String) map.get("status");
    }
}

那么获取结果映射集的代码如下所示:

Set<Map<String, Object>> mapped = data
    .stream()
    .collect(Collectors.groupingBy(
        m -> {
            Map<String, Object> key = new LinkedHashMap<>();
            key.putAll(m);
            key.remove("source");
            return key;
        },
        Collectors.mapping(SourceStatus::new, Collectors.toList())
    ))
    .entrySet().stream()
    .map(e -> {
        e.getKey().put("sourceStatuses", e.getValue());
        return e.getKey(); 
    })
    .collect(Collectors.toCollection(LinkedHashSet::new)); // maintain insertion order
// convert to json
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mapped);
System.out.println(json);

输出:

[ {
  "name" : "Hello",
  "date" : "01-05-2021 7:35:58 PM",
  "status" : "Good",
  "sourceStatuses" : [ {
    "source" : "1",
    "status" : "Good"
  }, {
    "source" : "2",
    "status" : "Good"
  } ]
}, {
  "name" : "Bye",
  "date" : "01-05-2021 7:35:58 PM",
  "status" : "Bad",
  "sourceStatuses" : [ {
    "source" : "3",
    "status" : "Bad"
  }, {
    "source" : "4",
    "status" : "Bad"
  } ]
} ]
 类似资料:
  • 我需要从不同的字典中创建一个熊猫数据框架,其中键必须作为数据框架内的列名。如果数据帧没有将键列为列,则必须动态创建键,并将其作为新列附加到数据帧。 我希望输入为, 输出应该是,, 循环的第一次迭代将键作为数据框的列名称,如果没有数据框,则创建值作为第一行的数据框。 第二次迭代检查键是否作为列出现在数据帧中,如果已经出现则插入,否则创建列并插入值作为第二行。 我确实不知道如何在python中动态运行

  • 问题内容: 我如何提取字符串[]或arraylist中的所有元素,并以适当的格式(所有空格之间使用单个空格)组合所有单词并存储在数组中。 输出:Java很酷。 问题答案: 使用。 或使用Apache Commons Lang 。 或使用Java8的。

  • 问题内容: 我有一个如下所示的pandas数据框,并通过一列保存数据组: 现在,我想创建新的数据框(名为df_w,df_x,df_y,df_z),这些数据框仅保存其原始数据中的数据,并在一些可迭代的列表(例如列表)中进行最佳组合: 有没有使用groupby,apply和/或applymap和函数来实现此目的的智能(矢量化熊猫)方法? 我当时正在考虑对数据框进行迭代,但这似乎不是很优雅。 预先感谢您

  • 创建一组元素,根据原始数组中的位置进行分组。 使用 Math.max.apply() 获取参数中最长的数组。 创建一个长度为返回值的数组,并使用 Array.from() 和 map-function 来创建一个分组元素数组。 如果参数数组的长度不同,则在未找到值的情况下使用 undefined 。 const zip = (...arrays) => { const maxLength =

  • 我有一个字符串数组和一个整数数组。如何使用第一个作为键,第二个作为值来创建地图? 如何在 Kotlin 中将 List 转换为 Map?不能解决这个问题;我有2个数组,想要一个地图。

  • 问题内容: 我有一个看起来像这样的数组。这是一个二维数组。 我想使用此信息来创建一个新的三维数组,如下所示。 请对此有任何帮助。我陷入困境,需要弄清楚如何使用此原始数组创建新数组。因此,基本上,我将每台计算机上的所有作业分组在一起,而这些作业的密钥取决于它们在原始阵列中的状态。因此,如果原始阵列上有一个键为2的作业,而该机上没有其他作业具有更高的键,则它将变成该作业的键0,并使用该机器名创建一个新