향상된 for 루프의 널 체크


172

Java의 for 루프에서 null을 방지하는 가장 좋은 방법은 무엇입니까?

이것은 추한 것 같습니다 :

if (someList != null) {
    for (Object object : someList) {
        // do whatever
    }
}

또는

if (someList == null) {
    return; // Or throw ex
}
for (Object object : someList) {
    // do whatever
}

다른 방법이 없을 수도 있습니다. 그들이 for구조 자체 에 넣었어야합니까 , null 인 경우 루프를 실행하지 않습니까?


2
NPE를 던지는 것이 좋습니다. null빈 컬렉션과 동일하지 않습니다.
Tom Hawtin-tackline

6
@GregMattes 2 월 질문은 10 월 질문과 어떻게 중복됩니까?
Val

1
Collections.nonNullElementsIn (...) 만 사용하면됩니다 : stackoverflow.com/a/34913556/5637185
Jeffrey Dilley

답변:


227

해당 목록을 어디서 구할 수 있는지 더 잘 확인해야합니다.

빈 목록은 실패하지 않기 때문에 빈 목록 만 있으면됩니다.

이 목록을 다른 곳에서 가져 와서 괜찮은지 모르는 경우 유틸리티 메소드를 작성하여 다음과 같이 사용할 수 있습니다.

for( Object o : safe( list ) ) {
   // do whatever 
 }

물론 safe다음과 같습니다.

public static List safe( List other ) {
    return other == null ? Collections.EMPTY_LIST : other;
}

57
Collections.emptyList ()는 추가 객체 (IIRC)를 할당하지 않습니다.
Jon Skeet

7
@Jon : 나는 항상 내 자신에게 물었다. 그 emptyList java.sun.com/j2se/1.5.0/docs/api/java/util/ 의 사용은 무엇인가… IIRC 란 무엇인가?
OscarRyz

11
IIRC = "정확하게 기억한다면". 그리고 네, Collections.emptyList ()에 대한 모든 호출에 대해 반환되는 싱글 톤 인스턴스가 있습니다.
ColinD

이것은 ... 실제로 질문에 대답하지 않습니다. 왜 대답이 받아 들여 집니까?
Christopher Wirt

1
@ChristopherWirt는 질문에 대답하지 않기 때문에 : D
Tarik

100

null로 전달하면 빈 시퀀스를 반환하는 도우미 메서드를 작성할 수 있습니다.

public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
    return iterable == null ? Collections.<T>emptyList() : iterable;
}

그런 다음 사용하십시오.

for (Object object : emptyIfNull(someList)) {
}

나는 실제로 그렇게 할 것이라고 생각하지 않습니다. 나는 보통 두 번째 양식을 사용합니다. 특히 "또는 throw ex"는 중요합니다. 실제로 null이 아니어야하는 경우 예외를 반드시 처리해야합니다. 당신은 무언가 잘못 되었다는 것을 알고 있지만, 피해의 정도를 모른다. 일찍 중단하십시오.


3
모든 iterable이 목록이 아니기 때문에 Iterable <T> 목록 매개 변수를 Iterable <T> iterable로 변경합니다.
롬보

이 메소드를 사용하여주의하십시오 : Collections 클래스를 사용하기 때문에이 메소드를 사용하면 목록을 변경할 수 없습니다
Tanorix

@tanorix : 어떤 식으로?
Jon Skeet

@JonSkeet Collections 클래스의 emptyList ()가 불변 목록을 반환한다는 것을 알 수 있습니다 : docs.oracle.com/javase/8/docs/api/java/util/… 따라서 사용자가 자신의 목록을 불변으로 바꾸고 싶지 않다면 문제가있다
Tanorix

@tanorix : 그러나이 질문의 요점은 반환 된 값을 반복 하는 것입니다. 그것은 그것을 수정하지 않습니다. 의 그 이유의 반환 형식 emptyIfNull입니다 Iterable<T>- 거기 불행한 일 remove에 대한 방법은 Iterator<T>그것은 분명하지 않다, 그러나 그것은 그것의 유일한 가변 측면의 (? 당신은 하늘의 콜렉션을 가지고있는 경우에, 왜 당신은 그것에서 아무것도를 제거하려고하는) 무엇을 ' 여기에 반대합니다.
Jon Skeet

29

이미 2017이며 이제 Apache Commons Collections4를 사용할 수 있습니다.

사용법 :

for(Object obj : ListUtils.emptyIfNull(list1)){
    // Do your stuff
}

로 다른 Collection 클래스에 대해 동일한 null 안전 검사를 수행 할 수 있습니다 CollectionUtils.emptyIfNull.


