null 안전 compareTo () 구현을 단순화하는 방법은 무엇입니까?


156

다음 compareTo()과 같은 간단한 클래스에 대한 메소드를 구현 하고 있습니다 ( Collections.sort()Java 플랫폼에서 제공하는 기타 기능 을 사용할 수 있음 ).

public class Metadata implements Comparable<Metadata> {
    private String name;
    private String value;

// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}

이 객체 의 자연스러운 순서 는 1) 이름으로 정렬하고 2) 이름이 같은 경우 값으로 정렬 하고 싶습니다 . 두 비교는 대소 문자를 구분하지 않아야합니다. 두 필드 모두 널 (NULL) 값이 완벽하게 허용되므로이 compareTo경우에는 깨지지 않아야합니다.

마음에 떠오르는 해결책은 다음과 같습니다 (여기서는 "guard 조항"을 사용하고 있지만 다른 사람들은 단일 리턴 포인트를 선호 할 수도 있지만 요점은 아닙니다) :

// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(Metadata other) {
    if (this.name == null && other.name != null){
        return -1;
    }
    else if (this.name != null && other.name == null){
        return 1;
    }
    else if (this.name != null && other.name != null) {
        int result = this.name.compareToIgnoreCase(other.name);
        if (result != 0){
            return result;
        }
    }

    if (this.value == null) {
        return other.value == null ? 0 : -1;
    }
    if (other.value == null){
        return 1;
    }

    return this.value.compareToIgnoreCase(other.value);
}

이것이 작동하지만이 코드에 완전히 만족하지는 않습니다. 분명히 그것은 매우 복잡하지는 않지만 매우 장황하고 지루합니다.

문제는 어떻게 이것을 덜 장황하게 만들 것입니다 기능을 유지하면서 입니까? 도움이된다면 Java 표준 라이브러리 또는 Apache Commons를 참조하십시오. 이것을 조금 더 간단하게 만드는 유일한 옵션은 내 "NullSafeStringComparator"를 구현하고 두 필드를 비교하는 데 적용하는 것입니까?

편집 1-3 : 에디의 권리; 위의 "둘 다 이름이 null"인 경우 수정

허용 된 답변

물론 Java 1.6에서 2009 년에이 질문을했습니다. 당시 Eddie의 순수한 JDK 솔루션 이 제가 가장 선호하는 대답이었습니다. 나는 지금까지 (2017)까지 그것을 바꾸지 못했습니다.

도 있습니다 제 3 자 라이브러리 솔루션 2009 아파치 코 몬즈 컬렉션 하나 2013 구아바 하나 -a, 모두에 의해 게시 나-것을 나는 어떤 시점에서 선호 않았다가.

이제 Lukasz Wiktor 의 깨끗한 Java 8 솔루션을 정답으로 만들었습니다 . Java 8의 경우 분명히 선호되며 요즘에는 거의 모든 프로젝트에서 Java 8을 사용할 수 있습니다.


답변:


173

Java 8 사용 :

private static Comparator<String> nullSafeStringComparator = Comparator
        .nullsFirst(String::compareToIgnoreCase); 

private static Comparator<Metadata> metadataComparator = Comparator
        .comparing(Metadata::getName, nullSafeStringComparator)
        .thenComparing(Metadata::getValue, nullSafeStringComparator);

public int compareTo(Metadata that) {
    return metadataComparator.compare(this, that);
}

7
Apache Commons Lang을 위해 Java 8 내장 기능 사용을 지원하지만 Java 8 코드는 매우 추악하고 여전히 장황합니다. org.apache.commons.lang3.builder.CompareToBuilder를 고수하겠습니다.
— jschreiner

1
null 객체에서 compareTo ()를 호출하려고 시도하기 때문에 Collections.sort (Arrays.asList (null, val1, null, val2, null))에서는 작동하지 않습니다. 솔직히 말해서 컬렉션 프레임 워크에 문제가있는 것처럼 보이며 이것을 모방하는 방법을 알아 내려고합니다.
— Pedro Borges는

3
@PedroBorges 저자는 null 컨테이너 참조를 정렬하는 것이 아니라 정렬 가능한 필드를 가진 컨테이너 객체 (그 필드가 null 일 수 있음)를 정렬하는 방법에 대해 물었다. 따라서 주석이 정확 Collections.sort(List)하지만 목록에 null이 포함되어 있으면 작동하지 않지만 주석은 질문과 관련이 없습니다.
— Scrubbie

