2017-01-13 183 views
3

我有一個List<Computer>。每臺計算機都有一個CPU和一個主機名的列表。 因此,假設我有:Java8在Map <Object,String>中轉換[List <Object>,String]

List<Computer> computers 

我可以叫

List<CPU> CPUs = computer.getCPUs(); 

,我可以叫

String hostname = computer.getHostName(); 

我想要的,使用流做什麼,獲得含地圖作爲關鍵的CPU和作爲字符串的主機名。相同計算機內的相同CPU將複製主機名。

我該怎麼做?

預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; 
} 
+3

什麼是computer'和'computers''之間的關係。如果你想讓你的問題繼續存在,可以添加完成任務的Java 8之前的代碼。 –

+0

謝謝,我添加了pre java8代碼 –

+1

我認爲沒有流和lambdas解決方案比你已經有的更好 –

回答

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())); 
+2

是什麼引導你假設有'cpu.getComputer()'方法? – Holger

+0

正如我在第一句中解釋的那樣,我假設這是因爲這是一個合理的假設,並且必須使用Stream API乾淨地解決這個問題。如果這樣的方法不存在,流管道將會變得更加低效,因爲我認爲如果沒有中間收集步驟,就無法做到這一點。 – diesieben07

1

您可以通過以相同的值分配到同一臺計算機的所有CPU實現自己Collector做到這一點:

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 i在這種情況下可以認爲是有點濫用。

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)); 
相關問題