2017-04-12 18 views
4

Javaのマップのリストから最小値を取得しようとしています。私はflatmap、stream、minの組み合わせを使用しており、期待通りの結果は得られません。ここでは、コード パブリッククラスTestMinは{Java 8ストリームの最小値が期待値を返さない

public static class TestHolder{ 
    public static Map<String,Integer> getValues(){ 
     Map<String,Integer> map = new HashMap<>(); 
     map.put("a",1); 
     map.put("b",3); 
     map.put("c",2); 

     return map; 

    } 
} 

public static void main(String[] args) { 
    List<Map<String, Integer>> l = new ArrayList<>(); 
    l.add(TestHolder.getValues()); 
    l.add(TestHolder.getValues()); 
    l.add(TestHolder.getValues()); 

    // Getting min 
    int min = l.stream().map((m)->m.values()).flatMap((v)->v.stream()).min(Integer::min).get(); 
    System.out.println(min); 
    } 

} 

出力は次のようになります。もちろん、2

、私は期待していた出力は、いくつかのデバッグが、それは価値がに対応する出力を提供していることを示唆しようとすると1です。 "c"。マップは

[a->2 , b->3, c->1] 

のように見える場合すなわちは、その後、私は取得しています出力は、それが値でソートすると、むしろキーでソートすると私に予期しない出力を提供していない理由の質問は1 です。

答えて

6

Stream::minは、Comparator契約に準拠したものを想定しています。しかし、Integer::minはそれをしません、それはちょうどその2つの入力の最小値を返します。代わりにInteger::compareを使用する必要があります。

+0

おかげで、返信用オリバー@。予想どおり、あなたは正しいです。どのように私たちはコンパイル時にこのようなエラーやバグを検出することができますか? – maneet

+0

@maneetできませんが、テストを書くことができます。 – Flown

+1

@maneet - これはロジックバグです。コンパイル時に(コンパイラ:: compareToが 'int'を返すと)それをどのように捕まえることができるのかははっきりしません。 –

0

あなたはIntStreamStream<Integer>を変換するmapToInt()機能を使用して、ちょうどそれにmin()を呼び出すことができます。

int min = l.stream() 
     .map(Map::values) 
     .flatMap(Collection::stream) 
     .mapToInt(Integer::intValue) 
     .min().orElse(defaultMinValue); 
関連する問題