2016-04-12 9 views
3

として返す:私はカテゴリごとに安い製品を含むリストを返したいさまざまなカテゴリと価格の製品のリストを、属性によって最小値を検索し、私はこれに似たクラス持たリスト

public class Product{ 
    public Integer category; 
    public Integer price;  

    // getters and setters omitted 
} 

を。私は、これをキーとしてカテゴリを持つ地図として取得する方法を見つけましたが、リストを用意したいと思います。それを行うための簡潔で読みやすい方法は何ですか?

これは私のマップを与えること、私がこれまで持っているものです。

Map<String, Product> cheapestProducts = products.stream() 
    .collect(
     groupingBy(              
      Product::getCategory, 
       collectingAndThen(minBy(comparing(Product::getPrice)), p -> p.get()) 
     ) 
    ); 
+1

わかりません。あなたのコードは 'Map 'を返すでしょうか?なぜそれを 'Map >'に格納しようとしていますか?あなたが 'Map'を持っているときに' values() 'を呼び出すことができます。 – Tunaki

+0

'製品 'とは何ですか? –

+2

'Map'で' .values() 'を呼び出すだけで' Collection 'を得ることができます。 'List'でなければならない場合、そのコレクションを' ArrayList(Collection) 'コンストラクタに渡します。 'Collector'の中にそのすべてが必要な場合は' collectingAndThen'を使うことができます。 – Holger

答えて

2

あなたは)(toMapメソッドを使用して、map.values呼び出すことができます。

Collection<Product> cheapestProducts = products 
      .stream() 
      .collect(Collectors.toMap(t -> t.category, u -> u, 
        (a, b) -> a.price > b.price ? b : a)) 
      .values(); 

また本当にあれば、上記のホルガーさんのコメントを見ますリストがほしい。

0

あなたはこのような何かを行うことができ、リストにマップから値を取得するには...

List<Value> list = new ArrayList<Value>(map.values()); 
1

私の意見では、あなたの方法はOKです。問題は可読性であり、解決策は私の意見では必要に応じて再利用可能なメソッドを抽出することです。 Java 8ストリームは流暢であるなど、ストリームは20行の長さにすることが多く、読みやすさに害を及ぼします。だからminByOptional::getをカプセル化するメソッドgetMinBy()(多分より良い名前があります)を抽出すると、私の意見では読みやすくなります。もちろん、メソッド自体は簡潔ではありませんが、再利用可能です。

Map<Integer, Product> cheapestProducts = products.stream() 
      .collect(
        groupingBy(
          Product::getCategory, 
          getMinBy(Product::getPrice) 
        )); 


    private static <T,C extends Comparable<? super C>> Collector<T, ?, T> getMinBy(Function<T, C> comparatorFunction) { 
     return collectingAndThen(minBy(comparing(comparatorFunction)), Optional::get); 
    } 
関連する問題