2
불필요한 목록 객체를 생성하지만 작동합니다. CollectionUtils.ifNotEmpty가 더 장황하지만 더 효율적이고 빠를 수 있습니다. 그다지 중요하지는 않습니다 ...
Lawrence

2
2017 년에 List.emptyIfNull (list1)
Dima

3
@Lawrence, 메소드는 새로운리스트 객체를 생성하지 않고 Collections.emptyList()내부적으로 사용하며 , 결과적으로 항상 동일한 사전 할당 된 빈 수정 불가능한리스트를 반환합니다.
Yoory N.

myobject.getCompanies (). getAddresses ()를 호출하고 둘 다 List를 반환하고 둘 다 null 일 수 있다면 어떻습니까?
powder366

9

Java 8 사용 Optional:

for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) {
    // do whatever
}

1
간단한 삼항 연산자보다 더 장황 someList != null ? someList : Collections.emptyList()하고 Optional객체 의 인스턴스를 만들고 즉시 버립니다 .
Yoory N.

2
이 몬스터 라인은 간단한 if (someList == null) 문보다 어떻게 우아합니까? 한 줄에 은행 신청서를 작성해 보겠습니다.
Andreas Panagiotidis

8

라이브러리 라이브러리 ArrayUtils.nullToEmpty에서 사용commons-lang

for( Object o : ArrayUtils.nullToEmpty(list) ) {
   // do whatever 
}

이 기능 commons-lang은 대부분의 Java 프로젝트에 포함 된 라이브러리에 있습니다.

// ArrayUtils.nullToEmpty source code 
public static Object[] nullToEmpty(final Object[] array) {
    if (isEmpty(array)) {
        return EMPTY_OBJECT_ARRAY;
    }
    return array;
}

// ArrayUtils.isEmpty source code
public static boolean isEmpty(final Object[] array) {
    return array == null || array.length == 0;
}

이것은 @OscarRyz의 답변과 동일하지만 DRY 만트라를 위해 주목할 가치가 있다고 생각합니다. 참고 항목 평민 - 랭 프로젝트 페이지를. nullToEmptyAPI 문서소스 는 다음과 같습니다.

commons-lang프로젝트 에 포함 할 Maven 항목 ( 아직없는 경우)

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
</dependency>

불행히도 유형에 commons-lang대해서는이 기능을 제공하지 않습니다 List. 이 경우 앞에서 언급 한대로 도우미 메서드를 사용해야합니다.

public static <E> List<E> nullToEmpty(List<E> list)
{
    if(list == null || list.isEmpty())
    {
        return Collections.emptyList();
    }
    return list;
}

7

List구현 한 메소드 호출에서 가져 오는 경우을 반환하지 말고 nullempty를 반환하십시오 List.

구현을 변경할 수 없으면 null검사 가 중단됩니다 . 그것이 될 should't 경우 null는 예외를 throw합니다.

빈 목록을 반환하는 도우미 메서드는 사용하지 않을 수도 있지만 때로는 유용 할 수 있기 때문에 버그를 숨길 수있는 모든 루프에서 호출하는 데 익숙 할 것입니다.


4

위의 답변을 수정 했으므로 Object에서 캐스트 할 필요가 없습니다.

public static <T> List<T> safeClient( List<T> other ) {
            return other == null ? Collections.EMPTY_LIST : other;
}

그런 다음 간단히

for (MyOwnObject ownObject : safeClient(someList)) {
    // do whatever
}

설명 : MyOwnObject :이 경우 List<Integer>MyOwnObject는 정수가됩니다.


1

for 루프에서 null을 효과적으로 방지하는 또 다른 방법은 Google Guava로 컬렉션을 래핑 Optional<T>하는 것입니다.이 컬렉션은 클라이언트가 컬렉션이 있는지 확인해야하므로 효과적으로 빈 컬렉션을 비울 수 있습니다 Optional.isPresent().


1

자신의 정적 null 안전 방법을 작성하는 데 관심이없는 사람은 commons-lang 's를 사용할 수 있습니다 org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object). 예를 들면 다음과 같습니다.

    for (final String item : 
    (List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) { ... }

ObjectUtils.defaultIfNull JavaDoc


나에게이 답변은 가장 우아합니다
Truong Nguyen

0

CollectionUtils.isEmpty(Collection coll)지정된 컬렉션이 비어 있으면 Null 안전 검사 방법을 사용하십시오 .

이것을 위해 import org.apache.commons.collections.CollectionUtils.

메이븐 의존성

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>

-4
for (Object object : someList) {

   // do whatever
}  throws the null pointer exception.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.