如何使用 Java lambda 遍历列表映射并返回单个值? [复制]

Posted

技术标签:

【中文标题】如何使用 Java lambda 遍历列表映射并返回单个值? [复制]【英文标题】:How to iterate over a map of lists and return a single value with Java lambdas? [duplicate] 【发布时间】:2021-02-16 10:26:53 【问题描述】:

我有这个想法。 我需要遍历 Map<UUID, List<Items>> groups 并返回一个值!

我可以用 Lambda 做到这一点吗?如何做? (如何获取具有 TYPE_12 项的组的 ID?TYPE_12 项将在所有组中只有一个)

提前感谢这是我的for 代码:

String theId = null;
for(Map.Entry<UUID, List<Item>> group : groupsOfItems) 
    for (Item item : group.getValue()) 
        if (item.getType() == Types.TYPE_12) 
            theId = group.getKey().toString();
            break;
        
    

【问题讨论】:

【参考方案1】:

如果您想使用函数式样式,您可以从映射条目集创建一个流,然后将其展开以获取底层列表中每个项目的流:

Optional<String> result = groupOfItems.entrySet().stream()
            .flatMap(entry -> entry.getValue().stream())
            .filter(item -> Types.TYPE_12.equals(item.getType))
            .map(Item::getId)
            .findAny();

result.ifPresent(id -> System.out.println("A match has been extracted: "+id));

事实上,函数式的方式并不比命令式的方式更高效,但更容易适应。假设您想知道是否有多个匹配项,您可以将 findAny 替换为具有限制的收集器:

List<String> matchedIds = groupOfItems.entrySet().stream()
            .flatMap(entry -> entry.getValue().stream())
            .filter(item -> Types.TYPE_12.equals(item.getType))
            .map(Item::getId)
            .limit(2)
            .collect(Collectors.toList());

if (matched.isEmpty()) System.out.println("No match found");
else if (matched.size() == 1) System.out.println("Exactly one match found: "+matched.get(0));
else System.out.println("At least two matches exist");

如有必要,流使用还允许并行化,只需将parallel() 步骤添加到您的管道。

【讨论】:

谢谢!伟大的!我很快就会试试这个!它看起来像我需要的。我正在努力将自己定位于实用风格。【参考方案2】:

这是一个使用 lambdas 的解决方案。不同之处在于这个不使用flatMap,如果找不到所需的值则抛出异常(基于问题指出在地图的整个值集中应该只有一个TYPE_12)。

UUID result = groupsOfItems.entrySet().stream()
    .filter(e -> e.getValue().stream()
        .anyMatch(item -> item.getType() == TYPE.TYPE_12))
    .findAny().orElseThrow().getKey();

【讨论】:

【参考方案3】:
String theId = null;

find:
for (Map.Entry<UUID, List<Item>> group : groupsOfItems.entrySet()) 
    for (Item item : group.getValue()) 
        if (item.getType() == Types.TYPE_12) 
            theId = group.getKey().toString();
            break find;
        
    

不,不要为此使用 lambda。 找到您的条目后,只需使用 java 标签打破两个 for 循环。 (请注意第一个 for 循环之前的 find:。这是一个标签,一旦您调用 break find;,它就会跳出标有该标签的块)

您还需要在第一个 for 循环中使用 .entrySet。仅仅通过 groupsOfItems 是不够的

【讨论】:

它对你有用吗@gai-jin?? 不,我在我的代码中有标签和所有内容(在这里我快速取样,更像是 suedo 代码)。如果可能的话,我想用 LAMBDA 来做。这是我的问题之一。只是为了用lambds重新制作它。 好吧,那没关系

以上是关于如何使用 Java lambda 遍历列表映射并返回单个值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何将 API Gateway API 中的路径参数映射到 Java Lambda 的请求对象

如何有效地迭代 Java Map 中的每个条目?

2021-08-01:如果只给定一个二叉树前序遍历数组pre和中序遍历数组in,能否不重建树,而直接生成这个二叉树的后序数组并返

映射在视图上的函数列表 - 视图是不是被多次遍历?

如何使用 Java 8 Lambda 将对象列表转换为 Map<Object, Object>

如何从数组列表中提取项目并对其进行计数,以便从元素及其总计数(正确)在 Java 中创建映射?