ProgramingTip

null 값에 대한 jdk8 스트림을 관리하는 방법

bestdevel 2020. 10. 11. 10:58
반응형

null 값에 대한 jdk8 스트림을 관리하는 방법


안녕하세요, Java 개발자 여러분,

in advanceJDK8이 아직 출시되지 않았기 때문에 주제가 약간 다를 수 있습니다. (지금은 아닙니다.) Lambda 즉, 특히 스트림에서 새로운 컬렉션 API와 부분을 의미합니다.

다음은 Java Magazine 기사에 어떤 예입니다 (수달 개체 수 알고리즘입니다 ..).

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

내 질문은 내부 반복 중간에 수달 중 하나가 null이면 어떻게 검증?

NullPointerException이 보관 될 예정이지만 이전 개발 패러다임 (비 기능적)에 여전히 갇혀있을 수 있습니다. 어떤 문제를 어떻게 처리해야합니까?

이것은 NullPointerException을 던진다면,이 기능이 매우 위험합니다.

  • 개발자는 null 값이 없는지 확인합니다 (이전 .filter (o-> o! = null) 사용).
  • 개발자는 응용 프로그램이 처리 할 NullOtter 또는 특수 NullOtter 개체를 생성하지 않습니다.

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

감사합니다!


현재의 생각은 null을 "허용"하는 추천합니다. 즉, 일부 작업은 덜 관대하고 결국 NPE를 던질 수있는 것이 일반적으로이를입니다. Lambda Libraries 전문가 그룹 메일 링리스트에서 null대한 논의, 특히이 메시지를 참조하십시오 . 이후 옵션 # 3에 대한 언급가가습니다. (Doug Lea의 주목할만한 반대). 네, NPE로 폭파되는 파이프 라인에 대한 OP의 우려는 유효합니다.

Tony Hoare가 null을 "Billion Dollar Mistake" 라고 말한 것은 아무것도 아닙니다 . null을 다루는 것은 진짜 고통입니다. 클래식 컬렉션 (람다 또는 스트림을 고려하지 않음) 모두 null은 문제가됩니다. 으로 FGE가 사용할 수 있습니다. null을 허용하는 컬렉션을 사용하면 API에 모호함이 생약. 예를 들어 Map.get () 에서 null 반환은 키가 있고 해당 값이 null이거나 키가 없음을 나타냅니다. 설치하기 위해 추가 작업을 수행해야합니다.

null의 일반적인 사용은 값이 없습니다. Java SE 8에 대해 제안 된이를 처리하기위한 제안을 던지거나 함수를 호출하는 등의 동작과 캡슐화 하는 값의 존재 / 부재를 함께 캡슐화 하는 새로운 유형 을 도입하는 것입니다. 값이 없습니다. 새 API는 여전히 사용하는 시스템의 다른 모든 가능성을 감안해야합니다.java.util.OptionalOptional

내 조언은 실제 null 참조를 최대한 피하는 것입니다. "null"은 누구에게 있는지 수달이 있습니다. 그러나 필요한 경우 OP의 null 값을 필터링하거나 센티넬 객체 ( Null Object Pattern )에 매핑하는 것이 좋은 방법입니다.


답변은 100 % 보장하지만 Optionalnull 을 사용하여 자체 케이스 처리 를 개선하기위한 작은 제안입니다 .

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

이 부분 Optional.ofNullable(listOfStuff).orElseGet(Collections::emptyList)을 사용하면 listOfStuffnull 인 경우 멋지게 처리 하고 NullPointerException으로 실패하는 대신 emptyList를 반환 할 수 있습니다.


Stuart의 답변은 훌륭한 설명을 제공하지만 다른 예를 제공하고 싶습니다.

reducenull 값을 포함하는 스트림에서 문제가 발생했습니다 (실제로 LongStream.average()는 축소 유형입니다). average ()이 반환하기 때문에 OptionalDoubleStream에 null이 가정했지만 NullPointerException이 발생했습니다. 이것은 Stuart 가 null v. empty에 대한 설명 때문 입니다.

따라서 OP에서 알 수있는 다음과 같은 필터를 추가했습니다.

list.stream()
    .filter(o -> o != null)
    .reduce(..);

또는 아래에서 지적한 tangens처럼 Java API에서 제공하는 술어를 사용하십시오.

list.stream()
    .filter(Objects::nonNull)
    .reduce(..);

메일 링리스트 토론에서 스튜어트가 링크 됨 : Brian Goetz on nulls in Streams


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

이 방법은 술어 로 사용하기 위해 존재합니다 .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을 피하는 방법 예. groupingBy 전에 필터 사용

groupingBy 전에 null 인스턴스를 필터링합니다.

다음은 예입니다.

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

참고 URL : https://stackoverflow.com/questions/17081063/how-should-we-manage-jdk8-stream-for-null-values

반응형