java - example - null 값에 대해 jdk8 스트림을 어떻게 관리해야합니까?




java swing border (4)

null을 피하는 방법의 예, 예를 들어 groupingBy 전에 필터 사용

groupingBy 전에 null 인스턴스를 필터링하십시오.

여기에 예제가있다.

MyObjectlist.stream()
            .filter(p -> p.getSomeInstance() != null)
            .collect(Collectors.groupingBy(MyObject::getSomeInstance));

https://code.i-harness.com

자바 개발자 여러분,

나는 JDK8이 아직 릴리즈되지 않았기 때문에 (그리고 지금은 어쨌든 ..) 주제가 조금 in advance 있을지도 모른다는 것을 알고있다.하지만 나는 Lambda 표현에 관한 기사와 특히 스트림으로 알려진 새로운 콜렉션 API와 관련된 부분을 읽었다.

다음은 자바 매거진 기사 에서 제공되는 예제입니다 (수달 인구 알고리즘입니다).

Set<Otter> otters = getOtters();
System.out.println(otters.stream()
    .filter(o -> !o.isWild())
    .map(o -> o.getKeeper())
    .filter(k -> k.isFemale())
    .into(new ArrayList<>())
    .size());

내 질문은 Set 내부 반복의 중간에 수달 중 하나가 null 인 경우 어떻게됩니까?

난 NullPointerException 던져 질 것으로 기대하지만 어쩌면 내가 이전 개발 패러다임 (비 기능성)에 갇혀 오전, 누군가가 나를 처리 할 수있는 방법을 나에게 계몽 수 있습니까?

이것이 실제로 NullPointerException을 던지면,이 기능은 매우 위험하며 아래처럼 사용해야합니다.

  • 개발자가 null 값이 없음을 확인합니다 (어쩌면 이전 .filter (o -> o! = null) 사용).
  • 개발자는 응용 프로그램이 null oter 또는 특수 NullOtter 객체를 처리하지 못하도록합니다.

가장 좋은 옵션 또는 다른 옵션은 무엇입니까?

감사!


스트림에서 null 값을 필터링하려는 경우 java.util.Objects.nonNull (Object)에 대한 메소드 참조 만 사용하면됩니다. 그 문서에서 :

이 메소드는 Predicate , filter(Objects::nonNull)

예 :

List<String> list = Arrays.asList( null, "Foo", null, "Bar", null, null);

list.stream()
    .filter( Objects::nonNull )  // <-- Filter out null values
    .forEach( System.out::println );

그러면 다음과 같이 인쇄됩니다.

Foo
Bar

현재의 사고는 Null을 "허용"하는 것으로 보인다. 즉, 일부 작업은 덜 관대하고 NPE를 던질 수 있지만 일반적으로 허용하기위한 것입니다. Lambda Libraries 전문가 그룹 메일 링리스트 의 nulls , 특히이 메시지 에 대한 설명을 참조하십시오. Doug Lea의 주목할만한 반대와 함께 옵션 # 3 주변의 합의가 나왔다. 그렇습니다. NPE로 파이프 라인이 파열되는 것에 대한 OP의 우려는 유효합니다.

토니 호아레 (Tony Hoare)가 null을 "억 달러의 실수" 라고 언급 한 것은 아무것도 아닙니다 . nulls를 다루는 것은 정말 고통 스럽습니다. 클래식 컬렉션 (람다 또는 스트림을 고려하지 않고)에서도 null이 문제가됩니다. 의견에 언급 된 fge와 같이 일부 컬렉션은 null을 허용하고 다른 컬렉션은 허용하지 않습니다. null을 허용하는 콜렉션에서는 API에 모호한 점이 있습니다. 예를 들어, Map.get ()의 경우, null가 돌려주는 경우는, 키가 존재 해, 그 값이 null의 경우, 또는 키가 결핍하고있는 경우를 나타냅니다. 이러한 경우를 명확히하기 위해 추가 작업을해야합니다.

null의 통상의 사용은 값의 부재를 나타내는 것입니다. Java SE 8에서 제안 된이 문제를 처리하기위한 접근법은 기본값의 제공 또는 예외의 throw와 함께 값의 유무를 캡슐화하는 새로운 java.util.Optional 유형을 도입하거나 함수 등이있다. Optional 은 새로운 API에 의해서만 사용되지만 시스템의 다른 모든 것들은 여전히 ​​null 가능성을 내포해야합니다.

나의 조언은 최대한의 범위에서 실제 null 참조를 피하는 것이다. 어떻게 "null"수달이 될 수 있는지 주어진 예제에서보기가 어렵습니다. 그러나 하나가 필요하다면, null 값을 필터링하거나 센티넬 객체 ( Null Object Pattern )에 매핑하는 OP의 제안은 훌륭한 접근 방법입니다.


대답은 100 % 정확하지만 목록 자체의 null 대 / 소문자를 처리 할 수있는 작은 제안은 선택 사항입니다 .

 List<String> listOfStuffFiltered = Optional.ofNullable(listOfStuff)
                .orElseGet(Collections::emptyList)
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

Optional.ofNullable(listOfStuff).orElseGet(Collections::emptyList)listOfStuff 가 null이고 NullPointerException으로 실패하는 대신 emptyList를 반환 할 때 listOfStuff 합니다.





java-stream