[java] 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.ofNullable함께 사용할 수 있지만 ORJava8에는 다른 접근 방식이 있습니까?



답변

다음과 같이 할 수 있습니다.

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


답변

삼항 조건 연산자는 어떻습니까?

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


답변

루프를 사용할 수도 있습니다.

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


답변

현재 답변은 좋지만 실제로 유틸리티 메서드에 넣어야합니다.

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);


답변

나는 다음과 같은 도우미 기능을 사용합니다.

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);


답변

원하는만큼 많은 요소에 적용 할 수있는 솔루션은 다음과 같습니다.

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

아래와 같은 솔루션을 상상할 수 있지만 첫 번째 솔루션 non nullity은 모든 요소를 보장 합니다.

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


답변

또한 모든 문자열을 String 배열로 묶은 다음 for 루프를 수행하여 할당 된 루프를 확인하고 중단 할 수 있습니다. s1, s2, s3, s4가 모두 문자열이라고 가정합니다.

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


s = s4;

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

할당되지 않은 경우 기본적으로 s4에 대한 조건을 던지도록 편집되었습니다.