[解決済み] 新しい関数computeIfAbsentの使い方を教えてください。
質問
をぜひ使いたい。 Map.computeIfAbsent が、学部生時代のラムダ以来、久しぶりです。
ほぼ をドキュメントから直接引用したもので、古いやり方の例を示しています。
Map<String, Boolean> whoLetDogsOut = new ConcurrentHashMap<>();
String key = "snoop";
if (whoLetDogsOut.get(key) == null) {
Boolean isLetOut = tryToLetOut(key);
if (isLetOut != null)
map.putIfAbsent(key, isLetOut);
}
そして新しい方法。
map.computeIfAbsent(key, k -> new Value(f(k)));
しかし、彼らの例では、私はそれを理解することができないようです。
どのように解決するのですか?
次のようなコードがあったとします。
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
public static void main(String[] s) {
Map<String, Boolean> whoLetDogsOut = new ConcurrentHashMap<>();
whoLetDogsOut.computeIfAbsent("snoop", k -> f(k));
whoLetDogsOut.computeIfAbsent("snoop", k -> f(k));
}
static boolean f(String s) {
System.out.println("creating a value for \""+s+'"');
return s.isEmpty();
}
}
すると、次のようなメッセージが表示されます。
creating a value for "snoop"
の2回目の起動のときと同じように、1回だけ
computeIfAbsent
には、そのキーに対応する値がすでに存在します。その
k
ラムダ式では
k -> f(k)
は、マップが値を計算するためにラムダに渡すキーのプレースホルダー(パラメータ)に過ぎない。つまり、この例ではキーは関数の呼び出しに渡される。
あるいは、こう書くこともできます。
whoLetDogsOut.computeIfAbsent("snoop", k -> k.isEmpty());
を使えばヘルパーメソッドなしで同じ結果を得ることができます (ただし、その場合はデバッグ用の出力は表示されません)。さらに簡単な方法として、既存のメソッドに単純に委譲することもできます。
whoLetDogsOut.computeIfAbsent("snoop", String::isEmpty);
この委譲では、パラメータを記述する必要はありません。
ご質問の例に近づけると、次のように書くことができます。
whoLetDogsOut.computeIfAbsent("snoop", key -> tryToLetOut(key));
(パラメータの名前が
k
または
key
). または、次のように書きます。
whoLetDogsOut.computeIfAbsent("snoop", MyClass::tryToLetOut);
もし
tryToLetOut
は
static
または
whoLetDogsOut.computeIfAbsent("snoop", this::tryToLetOut);
もし
tryToLetOut
はインスタンスメソッドです。
関連
-
[解決済み] tempとは何ですか、またjavaにおけるtempの用途は何ですか?
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] Pythonで辞書に新しいキーを追加するにはどうすればよいですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] 辞書のリストを辞書の値でソートするにはどうしたらいいですか?
-
[解決済み】Android UserManager.isUserAGoat()の正しい使用例?)
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ボタンでTextFieldをクリアする(Java)
-
[解決済み] このフォーマット(Tue Jul 13 00:00:00 CEST 2010)の日付をJavaの日付に変換する方法(文字列はalfrescoのプロパティに由来しています)
-
[解決済み] なぜJPAには@Transientアノテーションがあるのですか?
-
[解決済み] Java UnknownFormatConversionException
-
[解決済み] javac ソースファイルが見つかりません
-
[解決済み] javascriptでExpression言語を使うには?
-
[解決済み] ファイルを作成せずに、ファイルが存在するかどうかをチェックする
-
[解決済み] どのように配列の10未満の値(x * 2)を倍増するコードを取得するには?(Java)
-
[解決済み] スリーピング中のスレッドが割り込まれ、データベースへの接続が失われる
-
[解決済み] Javaでdoubleをfloatに変換する