211

Apache Commons Lang을 간단하게 사용할 수 있습니다 .

result = ObjectUtils.compare(firstComparable, secondComparable)

4
(@Kong : 이것은 원래의 질문의 또 다른 측면 인 널 안전을 고려하지만 대소 문자를 구분하지는 않습니다. 따라서 허용 된 답변을 변경하지 않습니다.)
— Jonik

3
또한, 내 마음에 아파치 코 몬즈는 2013 년 (. 일부 하위 프로젝트가 더 나은 다른 사람보다 유지하는 경우에도)에서 허용 대답 안 구아바이 같은 일을 달성하는 데 사용할 수 있습니다 ; nullsFirst()/를 참조하십시오 nullsLast().
— Jonik

8
@Jonik 왜 2013 년에 Apache Commons가 받아 들여지지 않아야한다고 생각하십니까?
— reallynice

1
Apache Commons의 대부분은 레거시 / 잘 관리되지 않은 / 품질이 낮은 것입니다. 구아바 와 같이 제공하는 대부분의 것들에 대한 더 나은 대안이 있습니다. 구아바 는 전체적으로 매우 고품질의 라이브러리이며 점점 JDK 자체입니다. 2005 년경 아파치 커먼즈 (Apache Commons)는 똥 이었지만 요즘에는 대부분의 프로젝트에서 필요하지 않습니다. (예를 들어, 어떤 이유로 FTP 클라이언트가 필요한 경우 Apache Commons Net 등에서 사용하는 등의 예외가 있습니다.)
— Jonik

6
@Jonik, Guava를 사용하여 질문에 어떻게 대답 하시겠습니까? Apache Commons Lang (패키지 org.apache.commons.lang3)이 "레거시 / 부족하게 유지 보수 / 품질이 낮음" 이라는 귀하의 주장 은 허위이거나 최선의 근거가 없습니다. Commons Lang3은 이해하기 쉽고 사용하기 쉽고 적극적으로 유지됩니다. 아마도 가장 많이 사용되는 라이브러리 일 것입니다 (Spring Framework 및 Spring Security 제외) . 예를 들어 null 안전 메서드가 있는 StringUtils 클래스는 입력 정규화를 간단하게 만듭니다.
— Paul

93

null 안전 비교기를 구현합니다. 구현이있을 수 있지만 구현하기가 너무 간단하여 항상 내 자신을 굴 렸습니다.

참고 : 위의 비교기 는 두 이름이 모두 null 인 경우 값 필드도 비교하지 않습니다. 나는 이것이 당신이 원하는 것이라고 생각하지 않습니다.

나는 이것을 다음과 같이 구현할 것이다 :

// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(final Metadata other) {

    if (other == null) {
        throw new NullPointerException();
    }

    int result = nullSafeStringComparator(this.name, other.name);
    if (result != 0) {
        return result;
    }

    return nullSafeStringComparator(this.value, other.value);
}

public static int nullSafeStringComparator(final String one, final String two) {
    if (one == null ^ two == null) {
        return (one == null) ? -1 : 1;
    }

    if (one == null && two == null) {
        return 0;
    }

    return one.compareToIgnoreCase(two);
}

편집 : 코드 샘플의 오타가 수정되었습니다. 그것이 먼저 테스트하지 않은 결과입니다!

편집 : nullSafeStringComparator를 정적으로 승격했습니다.


2
중첩 된 "if"와 관련하여 ...이 경우 읽기가 쉽지 않을 경우 중첩을 피하므로 피하십시오. 그렇습니다. 때때로 이것 때문에 불필요한 비교가있을 것입니다. 매개 변수에 대한 final은 필요하지 않지만 좋은 생각입니다.
— Eddie

31
XOR의 달콤한 사용
— James McMahon

