questo può essere una semplice domanda, ma vorrei capire chiaramente ...Java 8 comparatore nullsFirst naturalOrder confuso
Ho un codice come questo:
public final class Persona
{
private final int id;
private final String name
public Persona(final int id,final String name)
{
this.id = id;
this.name = name;
}
public int getId(){return id;}
public String getName(){return name;}
@Override
public String toString(){return "Persona{" + "id=" + id + ", name=" + name+'}';}
}
e sto testando questo codice :
import static java.util.Comparator.*;
private void nullsFirstTesting()
{
final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst(naturalOrder()));
final List<Persona>persons = Arrays.asList(new Persona(1,"Cristian"),new Persona(2,"Guadalupe"),new Persona(3,"Cristina"),new Persona(4,"Chinga"),new Persona(5,null));
persons
.stream()
.sorted(comparator)
.forEach(System.out::println);
}
Questo mostra i seguenti risultati:
Persona{id=5, name=null}
Persona{id=4, name=Chinga}
Persona{id=1, name=Cristian}
Persona{id=3, name=Cristina}
Persona{id=2, name=Guadalupe}
Questi risultati vanno bene per me ma ho un problema di comprensione.
Quando ignorare l'oggetto new Persona(5,null)
e passo comparatore:
final Comparator<Persona>comparator = comparing(Persona::getName);
Esso funziona come un fascino. Il mio ordinamento è di natural order of name property
. Il problema sorge quando aggiungo l'oggetto con name=null
, ho solo pensato che avrei avuto bisogno del mio comparatore come questo.
final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst());
Il mio pensiero era erronea: "OK, quando il nome non è nullo, vengono ordinati in natural order of name
, proprio come il comparatore precedente, e se sono null
essi saranno prima ma la mia non i nomi null saranno ancora ordinati nell'ordine naturale ".
Ma il codice giusto è questo:
final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst(naturalOrder()));
Non capisco il parametro nullsFirst
. Ho solo pensato che lo natural order of name
avrebbe esplicitamente [predefinito] anche i valori null
.
Ma i documenti dicono:
Restituisce un comparatore null-friendly che considera
null
essere meno di non nullo. Quando entrambi sononull
, sono considerati uguali a . Se entrambi non sono nulli, loComparator
specificato viene utilizzato per determinare l'ordine. Se il comparatore specificato ènull
, , il comparatore restituito considera tutti i valori non nulli uguali.
Questa riga: "Se entrambi non sono nulli, per determinare l'ordine viene utilizzato lo Comparator
specificato."
Sono confuso quando e come l'ordine naturale deve essere impostato in modo esplicito o quando viene inferito.
Nota * "Se il comparatore specificato è 'null', quindi il comparatore restituito considera tutti i valori non nulli uguali." * In altre parole, puoi fare 'nullsFirst (null)'; tuttavia ordina semplicemente i null in primo piano senza ordinare i non null. Il doc in realtà lo spiega abbastanza bene. – Radiodef
@chiperotiz quindi come lo hai risolto alla fine? Sei riuscito a ordinare prima per null e poi per ordine naturale? – Unheilig
sì usando questo codice 'comparatore finale comparatore = confrontando (Persona :: getName, nullsFirst (naturalOrder()));' –
chiperortiz