web-dev-qa-db-ja.com

Map(Key、Double)の最小値を取得します

Map(Key, Double)の最小値を取得するメソッド(おそらくGoogleコレクションを使用)はありますか?

従来の方法では、値に従ってマップをソートし、最初/最後のマップを使用する必要がありました。

25
user326667

これには標準の Collections#min() を使用できます。

_Map<String, Double> map = new HashMap<String, Double>();
map.put("1.1", 1.1);
map.put("0.1", 0.1);
map.put("2.1", 2.1);

Double min = Collections.min(map.values());
System.out.println(min); // 0.1
_

更新:キーも必要なので、 Collections に方法がありませんまたはGoogle _Collections2_MapCollectionではないため、API。 Maps#filterEntries() も実際には役に立ちません。反復のendでの実際の結果しかわからないためです。

その場合、最も簡単な解決策は次のようになります。

_Entry<String, Double> min = null;
for (Entry<String, Double> entry : map.entrySet()) {
    if (min == null || min.getValue() > entry.getValue()) {
        min = entry;
    }
}

System.out.println(min.getKey()); // 0.1
_

(左側のminのヌルチェック)

48
BalusC

引き続きCollections.minカスタムComparatorを使用してMap.Entryより低い値:

Map<String, Double> map = new HashMap<String, Double>();
map.put("1.1", 1.1);
map.put("0.1", 0.1);
map.put("2.1", 2.1);
Entry<String, Double> min = Collections.min(map.entrySet(), new Comparator<Entry<String, Double>>() {
    public int compare(Entry<String, Double> entry1, Entry<String, Double> entry2) {
        return entry1.getValue().compareTo(entry2.getValue());
    }
});
System.out.printf("%s: %f", min.getKey(), min.getValue()); // 0.1: 0.100000

Java 8の場合:

Entry<String, Double> min = Collections.min(map.entrySet(),
                                       Comparator.comparing(Entry::getValue));
19
superfav

従来の方法では、値に従ってマップをソートし、最初/最後のマップを使用する必要がありました。ありがとう

いいえ、しません。すべての値を反復処理し、各ステップで現在の要素をこれまでに見た最小の要素と比較する必要があります。これはO(n)です。並べ替えのO(n * log(n))と比較すると、潜在的にhugeの違いです。

ところで、これがまさにCollections.min()の仕組みです。

5

Java 8ストリームを使用:

return map
            .entrySet()
            .stream()
            .sorted(Comparator.comparingDouble(Map.Entry::getValue))
            .findFirst()
            .map(Map.Entry::getValue);

または

return map
            .entrySet()
            .stream()
            .min(Comparator.comparingDouble(Map.Entry::getValue))
            .map(Map.Entry::getValue);

ただし、複数回実行する場合は、必ず heap を確認してください。

4
voho

Java8ワンライナー

Key key = Collections.min(map.entrySet(), Map.Entry.comparingByValue()).getKey()
3
Ankit Sharma

GoogleコレクションBiMapを使用する傾向があります。

     String minKey = HashBiMap.create(map).inverse().get(Collections.min(map.values()));

またはそのようなもの(テストされていません)。

2
Yishai

これを効率的に行うために、独自のデータ構造を定義して、Mapインターフェースを実装するだけでなく、効率的なgetMin()操作を可能にすることもできます。

これは、マップとツリー(またはヒープデータ構造)の2つの内部データ構造を使用して実行できます。新しいペア(K、V)が追加されるたびに、それらをマップに追加し、ツリーにも(単一のエントリとして)追加します。これにより、get(Key)操作にはO(1)時間、追加、削除、およびgetMin操作にはO(log n)時間を使用できます。

1
Eyal Schneider

Java 8(および静的インポート)を使用します。@ superfavのソリューションをより整然とすることができます。

Map<String, Double> myMap;
String theKeyWithHighestValue = Collections.min(myMap.entrySet(), comparingDouble(Entry::getValue)).getKey()
1
Tarrasch

Java 8では、簡単に取得できます。

Double minValue = map.entrySet().stream().min(Map.Entry.comparingByValue()).get().getValue();
Double maxValue = map.entrySet().stream().max(Map.Entry.comparingByValue()).get().getValue();
1
Az.MaYo