9
@phihag-3 년 넘게 알고 있지만 final키워드는 실제로 필요하지 않습니다 (자바 코드는 이미 자세하게 장황합니다). 그러나 매개 변수를 로컬 변수 (재미있는 코딩 방법)로 재사용하지 못합니다. 소프트웨어에 대한 우리의 총체적인 이해는 시간이 지남에 따라 더 나아질 것입니다. 그래서 나는 final매개 변수 선언 (함수가 사소한 것일 수도 있음)을 사용하는 데 약간의 자세한 설명을 선호합니다 inmutability-by-quasi-default.) 그것의 이해력 / 유지 보수 오버 헤드는 웅대 한 계획에서 무시할 수 있습니다.
— luis.espinal

24
@ James McMahon 나는 동의하지 않는다. Xor (^)는 단순히 같지 않음 (! =)으로 바꿀 수 있습니다. 심지어 동일한 바이트 코드로 컴파일됩니다. ! = vs ^의 사용법은 맛과 가독성의 문제 일뿐입니다. 그래서 당신이 놀랐다는 사실로 판단하면 그것이 여기에 속하지 않는다고 말할 것입니다. 체크섬을 계산할 때 xor를 사용하십시오. 대부분의 다른 경우 (이것과 같이)! =를 고수합시다.
— bvdb

5
<T extends Comparable <T >> ...로 선언 된 String을 T, T로 바꾸면이 대답을 쉽게 확장 할 수 있으며, nullable Comparable 객체를 안전하게 비교할 수 있습니다
— Thierry

20

구아바를 사용한 업데이트 된 (2013) 솔루션에 대해서는이 답변의 하단을 참조하십시오.


이것이 내가 궁극적으로했던 것입니다. 우리는 이미 널 안전 문자열 비교를위한 유틸리티 메소드를 가지고 있었으므로 가장 간단한 해결책은 그것을 사용하는 것입니다. (이것은 큰 코드베이스입니다. 이런 종류를 놓치기 쉽습니다 :)

public int compareTo(Metadata other) {
    int result = StringUtils.compare(this.getName(), other.getName(), true);
    if (result != 0) {
        return result;
    }
    return StringUtils.compare(this.getValue(), other.getValue(), true);
}

이것은 헬퍼가 정의되는 방법입니다 (원하는 경우 널이 맨 처음에 오는지 또는 마지막에 오는지를 정의 할 수 있도록 오버로드됩니다).

public static int compare(String s1, String s2, boolean ignoreCase) { ... }

따라서 이것은 본질적으로 Eddie의 대답 (정적 도우미 메서드를 비교 자라고 부르지는 않지만 )과 uzhin의 답변 과 동일 합니다 .

어쨌든, 가능한 한 확립 된 라이브러리를 사용하는 것이 좋은 습관이라고 생각하기 때문에 Patrick의 솔루션을 강력하게 선호했을 것 입니다. ( 라이브러리를 알고 사용하십시오 조쉬 블로흐가 말하는대로.)하지만이 경우 그 깨끗한, 간단한 코드를 굴복 않았을 것이다.

편집 (2009) : Apache Commons Collections 버전

실제로 여기에 Apache Commons 기반 솔루션을 NullComparator더 단순 하게 만드는 방법이 있습니다. 클래스 에서 제공되는 대소 문자를 구분하지 않고Comparator 결합하십시오 String.

public static final Comparator<String> NULL_SAFE_COMPARATOR 
    = new NullComparator(String.CASE_INSENSITIVE_ORDER);

@Override
public int compareTo(Metadata other) {
    int result = NULL_SAFE_COMPARATOR.compare(this.name, other.name);
    if (result != 0) {
        return result;
    }
    return NULL_SAFE_COMPARATOR.compare(this.value, other.value);
}

지금 이것은 매우 우아합니다. (작은 사안 하나만 남아 있습니다 : 커먼즈NullComparator 는 제네릭을 지원하지 않으므로 확인되지 않은 할당이 있습니다.)

업데이트 (2013) : 구아바 버전

거의 5 년 후 여기에 제가 원래의 질문에 어떻게 대처할 수 있는지가 나와 있습니다. Java로 코딩하는 경우 (물론) Guava를 사용하고 있습니다 . (그리고 확실히 아닙니다 Apache Commons는 .)

이 상수를 "StringUtils"클래스와 같은 곳에 두십시오.

public static final Ordering<String> CASE_INSENSITIVE_NULL_SAFE_ORDER =
    Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsLast(); // or nullsFirst()

