7

Pythonスニペットに相当するJavaを探しています

max_valued_key = max(str_to_double_map.keys(), key=lambda x: str_to_double_map[x])

Collections.max のような標準的なものが必要です。他のコンパレータごとにもう 1 つのクラスを作成したくないため、Comparator のインライン定義で
これを行う方法はありますか。

次のコードを試してみましたが失敗しました

depScores = foo();
String dep = Collections.max(depScores.keySet(), new Comparator<String>() {
  @Override
  public int compare(String o1, String o2) {
    return depScores.get(o1).compareTo(depScores.get(o2));
  }
});

depScores 変数はコンパレーターから読み取ることができません。
Javaの内部クラスでは、外部から非最終変数にアクセスできないようです!

前もって感謝します!

4

2 に答える 2

4

depScoresfinal 変数として宣言するだけです。何らかの理由でできない場合は、それを指す 2 番目の (最終的な) 変数を作成します。

ローカル クラスは、変数が final である場合にのみ変数をキャプチャできます。


Comparator(非常に) 遅い補遺として、Java 8 でラムダからカスタムを作成するのは簡単です。

String dep = Collections.max(
    depScores.keySet(),
    Comparator.comparing(k -> depScores.get(k))
);

k -> depScores.get(k)ラムダをメソッド参照に置き換えると、さらに簡潔になりますdepScores::get

のようなローカル変数をキャプチャするための規則depScoreは、内部クラスよりもラムダに対して少し柔軟です: キャプチャされた変数は、実質的に finalのみである必要があります。つまり、明示的にマークする必要はありませんが、1 回だけ割り当てる必要がありますfinal

于 2013-11-05T09:25:02.213 に答える
4

あなたが望むことは、Java 8で可能です(可能になるでしょう):

Map<String,Double> map…
String maxKey=Collections.max(map.keySet(), (x,y)->Double.compare(map.get(x),map.get(y)));

またはさらに短い

String maxKey = Collections.max(map.keySet(), Comparator.comparingDouble(map::get));

以前の Java バージョンでは、以下を使用する必要があります。

String maxKey=Collections.max(map.keySet(), new Comparator<String>(){
    public int compare(String x, String y) {
        return Double.compare(map.get(x),map.get(y));
    }
});

呼び出しの直前に final 変数に代入することで、存在しmapないという問題を回避できます。final

final Map<String,Double> fmap=map;
String maxKey=Collections.max(map.keySet(), new Comparator<String>(){
    public int compare(String x, String y) {
        return Double.compare(fmap.get(x),fmap.get(y));
    }
});

しかし、ハッシュルックアップを必要としないため、次のヘルパーメソッドの方がさらに簡単で効率的だと思います。

static <K,V extends Comparable<V>> K keyForHighestValue(Map<K,V> map) {
    V maxValue=Collections.max(map.values());
    for(Map.Entry<K,V> e:map.entrySet()) {
        if(e.getValue()==maxValue) return e.getKey();
    }
    throw new ConcurrentModificationException();
}
于 2013-11-05T09:27:26.947 に答える