import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        Objeto o1 = new Objeto(1, "c", LocalDate.of(2018, 01, 1));
        Objeto o2 = new Objeto(2, "b", null);
        Objeto o3 = new Objeto(3, "a", LocalDate.of(2018, 01, 2));
    
        List<Objeto> objetos = new ArrayList<>();
        objetos.add(o1);
        objetos.add(o2);
        objetos.add(o3);
    
        System.out.println("SEM ORDENAÇÃO: ");
        for (Objeto objeto : objetos) {
            System.out.println(objeto);
        }
    
        System.out.println("\n\nORDENADO PELO NÚMERO: ");
        Collections.sort(objetos, new ObjetoNumeroComparator());
        for (Objeto objeto : objetos) {
            System.out.println(objeto);
        }
    
        System.out.println("\n\nORDENADO PELA PALAVRA: ");
        Collections.sort(objetos, new ObjetoPalavraComparator());
        for (Objeto objeto : objetos) {
            System.out.println(objeto);
        }
    
        System.out.println("\n\nORDENADO PELA DATA: ");
        Collections.sort(objetos, new ObjetoDataComparator());
        for (Objeto objeto : objetos) {
            System.out.println(objeto);
        }
    }
}

final class Objeto {
    private final int numero;
    private final String palavra;
    private final LocalDate data;
    
    public Objeto(int numero, String palavra, LocalDate data) {
        this.numero = numero;
        this.palavra = palavra;
        this.data = data;
    }

    public int getNumero() {
        return numero;
    }

    public String getPalavra() {
        return palavra;
    }

    public LocalDate getData() {
        return data;
    }

    @Override
    public String toString() {
         return numero + " " + palavra + " " + data;
    }
}

class ObjetoNumeroComparator implements Comparator<Objeto> {
    public ObjetoNumeroComparator() {
    }

    @Override
    public int compare(Objeto o1, Objeto o2) {
        return o1.getNumero() - o2.getNumero();
    }
}

class ObjetoPalavraComparator implements Comparator<Objeto> {
    public ObjetoPalavraComparator() {
    }

    @Override
    public int compare(Objeto o1, Objeto o2) {
        String a = o1.getPalavra();
        String b = o2.getPalavra();
        return a == null && b == null ? 0
                : a == null ? 1
                : b == null ? -1
                : a.compareTo(b);
    }
}

class ObjetoDataComparator implements Comparator<Objeto> {
    public ObjetoDataComparator() {
    }

    @Override
    public int compare(Objeto o1, Objeto o2) {
        LocalDate a = o1.getData();
        LocalDate b = o2.getData();
        return a == null && b == null ? 0
                : a == null ? 1
                : b == null ? -1
                : a.compareTo(b);
    }
}