在嵌套对象列表上迭代并使用流API将它们存储到哈希图

发布于 2025-02-09 07:27:31 字数 1149 浏览 1 评论 0原文

我正在尝试通过嵌套的Java对象和使用Java 8填充A map 的嵌套对象进行迭代。

这是对象的列表和结构

issuetypedto.java

public class IssueTypeDto {
    private String id;
    private String name;
    private List<CustomFieldDto> customFields;
}

customfielddto.java

    private String id;
    private TypeDto type;

我正在获取list issuetypedto作为响应。每个ISSUETYPEDTO对象可以具有customfielddto对象的列表。我的要求是,我需要在ISSUETYPEDTO对象的列表上进行迭代,并且对于每个customfielddto对象,我需要获得id> id和相应的键入对象并将其插入地图作为键和值。这是我目前正在尝试做的事情

Map<String, TypeDto> map = issueTypes.stream()
    .flatMap(issueType->issueType.getCustomFields().stream()
                .collect(Collectors.toMap(
                            CustomFieldDto::getId,
                            CustomFieldDto::getType)));

,但我遇到了编译时间错误作为类型不匹配:

cannot convert from Stream<Object> to Map<String,TypeDto>"

我是Java 8流的新手。因此,我无法弄清楚这个问题。任何帮助将不胜感激。

I am trying to iterate over nested java object and from nested object I'm trying to populate a map using Java 8.

Here is the list and structure of objects

IssueTypeDto.java

public class IssueTypeDto {
    private String id;
    private String name;
    private List<CustomFieldDto> customFields;
}

CustomFieldDto.java

    private String id;
    private TypeDto type;

I am getting List of IssueTypeDto as response. Each IssueTypeDto object can have a list of CustomFieldDto objects. My requirement is I need to iterate over a list of IssueTypeDto objects and for each CustomFieldDto object I need to get id and the corresponding TypeDto object and insert it into a map as key and value. Here is what I am trying to do currently

Map<String, TypeDto> map = issueTypes.stream()
    .flatMap(issueType->issueType.getCustomFields().stream()
                .collect(Collectors.toMap(
                            CustomFieldDto::getId,
                            CustomFieldDto::getType)));

But i am getting compile time error as Type mismatch:

cannot convert from Stream<Object> to Map<String,TypeDto>"

I am new to Java 8 streams. So I am not able to figure out the issue. Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月朦胧 2025-02-16 07:27:31

让我们知道一般概念。您想将一个对象转换为另一个对象。可以是1比1的关系,也可以是许多人的关系。如果1至1,则需要使用.map。 1到许多 - .flatmap。因此,换句话说,映射将对象A转换为对象B。Flatmap将对象A转换为对象B的流。

您的情况应该是这样:

issueTypes.stream()
.flatMap(issueType -> issueType.getCustomFields().stream())
.collect(Collectors.toMap(CustomFieldDto::getId CustomFieldDto::getType));

另外,请确保在不同对象的键上没有重复项,否则Collector.TOMAP()将由于钥匙重复而抛出异常。

Let's know the general concepts. You want to transform one object to another one. It can be 1 to 1 relationship or 1 to many. In case of 1 to 1 you need to use .map. 1 to many - .flatMap. So in other words map convert Object A to Object B. flatMap convert Object A to Stream of Object B. You was near you missed ')'.

Your case should be like this:

issueTypes.stream()
.flatMap(issueType -> issueType.getCustomFields().stream())
.collect(Collectors.toMap(CustomFieldDto::getId CustomFieldDto::getType));

Also please be sure that there are no duplicates on keys of different objects, otherwise Collectors.toMap() will throw exception due to key duplication.

情魔剑神 2025-02-16 07:27:31

您提供的代码没有两个原因:

  • flatmap() Intermediate 它期望返回作为参数的函数。相反,您创建了一个生成 map 的嵌套流。因此,您的函数与flatmap()期望。

  • 您的流管线缺少终端操作,因此此任务不正确

Map<String, TypeDto> map = issueTypes.stream().flatMap();

左侧有一个地图,右侧有一个流(因为flatmap()是一个中间操作,返回流)。

要修复它,您需要将功能传递到flatMap()返回流中,然后添加终端操作到管道中,即从主中产生结果通过移动collect()flatmap()移出。

这就是可以通过使用collector.tomap() 来完成的(在您提到的注释中,可以重复 id s) :

Map<String, TypeDto> map = issueTypes.stream()
    .flatMap(issueType -> issueType.getCustomFields().stream())
    .collect(Collectors.toMap(
        CustomFieldDto::getId,   // mapping a key
        CustomFieldDto::getType, // mapping a value
        (left, right) -> left    // resolving duplicates - preserve the first encountered value
    ));

处理重复项的另一种方法是通过将映射到同一键的值存储到列表中来保存所有重复项,可以使用collectors.groupingby()

 Map<String, List<TypeDto>> map = issueTypes.stream()
    .flatMap(issueType -> issueType.getCustomFields().stream())
    .collect(Collectors.groupingBy(CustomFieldDto::getId));

The code you've provided does not compile for two reasons:

  • flatMap() is an intermediate operation which expects a function that returns a stream as an argument. Instead, you've created a nested stream that generates a map. Therefore, your function doesn't match what flatMap() expects.

  • Your stream pipeline lacks the terminal operation, therefore this assignment is incorrect

Map<String, TypeDto> map = issueTypes.stream().flatMap();

There's a map on the left side and a stream on the right side (because flatMap() is an intermediate operation, returns you stream).

To fix it, you need to make the function passed into the flatMap() return a stream, and add a terminal operation to the pipeline, i.e. produce the result from the main stream by moving collect() out from the flatMap().

That's how it can be done by using Collectors.toMap() (in the comments you've mentioned that there could be duplicated ids ):

Map<String, TypeDto> map = issueTypes.stream()
    .flatMap(issueType -> issueType.getCustomFields().stream())
    .collect(Collectors.toMap(
        CustomFieldDto::getId,   // mapping a key
        CustomFieldDto::getType, // mapping a value
        (left, right) -> left    // resolving duplicates - preserve the first encountered value
    ));

Another way of handling duplicates is preserve all of them by storing values mapped to the same key into a list, which can be done with Collectors.groupingBy():

 Map<String, List<TypeDto>> map = issueTypes.stream()
    .flatMap(issueType -> issueType.getCustomFields().stream())
    .collect(Collectors.groupingBy(CustomFieldDto::getId));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文