그런 다음 public class Metadata implements Comparable<Metadata>:

@Override
public int compareTo(Metadata other) {
    int result = CASE_INSENSITIVE_NULL_SAFE_ORDER.compare(this.name, other.name);
    if (result != 0) {
        return result;
    }
    return CASE_INSENSITIVE_NULL_SAFE_ORDER.compare(this.value, other.value);
}    

물론 이것은 Apache Commons 버전 (JDK의 CASE_INSENSITIVE_ORDER 모두 사용)과 거의 동일하며, nullsLast()구아바 고유의 유일한 사용입니다 . 이 버전은 Guava가 Commons Collections에 대한 종속성으로 선호되기 때문에 간단합니다. ( 모두 동의 .)

궁금한 Ordering점이 있으면 구현한다는 점에 유의하십시오 Comparator. 더 복잡한 정렬 요구에 특히 편리합니다. 예를 들어을 사용하여 여러 주문을 연결할 수 있습니다 compound(). 자세한 내용은 주문을 읽으십시오 !


2
String.CASE_INSENSITIVE_ORDER는 실제로 솔루션을 훨씬 깨끗하게 만듭니다. 좋은 업데이트.
— Patrick

2
어쨌든 Apache Commons를 사용 ComparatorChain하는 경우 고유 한 compareTo방법이 필요하지 않습니다 .
— amoebe

13

필자는 아파치 커먼즈를 사용하는 것이 좋습니다. 아파치 커먼즈는 스스로 작성할 수있는 것보다 낫기 때문입니다. 또한 재창조보다는 '실제'작업을 수행 할 수 있습니다.

관심있는 클래스는 Null Comparator 입니다. 널을 높이거나 낮출 수 있습니다. 또한 두 값이 null이 아닌 경우 사용할 고유 비교기를 제공합니다.

귀하의 경우 비교를 수행하는 정적 멤버 변수를 가질 수 있으며 compareTo메소드는이를 참조합니다.

같은 것

class Metadata implements Comparable<Metadata> {
private String name;
private String value;

static NullComparator nullAndCaseInsensitveComparator = new NullComparator(
        new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                // inputs can't be null
                return o1.compareToIgnoreCase(o2);
            }

        });

@Override
public int compareTo(Metadata other) {
    if (other == null) {
        return 1;
    }
    int res = nullAndCaseInsensitveComparator.compare(name, other.name);
    if (res != 0)
        return res;

    return nullAndCaseInsensitveComparator.compare(value, other.value);
}

}

자신의 롤을 결정 하더라도이 클래스를 염두에 두십시오.이 클래스는 null 요소를 포함하는 목록을 주문할 때 매우 유용하기 때문입니다.


고마워, 나는 커먼즈에 이런 것이 있기를 바랐습니다! 그러나이 경우, 나는 그것을 사용하여 끝나지 않았다 : stackoverflow.com/questions/481813/...
— Jonik

String.CASE_INSENSITIVE_ORDER;를 사용하여 접근 방식을 단순화 할 수 있다는 것을 깨달았습니다. 편집 한 후속 답변을 참조하십시오.
— Jonik

이것은 좋지만 "if (other == null) {"검사는 없어야합니다. Javadoc for Comparable에 따르면 other가 null 인 경우 compareTo는 NullPointerException을 발생시켜야합니다.
— Daniel Alexiuc

7

null 값을 지원해야한다고 말했기 때문에 귀하의 질문에 직접 대답하지 못할 수도 있습니다.

그러나 compareTo에서 null 지원 은 Comparable 공식 javadocs에 설명 된 compareTo 계약과 일치하지 않습니다 .

null은 어떤 클래스의 인스턴스도 아니며 e.compareTo (null)은 e.equals (null)이 false를 반환하더라도 NullPointerException을 발생시켜야합니다.

따라서 NullPointerException을 명시 적으로 throw하거나 null 인수가 역 참조 될 때 처음으로 throw되도록합니다.


4

방법을 추출 할 수 있습니다.

public int cmp(String txt, String otherTxt)
{
    if ( txt == null )
        return otjerTxt == null ? 0 : 1;

    if ( otherTxt == null )
          return 1;

    return txt.compareToIgnoreCase(otherTxt);
}

