Java流:对HashMap键值进行分组以防止重复键

发布于 2025-01-11 15:26:06 字数 926 浏览 0 评论 0原文

我的 Java 应用程序中有以下 HashMap:

final Map<UUID, Boolean> map = demoRepo.demoService.stream()
        .collect(Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus));

但是,由于结果包含多个 menuUuid 值,我需要将它们分组,因为键不包含相同的值。那么,我应该如何使用流来做到这一点?

更新:我也尝试了groupingBy,如下所示,但我认为用法不正确:

final Map<UUID, Boolean> map = sdemoRepo.demoService.stream()
                .collect(Collectors.groupingBy(
                        ProductDTO::getMenuUuid, LinkedHashMap::new,
                        Collectors.mapping(ProductDTO::getStatus)));

假设我有以下流:

MenuUuid   |   Status |
-----------------------
1              true
2              false
1              true
1              true
3              true
2              false

那么我需要一个像这样的地图结果; 1:正确,2:错误,3:正确

I have the following HashMap in my Java app:

final Map<UUID, Boolean> map = demoRepo.demoService.stream()
        .collect(Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus));

However, as the result contains multiple menuUuid value, I need to group them as the key does not contain the same value. So, how should I do this using stream?

Update: I also tried groupingBy as shown below, but I think the usage is not correct:

final Map<UUID, Boolean> map = sdemoRepo.demoService.stream()
                .collect(Collectors.groupingBy(
                        ProductDTO::getMenuUuid, LinkedHashMap::new,
                        Collectors.mapping(ProductDTO::getStatus)));

Suppose that I have the following stream:

MenuUuid   |   Status |
-----------------------
1              true
2              false
1              true
1              true
3              true
2              false

Then I need a map result like; 1:true, 2:false, 3:true

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

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

发布评论

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

评论(3

早乙女 2025-01-18 15:26:06

如果所有用户 id 都具有相同的布尔值,则只需执行以下操作:

final Map<UUID, Boolean> map = demoRepo.demoService.stream()
        .collect(Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus,
                (existingValue, newValue)->existingValue));

最后一个 lambda 是合并函数。它用于决定如何合并重复的键。在这种情况下,它只保留已经存在的第一个。您也可以使用新的,因为您并没有真正改变 boolean 并且它们都是相同的值。

如果您的 ProductDTO 类使用 UUID 通过 equals() 确定相等性,您还可以执行以下操作:

final Map<UUID, Boolean> map = demoRepo.demoService.stream()
        .distinct()
        .collect(Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus));

这有效,因为您不会有任何重复的 UUID

If all the user ids have the same boolean then just do the following:

final Map<UUID, Boolean> map = demoRepo.demoService.stream()
        .collect(Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus,
                (existingValue, newValue)->existingValue));

the last lambda, is a merge function. it is used to make a decision on how to merge duplicate keys. In this case, it just keeps the first that's already there. You could also use the new one since you aren't really altering the boolean and they are all the same value.

If your ProductDTO class uses UUID to determine equality via equals() you could also do the following:

final Map<UUID, Boolean> map = demoRepo.demoService.stream()
        .distinct()
        .collect(Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus));

This works because you won't have any duplicate UUID's

明天过后 2025-01-18 15:26:06

Collectors.toMap(Function keyMapper,
函数值映射器,
BinaryOperator mergeFunction)
允许调用者定义一个 BinaryOperator mergeFunction,如果流为已存在的键提供键值对,则返回正确的值。

以下示例使用 Boolean.ologicalOr 方法将现有值与新值组合。
相同的 UUID 键不会分组,因为结果是单个键-单值映射。但

final Map<UUID, Boolean> map = demoRepo.demoService.stream()
        .collect(Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus,
                 Boolean::logicalOr));

特别是 Boolean::ologicalOr 是一个函数,如果映射已经包含键的值,则会调用该函数。在这种情况下,Boolean::ologicalOr 将现有映射值和来自 Stream` 的新值作为参数,并返回这两个值的逻辑或作为结果。然后将结果输入到地图中。

The Collectors.toMap(Function keyMapper,
Function valueMapper,
BinaryOperator mergeFunction)
allows the caller to define a BinaryOperator mergeFunction that returns the correct value if the stream provides a key-value pair for a key that already exists.

The following example uses the Boolean.logicalOr method to combine the existing value with the new one.
Equal UUID keys are not grouped,since the result is a single key-single value map. But

final Map<UUID, Boolean> map = demoRepo.demoService.stream()
        .collect(Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus,
                 Boolean::logicalOr));

In particular Boolean::logicalOr is a function that is called if the map already contains a value for the key. In this case, the Boolean::logicalOr takes as argument the existing map value and the new value from theStream` and returns the Logical Or of these two, as the result. This results is then entered in the map.

來不及說愛妳 2025-01-18 15:26:06

您必须合并这些值。看看是否有帮助

final Map<UUID, Boolean> map  =
    demoRepo.stream().filter(Objects::nonNull)
        .collect(
            Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus,
                (menuUuid, status) -> {
                  menuUuid.addAll(status);
                  return menuUuid;
                }));

You will have to merge the values. See if it helps

final Map<UUID, Boolean> map  =
    demoRepo.stream().filter(Objects::nonNull)
        .collect(
            Collectors.toMap(
                ProductDTO::getMenuUuid,
                ProductDTO::getStatus,
                (menuUuid, status) -> {
                  menuUuid.addAll(status);
                  return menuUuid;
                }));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文