web-dev-qa-db-ja.com

Javaコレクションソートを使用するときにnullを処理する方法

JavaでCollection.sortを使用する場合、内部オブジェクトの1つがnullの場合、何を返す必要がありますか

例:

Collections.sort(list, new Comparator<MyBean>() {
    public int compare(MyBean o1, MyBean o2) {
      return o2.getDate().compareTo(o1.getDate());
     } 

});

O2はnullではないが、o2.getDate()はnullであるとしましょう。null検証を追加すると、1または-1または0を返す必要がありますか?

31
Giancarlo Corzo

当然、それはあなたの選択です。どんなロジックを書いても、それはソート規則を定義します。したがって、「すべき」は、ここでは実際には適切な言葉ではありません。

他の要素の前にnullを表示したい場合は、次のようなことができます

public int compare(MyBean o1, MyBean o2) {
    if (o1.getDate() == null) {
        return (o2.getDate() == null) ? 0 : -1;
    }
    if (o2.getDate() == null) {
        return 1;
    }
    return o2.getDate().compareTo(o1.getDate());
} 
40
Nikita Rybak

Java 8では、nullsFirst()も使用できます:

_Comparator.nullsFirst(Date::compareTo).compare(dateOne, dateTwo);
_

またはnullsLast()

_Comparator.nullsLast(Date::compareTo).compare(dateOne, dateTwo);
_

これらのメソッドは、nullを最初または最後にソートします。 nullが他のオブジェクトよりも大きいか小さいかを問わず、誤りも正しいこともありません。他の人がすでに述べたように、これは完全にあなた次第です。

21
user1438038

それは、nullを大きな値と見なすか、低い値と見なすかによって異なります。

ほとんどの場合、null <その他すべてであると考えることができますが、それはコンテキストに依存します。

そして、0はここではひどい戻り値になります。

2
Colin Hebert

Nikita Rybakからの回答に続いて、私はすでに列挙型コンパレータを持っています。ここからnullロジックのみを追加します。

public enum Orden implements Comparator<CmunParametrosDTO> {
        ByStrDescripcion {
            public int compare(CmunParametrosDTO item1, CmunParametrosDTO item2) {
                if (item1.getStrDescripcion() == null && item2.getStrDescripcion() == null)
                    return 0;
                if (item1.getStrDescripcion() == null)
                    return 1;
                else if (item2.getStrDescripcion() == null)
                    return -1;
                return item1.getStrDescripcion().compareTo(item2.getStrDescripcion());
            }
        }
        public abstract int compare(CmunParametrosDTO item1, CmunParametrosDTO item2);

        public Comparator<CmunParametrosDTO> ascending() {
            return this;
        }

        public Comparator<CmunParametrosDTO> descending() {
            return Collections.reverseOrder(this);
        }
}

このフォームでは、リストのsortメソッドを呼び出すことができます。

    if(isBolOrdAscendente()) Collections.sort(listado, CmunParametrosDTO.Orden.ByStrDescripcion .ascending());
    else Collections.sort(listado, CmunParametrosDTO.Orden.ByStrDescripcion .descending());
1
ELD

オブジェクトがnullであるか、オブジェクトのコンテンツがnullであるかによって異なります。

オブジェクトはnullです:

    import static Java.util.Comparator.*;

    List<Data> listOfData = Arrays.asList(
           new Data("foo"),
           null,
           new Data("bar"),
           new Data("nyu"));

    listOfData.sort(nullsFirst(comparing(Data::getValue)));
    listOfData.forEach(System.out::println);
    //OUTPUT:
    // null
    // Data(bar)
    // Data(foo)
    // Data(nyu)

オブジェクトのコンテンツはnullです:

    List<Data> listOfData = Arrays.asList(
           new Data("foo"),
           new Data(null),
           new Data("bar"),
           new Data("nyu"));


    listOfData.sort(nullsFirst(
         comparing(Data::getValue, nullsFirst(naturalOrder()))));

    listOfData.forEach(System.out::println);
    //OUTPUT:
    // Data(null)
    // Data(bar)
    // Data(foo)
    // Data(nyu)
0
davidddp