public int compareTo(Metadata other) {
   int result = cmp( name, other.name); 
   if ( result != 0 )  return result;
   return cmp( value, other.value); 

}


2
"0 : 1"이 "0 : -1"이 아니어야합니까?
— Rolf Kristensen

3

클래스를 불변으로 설계 할 수 있습니다 (Effective Java 2nd Ed.에는 이것에 대해 훌륭한 섹션이 있습니다 (항목 15 : 변경 가능성 최소화)) null이 불가능한 구성을 확인하십시오 ( 필요한 경우 null 객체 패턴을 사용하십시오 ). 그런 다음 모든 검사를 건너 뛰고 값이 null이 아니라고 가정 할 수 있습니다.


예, 그것은 일반적으로 좋은 해결책이며 많은 것들을 단순화합니다. 그러나 여기서는 어떤 이유로 null 값이 허용되고 고려되어야하는 경우에 더 관심이있었습니다 :)
— Jonik

2

나는 비슷한 것을 찾고 있었고 이것은 조금 복잡해 보였으므로 이것을했습니다. 이해하기가 조금 더 쉽다고 생각합니다. 비교기 또는 하나의 라이너로 사용할 수 있습니다. 이 질문에서는 compareToIgnoreCase ()로 변경합니다. 있는 그대로 널이 뜬다. 싱크하려는 경우 1, -1을 뒤집을 수 있습니다.

StringUtil.NULL_SAFE_COMPARATOR.compare(getName(), o.getName());

.

public class StringUtil {
    public static final Comparator<String> NULL_SAFE_COMPARATOR = new Comparator<String>() {

        @Override
        public int compare(final String s1, final String s2) {
            if (s1 == s2) {
                //Nulls or exact equality
                return 0;
            } else if (s1 == null) {
                //s1 null and s2 not null, so s1 less
                return -1;
            } else if (s2 == null) {
                //s2 null and s1 not null, so s1 greater
                return 1;
            } else {
                return s1.compareTo(s2);
            }
        }
    }; 

    public static void main(String args[]) {
        final ArrayList<String> list = new ArrayList<String>(Arrays.asList(new String[]{"qad", "bad", "sad", null, "had"}));
        Collections.sort(list, NULL_SAFE_COMPARATOR);

        System.out.println(list);
    }
}

2

Java 8을 사용하여 객체간에 null 친화적 인 비교를 수행 할 수 있습니다. 문자열 이름과 정수 연령이라는 두 개의 필드가있는 Boy 클래스를 가지고 있다고 가정하고 이름을 먼저 비교 한 다음 둘 다 동일한 경우 연령을 원합니다.

static void test2() {
    List<Boy> list = new ArrayList<>();
    list.add(new Boy("Peter", null));
    list.add(new Boy("Tom", 24));
    list.add(new Boy("Peter", 20));
    list.add(new Boy("Peter", 23));
    list.add(new Boy("Peter", 18));
    list.add(new Boy(null, 19));
    list.add(new Boy(null, 12));
    list.add(new Boy(null, 24));
    list.add(new Boy("Peter", null));
    list.add(new Boy(null, 21));
    list.add(new Boy("John", 30));

    List<Boy> list2 = list.stream()
            .sorted(comparing(Boy::getName, 
                        nullsLast(naturalOrder()))
                   .thenComparing(Boy::getAge, 
                        nullsLast(naturalOrder())))
            .collect(toList());
    list2.stream().forEach(System.out::println);

}

private static class Boy {
    private String name;
    private Integer age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Boy(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String toString() {
        return "name: " + name + " age: " + age;
    }
}

그리고 결과 :

    name: John age: 30
    name: Peter age: 18
    name: Peter age: 20
    name: Peter age: 23
    name: Peter age: null
    name: Peter age: null
    name: Tom age: 24
    name: null age: 12
    name: null age: 19
    name: null age: 21
    name: null age: 24


1

데이터에 null이없는 경우 (항상 문자열에 대한 좋은 아이디어) 데이터가 실제로 큰 경우, 실제로 값을 비교하기 전에 세 번의 비교를 수행하고 있습니다 . tad 비트를 최적화 할 수 있습니다. 읽을 수있는 코드 인 YMMV는 약간의 최적화보다 우선합니다.

