[英]Create new groupings based on the String element of a Map<String, List<Object>>
我有一个名为“ Coordinates
的Objects
的列表,每个坐标都包含三个值。 两个类型为double
x,y和一个String
名称。 我的代码接收坐标输入作为输入,并通过创建<String, List<Object>>
类型的Map
根据名称对它们进行分组。 这样,我将拥有一个与所有相应坐标相关联的名称,而不是将一对坐标与一个名称相关联。
EG:
地图前:
[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
其中A,B和C是名称。 如果多个名称同时出现,则表示它们共享相同的坐标。
地图后:
[[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
我想要实现的是将每个名称与组分开,并将所有坐标链接到该名称。
我要达到的目标的EG:
[[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
以下是创建Map
并按名称分组的代码:
Map<String, List<Coordinates>> newList = coordinateList.stream()
.collect(Collectors.groupingBy(Coordinates::getName));
有什么办法可以做到这一点? 请注意,名称(例如ABC)没有用逗号或空格分隔,但是如果有可能的解决方案,我已经知道该怎么做(A,B,C)。
座标课:
public class Coordinates {
private double X;
private double Y;
private String name;
public Coordinates(double dexp, double dent, String name) {
this.X=dexp;
this.Y=dent;
this.name=name;
}
@Override
public String toString() {
return "["+X+","+Y+"]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getX() {
return X;
}
public void setX(double x) {
X = x;
}
public double getY() {
return Y;
}
public void setY(double y) {
Y = y;
}
}
名称示例:
STEP(One)
STEP(Two)
STEP(One)STEP(Two)
如果我对您的理解正确,我们假设您已经可以轻松到达第二张地图。 这对于任何一个地图都应该起作用,但是您甚至可以基于此稍作优化。 继续这个假设并使用您的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。
注意 :这将创建一个单名称映射到它们各自的坐标。 您可以很容易地翻转该地图(两者应该是相当独特的),尽管我自己不确定用例。 请记住,如果两个名称在此地图上具有相同的坐标,则翻转地图可能会导致丢失其中一个名称。 因此,我使用名称->坐标原样保留答案。
将名称拆分任务留给您,并假设您不想使用拆分名称创建新的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() ) ) );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.