我有一个表示另一个列表中条目的ID (可以是重复的)的List<String>
,它是一个List<Cheat>
,其中每个作弊者都有一个字符串ID和一个List<Integer> RNG
。这两种方法都有Cheat中的访问器方法。
我需要将这个ID列表转换为每个作弊的RNG列表,为我提供了ID。
例如,我可能有3个作弊:
1:{ID:1, RNG:{1,2,3}}
2:{ID:2, RNG{1,2}}
3:{ID:3, RNG:{1}}
以及以下ID的列表:
{3,1,1,2}.
我需要得到{ 1,1,2,3,1,2,3,1,2,3,1,2}的最终列表,它是Cheat 3的RNG,然后是cheat 1的RNG,然后是cheat 1的RNG,最后是cheat 2的RNG。
如果有人能帮我的忙,我将不胜感激。谢谢。
我尝试过,但失败了:
ImmutableList<Integer> sequenceRngs = cheatIds.stream()
.map(s -> cheats.stream()
.filter(cheat -> cheat.getId().equals(s))
.findFirst()
.map(cheat -> cheat.getRng()))
.flatMap(cheat -> cheat.getRng())
.collect(ListUtils.toImmutableList());
发布于 2020-01-20 21:34:33
一种可能的解决方案是:
import java.util.List;
import java.util.stream.Collectors;
class Scratch {
static class Cheat {
int id;
List<Integer> rng;
public Cheat(int id, List<Integer> rng) {
this.id = id;
this.rng = rng;
}
}
public static void main(String[] args) {
List<Cheat> allCheats = List.of(
new Cheat(1, List.of(1,2,3)),
new Cheat(2, List.of(1,2)),
new Cheat(3, List.of(1))
);
List<Integer> result = List.of(3, 1, 1, 2).stream()
.flatMap(id -> allCheats.stream()
.filter(cheat -> cheat.id == id)
.findFirst().orElseThrow().rng.stream())
.collect(Collectors.toList());
System.out.println(result);
}
}
关键是使用flatMap最终在单个集合中获得结果,而不是嵌套集合。
发布于 2020-01-20 21:30:14
传递给flatMap
的lambda应该返回一个Stream
,而不是一个List
。您应该处理流中没有这样的元素的情况-即使您确定有。类似这样的代码应该可以:
final ImmutableList<String> sequenceRngs = cheatIds.stream().flatMap(id ->
cheats.stream().filter(cheat -> id.equals(cheat.getId()))
.findAny().orElseThrow(IllegalStateException::new)
.getRng().stream())
.collect(ListUtils.toImmutableList());
此外,我建议将作弊列表转换为映射-这将简化代码,并将搜索的复杂度从O(n)降低到O(1)。
发布于 2020-01-20 22:21:25
您可以通过以下步骤实现这一点:
cheatId
到关联的RNG id
的映射:Map map = cheats.stream() .collect(Collectors.toMap(List>::getId,在作为输入提供的cheatIds
上欺骗-> getId,并从地图中获取相应的RNG以收集为输出:
.collect(Collectors.toList());输出= cheatIds.stream() .flatMap(ch -> map.get(ch).stream()) List output
https://stackoverflow.com/questions/59824178
复制相似问题