web-dev-qa-db-ja.com

Java 8での複数のnullチェック

複数のヌルチェックには少しい以下のコードがあります。

String s = null;

if (str1 != null) {
    s = str1;
} else if (str2 != null) {
    s = str2;
} else if (str3 != null) {
    s = str3;
} else {
    s = str4;
}

そこで、Optional.ofNullable以下のようになりますが、誰かが私のコードを読んだとしても理解するのは依然として困難です。 Java 8。

String s = Optional.ofNullable(str1)
                   .orElse(Optional.ofNullable(str2)
                                   .orElse(Optional.ofNullable(str3)
                                                   .orElse(str4)));

Java 9では、Optional.ofNullablewith OR、しかしJava8には他のアプローチはありますか?

96
sparker

次のようにできます:

String s = Stream.of(str1, str2, str3)
    .filter(Objects::nonNull)
    .findFirst()
    .orElse(str4);
169

三項条件演算子はどうですか?

String s = 
    str1 != null ? str1 : 
    str2 != null ? str2 : 
    str3 != null ? str3 : str4
;
72
Eran

ループを使用することもできます:

String[] strings = {str1, str2, str3, str4};
for(String str : strings) {
    s = str;
    if(s != null) break;
}
33
ernest_k

現在の答えはいいですが、あなたは本当にそれをユーティリティメソッドに入れるべきです:

public static Optional<String> firstNonNull(String... strings) {
    return Arrays.stream(strings)
            .filter(Objects::nonNull)
            .findFirst();
}

そのメソッドは私のUtilクラスに何年もあり、コードをよりきれいにします:

String s = firstNonNull(str1, str2, str3).orElse(str4);

ジェネリックにすることもできます:

@SafeVarargs
public static <T> Optional<T> firstNonNull(T... objects) {
    return Arrays.stream(objects)
            .filter(Objects::nonNull)
            .findFirst();
}

// Use
Student student = firstNonNull(student1, student2, student3).orElseGet(Student::new);
26
walen

私は次のようなヘルパー関数を使用します

T firstNonNull<T>(T v0, T... vs) {
  if(v0 != null)
    return v0;
  for(T x : vs) {
    if (x != null) 
      return x;
  }
  return null;
}

次に、この種のコードは次のように記述できます。

String s = firstNonNull(str1, str2, str3, str4);
13

必要な数の要素に適用できるソリューションは次のとおりです。

Stream.of(str1, str2, str3, str4)
      .filter(Object::nonNull)
      .findFirst()
      .orElseThrow(IllegalArgumentException::new)

以下のようなソリューションを想像できますが、最初のソリューションではnon nullityすべての要素

Stream.of(str1, str2, str3).....orElse(str4)
4
azro

また、すべての文字列を文字列の配列にまとめてから、forループを実行して、割り当てられたループをチェックして中断することもできます。 s1、s2、s3、s4がすべて文字列であると仮定します。

String[] arrayOfStrings = {s1, s2, s3};


s = s4;

for (String value : arrayOfStrings) {
    if (value != null) { 
        s = value;
        break;
    }
}

何も割り当てられていない場合のデフォルトの条件をs4にスローするように編集されました。

3
danielctw

メソッドベースでシンプル。

String getNonNull(String def, String ...strings) {
    for(int i=0; i<strings.length; i++)
        if(strings[i] != null)
             return s[i];
    return def;
}

そしてそれを次のように使用します:

String s = getNonNull(str4, str1, str2, str3);

配列を使用するのは簡単で、きれいに見えます。

3
Madhusoodan P