web-dev-qa-db-ja.com

Java 8 HashMapからnullでも空でもない値を抽出

以下を考えてみましょうHashMap

HashMap<String, String> map = new HashMap<String, String>();

私はマップのような値を持っています

map.put("model", "test");

現在、私がやっているマップから値を取得したい場合

if(map!=null){
 if(map.get("model")!=null && !map.get("model").isEmpty()){
   //some logic
 }
}

Java 8にOptionalまたはLambdasを使用して上記の条件を達成するより良い方法はありますか?

13
ppb

マップがnullであるかどうかを確認する理由はわかりませんが、次のとおりです。

Optional.ofNullable(map)
    .map(m -> m.getOrDefault("model", "")) // Use an empty String if not present
    .filter(s -> !s.isEmpty())             // Filter all empty values
    .ifPresent(valueString -> {            // Check if value is present
        // Logic here
});

または1行で:

Optional.ofNullable(map).map(m -> m.getOrDefault("model", "")).filter(s -> !s.isEmpty()).ifPresent(valueString -> {
        // Logic here
});

何かを返したい場合は、ifPresentmapに変更します。つまり、計算するものは何でもオプションです。

6
smac89

まず、Mapをnullにしないでください。決して。空の場合もありますが、nullになる理由はありません。そのため、最初のnullチェックがなくなります。

さて、残念ながら、Javaにはそのようなユーティリティメソッドはありませんが、一般的に使用されるいくつかのライブラリ(Apache commons、Guavaなど)があります。 :

String model = map.get("model");
if (!Strings.isEmptyOrNull(model)) {
    // do somthing
}

ロジックの一部としてオプションを使用してヌル値をラップすることは、アンチパターンと見なされます。オプションは、戻り値の型として使用されるように設計されています。そのため、ここでの使用は推奨しません。

また、オブジェクトの属性を格納するためにマップを使用しているように感じる場合は、マップを使用する代わりに、型付きプロパティを使用して実際のクラスを定義することを検討してください。

12
JB Nizet

Optional アプローチに興味がある場合、

map.get("model")値を Optional.ofNullable にラップし、 Predicate<String>value -> !value.isEmpty()でフィルター処理を実行できます。

if (isNull(map)) { // import static Java.util.Objects.isNull;
    return;        // to minimise nesting
}

Optional.ofNullable(map.get("model"))
        .filter(value -> !value.isEmpty())
        .ifPresent(value -> { ... });
2
Andrew Tobilko

サンプルコードでmapが表示されていると宣言した場合、nullにはならず、チェックする必要はありません。確認したい場合は、アサーションを追加します。

assert map != null;

空の文字列をテストしている場合、考えられるアプローチは、キーが存在しない場合にデフォルトとして空の文字列を使用することです。

if (!map.getOrDefault("model", "").isEmpty()) {
    ...
}

キーが存在しない場合、MapではなくOptionalを返すメソッドがnullに追加されなかったことは残念だと思います。何かのようなもの:

map.getOptional("model").filter(v -> !v.isEmpty()).ifPresent(v -> {
    ...
}

オプションが追加されましたが、「存在しない」ことを意味するnullを返すメソッドを非推奨にするために、古いAPIの手直しはほとんど行われていません。

0
sprinter