我有List<Computer>
。每台计算机都有一个CPU列表和一个主机名。
所以,假设我有:
List<Computer> computers
我可以打电话
List<CPU> CPUs = computer.getCPUs();
我可以致电
String hostname = computer.getHostName();
我想要做的是,使用Streams,获取一个包含CPU密钥的Map和一个包含主机名的String。同一台计算机内的相同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;
}
答案 0 :(得分:1)
如果您的CPU
班级对其Computer
实例有反向引用,那么您可以轻松完成此操作。首先在所有计算机上流式传输,使用getCPUs
进行平面映射,这将为您提供所有CPU的Stream<CPU>
。然后,您可以使用Collectors.toMap
收集Map<CPU, String>
使用Function.identity
作为密钥,并使用lambda首先提取Computer
,然后使用CPU中的主机名获取值。
在代码中:
computers.stream()
.flatMap(computer -> computer.getCPUs().stream())
.collect(Collectors.toMap(Function.identity(), cpu -> cpu.getComputer().getHostname()));
答案 1 :(得分:1)
您可以通过实现自己的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
可能会被视为有点滥用。
答案 2 :(得分:1)
您可以使用中间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));