根据Map <string,list <object =“” >>的String元素创建新的分组

时间:2019-02-13 18:05:41

标签: java list dictionary java-8 java-stream

我有一个名为Objects的{​​{1}}列表,每个坐标包含三个值。两个Coordinates类型的x,y和一个double类型的名称。我的代码接收坐标的输入条目,并通过创建类型String的{​​{1}}根据名称对它们进行分组。这样,我就没有一个与名称相关联的坐标对,而是拥有一个与所有相应坐标相关联的名称。

E.G。 :

地图之前:

Map

其中A,B和C是名称。如果同时出现多个名称,则意味着它们共享相同的坐标。

地图后:

<String, List<Object>>

我想要实现的是从组中分离每个名称,并将所有坐标链接到该名称。

E.G。我要实现的目标:

[0.01,0.51] --> A
[0.01,0.56] --> A
[0.01,0.61] --> A
[0.01,0.66] --> AB
[0.01,0.71] --> ABC
[0.01,0.76] --> ABC

创建[[0.01,0.01,0.01],[0.51,0.56,0.61]] --> A [[0.01,0.01], [0.61,0.66]] --> AB [[0.01, 0.01], [0.71,0.76]] --> ABC 并按名称分组的代码如下:

[[0.01,0.01,0.01,0.01,0.01,0.01],[0.51,0.56,0.61,0.66,0.71,0.76]] --> A
[[0.01,0.01,0.01,0.01], [0.61,0.66,0.71,0.76]]                    --> B
[[0.01,0.01], [0.71,0.76]]                                        --> C

有什么办法可以做到这一点?请注意名称,例如ABC,不是用逗号或空格隔开,但是如果有可能的解决方案,我已经知道如何做到这一点(A,B,C)。

坐标类:

Map

名称示例:

Map<String, List<Coordinates>> newList = coordinateList.stream()
                .collect(Collectors.groupingBy(Coordinates::getName));

2 个答案:

答案 0 :(得分:-1)

如果我对您的理解正确,我们假设您已经可以轻松到达第二张地图。这对于任何一个地图都应该起作用,但是您甚至可以基于此稍作优化。继续这个假设并使用您的Map<String, List<Coordinate>>,我们可以根据该输入进行累积/合并:

Map<String, List<Coordinate>> myComboMap = /* ... */;
Map<String, List<Coordinate>> myAbsoluteMap = new HashMap<>();
myComboMap.forEach((name, coords) -> {
    List<String> names = /* split up name into list, or just iterate */;
    names.forEach(n -> {
        //merge or create the results for each name
        myAbsoluteMap.compute(n, (key, old) -> {
            if (old == null) {
                //copy list to avoid changing old map
                return new ArrayList<>(coords);
            }
            //or append to an existing list
            old.addAll(coords);
            return old;
        });
    });
});

这也可以通过#flatMap和Collectors#toMap通过流完成,但是该解决方案将涉及创建许多对象,因此为了简单起见,我使用了副作用#forEach。

注意:这将创建单名到其各自坐标的映射。您可以很容易地翻转该地图(两者应该是相当独特的),尽管我自己不确定用例。请记住,如果两个名称在此地图上具有相同的坐标,则翻转地图可能会导致丢失其中一个名称。因此,我将答案原样保留在names-> coordinates。

答案 1 :(得分:-1)

将名称拆分任务留给您,并假设您不想使用拆分名称创建新的Coordinate对象,您可以执行以下操作:

   Map<String, List<Coordinates> > newList = coordinateList.stream()
       .flatMap( c -> split( c.getName() ).stream()
                      .map( sn -> new AbstractMap.SimpleEntry<>(sn, c) ) )
       .collect( Collectors.groupingBy(
                 Map.Entry::getKey, 
                 Collectors.mapping(Map.Entry::getValue, Collectors.toList() ) ) );