2017-01-13 24 views
3

私はList<Computer>を持っています。すべてのコンピュータには、CPUとホスト名のリストがあります。 だから、私は持っているとしますJava8は、マップ<Object、String>内の[List <Object>、String]を変換します。

List<Computer> computers 

私は

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

を呼び出すことができますし、私は、Streamsを使用している何をしたいのか

String hostname = computer.getHostName(); 

を呼び出すことができ、含まれている地図を入手キーとしてCPUを、Stringとしてホスト名を指定します。同じコンピュータ内の同じCPUがホスト名を複製します。

どうすればいいですか?

前Java8のコードは、これを次のようになります。それはComputerインスタンスのためにあなたのCPUクラスは後方参照を持っている

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

ストリームとラムダの解決策はあなたよりも優れていると思います –

答えて

1

場合、あなたは簡単にこれを行うことができます。すべてのコンピュータ上の最初のストリームとgetCPUsのフラットマップを使用すると、すべてのCPUがStream<CPU>になります。次に、Collectors.toMapを使用してMap<CPU, String>に集め、キーにはFunction.identityを使用し、最初にComputerを抽出し、その値のCPUからホスト名を抽出することができます。コードで :

computers.stream() 
    .flatMap(computer -> computer.getCPUs().stream()) 
    .collect(Collectors.toMap(Function.identity(), cpu -> cpu.getComputer().getHostname())); 
+2

'cpu.getComputer()'メソッドがあると仮定するのは何ですか? – Holger

+0

最初の文章で説明したように、これは合理的な前提であり、ストリーム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

あなたが一緒にCPUとホスト名を保持するために、中間Entryを使用してそれを行うことができます。

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)); 
関連する問題