        if(o1.name != null && o2.name != null){
            return o1.name.compareToIgnoreCase(o2.name);
        }
        // at least one is null
        return (o1.name == o2.name) ? 0 : (o1.name != null ? 1 : -1);

1
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Comparator;

public class TestClass {

    public static void main(String[] args) {

        Student s1 = new Student("1","Nikhil");
        Student s2 = new Student("1","*");
        Student s3 = new Student("1",null);
        Student s11 = new Student("2","Nikhil");
        Student s12 = new Student("2","*");
        Student s13 = new Student("2",null);
        List<Student> list = new ArrayList<Student>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s11);
        list.add(s12);
        list.add(s13);

        list.sort(Comparator.comparing(Student::getName,Comparator.nullsLast(Comparator.naturalOrder())));

        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            Student student = (Student) iterator.next();
            System.out.println(student);
        }


    }

}

출력은

Student [name=*, id=1]
Student [name=*, id=2]
Student [name=Nikhil, id=1]
Student [name=Nikhil, id=2]
Student [name=null, id=1]
Student [name=null, id=2]

1

NullSafe Comparator 를 사용 하는 간단한 방법 중 하나는 Spring 구현을 사용하는 것입니다. 아래는 참조하는 간단한 예 중 하나입니다.

public int compare(Object o1, Object o2) {
        ValidationMessage m1 = (ValidationMessage) o1;
        ValidationMessage m2 = (ValidationMessage) o2;
        int c;
        if (m1.getTimestamp() == m2.getTimestamp()) {
            c = NullSafeComparator.NULLS_HIGH.compare(m1.getProperty(), m2.getProperty());
            if (c == 0) {
                c = m1.getSeverity().compareTo(m2.getSeverity());
                if (c == 0) {
                    c = m1.getMessage().compareTo(m2.getMessage());
                }
            }
        }
        else {
            c = (m1.getTimestamp() > m2.getTimestamp()) ? -1 : 1;
        }
        return c;
    }

0

다른 Apache ObjectUtils 예제 다른 유형의 객체를 정렬 할 수 있습니다.

@Override
public int compare(Object o1, Object o2) {
    String s1 = ObjectUtils.toString(o1);
    String s2 = ObjectUtils.toString(o2);
    return s1.toLowerCase().compareTo(s2.toLowerCase());
}

0

이것이 ArrayList를 정렬하는 데 사용하는 구현입니다. 널 클래스는 마지막으로 정렬됩니다.

필자의 경우 EntityPhone은 EntityAbstract를 확장하고 컨테이너는 List <EntityAbstract>입니다.

"compareIfNull ()"메소드는 널 안전 정렬에 사용됩니다. 다른 방법은 완전성을위한 것이며, compareIfNull을 사용하는 방법을 보여줍니다.

@Nullable
private static Integer compareIfNull(EntityPhone ep1, EntityPhone ep2) {

    if (ep1 == null || ep2 == null) {
        if (ep1 == ep2) {
            return 0;
        }
        return ep1 == null ? -1 : 1;
    }
    return null;
}

private static final Comparator<EntityAbstract> AbsComparatorByName = = new Comparator<EntityAbstract>() {
    @Override
    public int compare(EntityAbstract ea1, EntityAbstract ea2) {

    //sort type Phone first.
    EntityPhone ep1 = getEntityPhone(ea1);
    EntityPhone ep2 = getEntityPhone(ea2);

    //null compare
    Integer x = compareIfNull(ep1, ep2);
    if (x != null) return x;

    String name1 = ep1.getName().toUpperCase();
    String name2 = ep2.getName().toUpperCase();

    return name1.compareTo(name2);
}
}


private static EntityPhone getEntityPhone(EntityAbstract ea) { 
    return (ea != null && ea.getClass() == EntityPhone.class) ?
            (EntityPhone) ea : null;
}

0

간단한 핵을 원한다면 :

arrlist.sort((o1, o2) -> {
    if (o1.getName() == null) o1.setName("");
    if (o2.getName() == null) o2.setName("");

    return o1.getName().compareTo(o2.getName());
})

목록의 끝에 null을 넣으려면 위의 metod에서 이것을 변경하십시오.

return o2.getName().compareTo(o1.getName());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.