我有一台List<Computer>。每台计算机都有一个CPU列表和一个主机名。所以,假设我有:
List<Computer> computers我可以打电话给你
List<CPU> CPUs = computer.getCPUs();我可以给你打电话
String hostname = computer.getHostName();我想要做的是,使用Streams获得一个Map,其中包含作为关键字的CPU和作为字符串的主机名。相同计算机中的相同CPU将复制主机名。
我该怎么做呢?
Pre Java8代码如下:
public Map<CPU, String> getMapping(List<Computer> computers) {
Map<CPU, String> result = new HashMap<>();
for (Computer computer : computers) {
for (CPU cpu : computer.getCPUs()) {
result.put(cpu, computer.getHostname());
}
}
return result;
}发布于 2017-01-14 01:42:26
如果您的CPU类有一个对它的Computer实例的反向引用,那么您可以很容易地做到这一点。首先是所有计算机上的流,然后是getCPUs的平面图,这将为您提供所有CPU的Stream<CPU>。然后,您可以使用Collectors.toMap将其收集到Map<CPU, String>中,使用Function.identity作为键,并使用lambda从CPU中提取值,首先提取Computer,然后提取主机名。在代码中:
computers.stream()
.flatMap(computer -> computer.getCPUs().stream())
.collect(Collectors.toMap(Function.identity(), cpu -> cpu.getComputer().getHostname()));发布于 2017-01-14 02:08:02
您可以通过实现自己的Collector来实现,以便将相同的值分配给同一台计算机的所有CPU:
Map<CPU, String> cpus = computers.stream().collect(
Collector.of(
HashMap::new,
// Put each cpu of the same computer using the computer's hostname as value
(map, computer) -> computer.getCPUs().stream().forEach(
cpu -> map.put(cpu, computer.getHostName())
),
(map1, map2) -> { map1.putAll(map2); return map1; }
)
);这基本上等同于您当前使用Stream API所做的工作,唯一的区别是您可以通过简单地使用并行流而不是普通流来并行化它,但在这种特殊情况下,由于任务非常小,在性能方面可能没有太大帮助,因此在这种情况下使用Stream API可能会被认为是有点滥用。
发布于 2017-01-16 14:23:24
您可以使用一个中间Entry将CPU和主机名放在一起:
Map<CPU, String> map = computers.stream()
.flatMap(c -> c.getCPUs().stream().map(cpu -> new AbstractMap.SimpleEntry<>(cpu, c.getHostName())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));https://stackoverflow.com/questions/41639933
复制相似问题