简体   繁体   English

Transforming a Map in Java using Java 8 Streams - Segregating Map based on the Value of the Map

[英]Transforming a Map in Java using Java 8 Streams - Segregating Map based on the Value of the Map

I have a Map in Java:我在 Java 中有一个 Map:

Map<String, Set<EntityObject>> itemGroupsMap

class EntityObject {
  boolean isParent;
  String groupId;
}

Now I want to transform itemGroupsMap Map ---to ---:现在我想将itemGroupsMap Map --- 转换为 ---:

Map<EntityObject, Set<EntityObject>> parentChildMap.

The logic to do is that each entry of itemGroupsMap -> Set -> Among this Set will an EntityObject that will be a parent (EntityObject.isParent=1).要做的逻辑是itemGroupsMap -> Set -> 在这个 Set 中的每个条目都会有一个 EntityObject,它将是一个父级 (EntityObject.isParent=1)。 So for each entry in the map I have to find the parent EntityObject and make it key of the parentChildMap and put only the rest of the entitiObjects as the Set/List to this key.因此,对于 map 中的每个条目,我必须找到父 EntityObject 并将其设为parentChildMap的键,并且仅将 entitiObjects 的 rest作为该键的 Set/List。

I have tried using 2 foreach loops and I am pretty new to Java 8 so was looking how I can reduce my code using streams?我尝试使用 2 个 foreach 循环,而且我对 Java 8 很陌生,所以正在寻找如何使用流来减少我的代码?

I looked at Collectors.partitioningBy but it creates 2 maps with 0, 1 keys.我查看了 Collectors.partitioningBy 但它使用 0、1 个键创建了 2 个映射。 I dont really need that.我真的不需要那个。

Any suggestions?有什么建议么?

Maybe something like this:也许是这样的:

Map<EntityObject, Set<EntityObject>> newMap = itemGroupsMap.entrySet().stream()
        .collect(Collectors.toMap(
                entry -> entry.getValue().stream().filter(value -> value.isParent).findFirst().orElse(null),
                Map.Entry::getValue
        ));

Note: his code doesn't care about data set in initial map without parent -> entry.getValue().stream().filter(value -> value.isParent).findFirst().orElse(null), it tells: set null as a key when no parents in set. Note:他的代码不关心没有父级的初始 map 中的数据集 -> entry.getValue().stream().filter(value -> value.isParent).findFirst().orElse(null),它告诉:当设置中没有父母时,将null设置为键。 So, if it is possible, then every set without parent will be overwritting by the next one without parent.因此,如果可能,那么没有父级的每个集合都将被下一个没有父级的集合覆盖。

Here are several approaches, assuming I understand what you want.假设我了解您想要什么,这里有几种方法。 If the key of the map is EntityObject, then it needs to override equals to take care of duplicate keys which are not allowed.如果 map 的 key 是 EntityObject,那么它需要重写 equals 来处理不允许的重复 key。 This could be done by using the Id as part of the equals implementation (which isn't obvious from the class provided)这可以通过使用 Id 作为 equals 实现的一部分来完成(这在 class 提供的情况下并不明显)

            Map<EntityObject, Set<EntityObject>> parentChildMap =
                itemGroupsMap.entrySet().stream()
                        .collect(Collectors.toMap(
                                // get the single parent object and use
                                // as a key
                                e -> e.getValue().stream()
                                        .filter(o -> o.isParent)
                                        .findFirst().get(),
                                // get the value and remove the parent
                                // key, convert to a set and use as the new
                                // value.
                                e -> e.getValue().stream()
                                        .filter(o -> !o.isParent)
                                        .collect(
                                                Collectors.toSet())));

There may be a better way to do it with streams but I prefer the following as it is straight forward.使用流可能有更好的方法,但我更喜欢以下方法,因为它是直截了当的。

        // create the map
        Map<EntityObject, Set<EntityObject>> parentChildMap = new HashMap<>();

        for (Entry<String, Set<EntityObject>> e : itemGroupsMap
                .entrySet()) {

            // get the set of EntityObjects
            Set<EntityObject> eoSet = e.getValue();

            // get the parent one
            EntityObject parentObject = eoSet.stream()
                    .filter(eo->eo.isParent).findFirst().get();

            // remove the parent one from the set
            eoSet.remove(parentObject);

            // add the parentObject and the set to the map
            parentChildMap.put(parentObject,eoSet);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM