Java 基于地图的字符串元素创建新分组<;字符串,列表<;对象>&燃气轮机;
我有一个名为坐标的对象列表,每个坐标包含三个值。两个Java 基于地图的字符串元素创建新分组<;字符串,列表<;对象>&燃气轮机;,java,list,dictionary,java-8,java-stream,Java,List,Dictionary,Java 8,Java Stream,我有一个名为坐标的对象列表,每个坐标包含三个值。两个doublex,y类型和一个Stringname类型。“我的代码”接收坐标作为输入项,并通过创建类型为的地图,根据名称对其进行分组。通过这种方式,我没有将一对坐标与一个名称关联,而是将一个名称与所有对应的坐标关联 例如: 地图前: [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
double
x,y类型和一个String
name类型。“我的代码”接收坐标作为输入项,并通过创建类型为
的地图,根据名称对其进行分组。通过这种方式,我没有将一对坐标与一个名称关联,而是将一个名称与所有对应的坐标关联
例如:
地图前:
[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
我想要实现的是将每个名称从组中分离出来,并将所有坐标链接到该名称
例如,我正在努力实现的目标:
[[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<String, List<Coordinates>> newList = coordinateList.stream()
.collect(Collectors.groupingBy(Coordinates::getName));
姓名示例:
STEP(One)
STEP(Two)
STEP(One)STEP(Two)
如果我理解正确的话,我们假设你已经可以很容易地到达你的第二张地图。这应该适用于任何一个地图,但是,您甚至可以在此基础上稍微优化它。根据此假设,使用您的地图
,我们可以根据该输入进行累积/合并:
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;
});
});
});
Map-myComboMap=/*…*/;
Map myAbsoluteMap=新HashMap();
myComboMap.forEach((名称、坐标)->{
列表名称=/*将名称拆分为列表,或只是迭代*/;
名称。forEach(n->{
//合并或创建每个名称的结果
myAbsoluteMap.compute(n,(键,旧)->{
if(old==null){
//复制列表以避免更改旧地图
返回新的ArrayList(coords);
}
//或附加到现有列表中
old.addAll(coords);
返老还童;
});
});
});
这也可以通过#flatMap和Collectors#toMap对streams进行处理,但是该解决方案将涉及创建许多对象,因此为了简单起见,我使用了一个副作用#forEach
注意:这将创建单个名称到各自坐标的地图。您可以很容易地翻转该映射(两者都应该是相当独特的),尽管我自己并不确定该用例。请记住,如果两个名称在此地图上具有相同的坐标,则翻转地图可能会丢失其中一个名称。因此,我保留了名称->坐标的答案。将名称拆分任务留给您,并且假设您不想使用拆分名称创建新的坐标
对象,您可以执行以下操作:
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() ) ) );
Map newList=coordinateList.stream()
.flatMap(c->split(c.getName()).stream()
.map(sn->newAbstractMap.SimpleEntry(sn,c)))
.collect(收集器.groupingBy(
Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,Collectors.toList());
那么你所有的名字都是一个字母?否则,必须有一种方法来分隔各个名称。不,它们不是单个字母。为了简单起见,我只是在示例中添加了它们。它们可以包含字母、字符,但不能包含数字。因此,我们不知道它们看起来像什么,也不知道如何将它们分开。另外,坐标
类不包括在您的问题中。拆分名称时,似乎还需要更改坐标对象本身中的“名称”属性。没有消息来源,我们不知道这是否可能。请回答您的问题并添加这两条信息,否则我看不出我们能为您提供什么帮助。我会慎重选择使用double
值作为标识符。在Java中,值0.1不能精确表示为双精度浮点值。选择使用双倍作为标识符可能会使系统脆弱且容易出错。
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() ) ) );