繁体   English   中英

Java8转换一个[List <Object> ,字符串]在地图中 <Object, String>

[英]Java8 transform a [List<Object>, String] in a Map<Object, String>

我有一个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;
}

如果您的CPU类具有对其Computer实例的反向引用,那么您可以轻松地执行此操作。 首先在所有计算机getCPUs ,并使用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()));

您可以通过实现自己的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可能会被视为有点滥用。

您可以使用中间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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM