import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Victor Williams Stafusa da Silva
 */
public class Main {
    public static void main(String[] args) {
        System.out.println(Intervalo.reduzir(new Intervalo(1, 3), new Intervalo(2, 6), new Intervalo(7, 10)));
        System.out.println(Intervalo.reduzir(new Intervalo(1, 3), new Intervalo(2, 8), new Intervalo(7, 10)));
        System.out.println(Intervalo.reduzir(new Intervalo(1, 3), new Intervalo(4, 7), new Intervalo(8, 10)));
        System.out.println(Intervalo.reduzir(new Intervalo(1, 3), new Intervalo(3, 10)));
    }
}

final class Intervalo {
    private final double a;
    private final double b;

    public Intervalo(double a, double b) {
        if (b < a) throw new IllegalArgumentException();
        this.a = a;
        this.b = b;
    }

    public double getA() {
       return a;
    }

    public double getB() {
       return b;
    }

    @Override
    public String toString() {
        return "[" + a + "<->" + b + "]";
    }

    public Evento getEventoA() {
        return new Evento(true, a);
    }

    public Evento getEventoB() {
        return new Evento(false, b);
    }

    @SafeVarargs
    public static List<Intervalo> reduzir(Intervalo... lista) {
        return reduzir(List.of(lista));
    }

    public static List<Intervalo> reduzir(List<Intervalo> lista) {
        List<Evento> eventos = new ArrayList<>(lista.size() * 2);
        for (Intervalo i : lista) {
            eventos.add(i.getEventoA());
            eventos.add(i.getEventoB());
        }
        Collections.sort(eventos);
        List<Intervalo> saida = new ArrayList<>(lista.size());
        int contagem = 0;
        double inicio = Double.NEGATIVE_INFINITY;
        for (Evento e : eventos) {
            if (e.isInicioIntervalo()) {
                if (contagem == 0) inicio = e.getPonto();
                contagem++;
            } else {
                contagem--;
                if (contagem == 0) saida.add(new Intervalo(inicio, e.getPonto()));
            }
        }
        return saida;
    }
}

final class Evento implements Comparable<Evento> {
    private final boolean inicioIntervalo;
    private final double ponto;

    public Evento(boolean inicioIntervalo, double ponto) {
        this.inicioIntervalo = inicioIntervalo;
        this.ponto = ponto;
    }

    public boolean isInicioIntervalo() {
        return inicioIntervalo;
    }

    public double getPonto() {
        return ponto;
    }

    @Override
    public int compareTo(Evento outro) {
        return this.ponto < outro.ponto ? -1
                : this.ponto > outro.ponto ? 1
                : this.inicioIntervalo == outro.inicioIntervalo ? 0
                : this.inicioIntervalo ? -1
                : 1;
    }
}