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.