> For the complete documentation index, see [llms.txt](https://educacion.gitbook.io/programacion/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://educacion.gitbook.io/programacion/ud6-estructuras-de-datos-avanzadas/estructuras-de-datos-en-java/interfaces-en-colleccions/comparator-e-comparable.md).

# Comparator e Comparable

**Comparable** e **Comparator** son dúas interfaces que definen como deben **compararse e ordenarse** os obxectos. Aínda que ambas perseguen o mesmo fin, aplican conceptos de deseño diferentes:

* **Comparable** utilízase para definir a orde natural dun obxecto (a que ten por defecto).
* **Comparator** utilízase para definir ordes alternativas ou personalizadas sen modificar a clase orixinal.

{% hint style="warning" %}
Esta distinción permite respectar o **principio SOLID de Aberto/Pechado**, xa que podemos crear novas estratexias de ordenación (Comparator) sen ter que alterar o código da clase que queremos ordenar.
{% endhint %}

## Comparable\<T>

A interface Comparable\<T> en Java é unha interface tipada fundamental que permite definir nunha clase a súa estratexia de comparación predeterminada.

{% hint style="warning" %}
**Documentación oficial:** <https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Comparable.html>
{% endhint %}

A interface define un único método fundamental:

<pre class="language-java"><code class="lang-java"><strong>public interface Comparable&#x3C;T>{
</strong><strong>    public int compareTo(T o);
</strong><strong>}
</strong></code></pre>

Imos a supoñer que queremos comparar dous obxectos do mesmo tipo, o1 e o2.

```java
o1.compareTo(o2);
```

As clases que implementen este método da interface comparable, deben de ter en conta o seguinte:

* Se o1 se ordena primeiro que o2, compareTo devolve un **número negativo**
* Se o2 se ordena primeriro que o1, compareTo devolve un **número positivo**
* Se se considera **iguais a efectos de ordenación**, devolve 0

```java
package Comparable;

public class Alumno implements Comparable<Alumno>{

    public String nombre;
    public int edad;

    public Alumno(String nombre, int edad) {
        this.nombre = nombre;
        this.edad = edad;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public int getEdad() {
        return edad;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }

    @Override
    public int compareTo(Alumno o) {
        // Exemplo: Ordenar por idade de menor a maior
        if (this.edad < o.edad) return -1;
        if (this.edad > o.edad) return 1;
        return 0;
         //Si el menor es el que va primero o1.getEdad()-o2.getEdad();
         //Si el mayor es el que va primero o2.getEdad()-o1.getEdad();
         //Integer.compare(o1.getEdad(), o2.getEdad())
    }
    
    @Override
    public String toString() {
        return "Alumno{" +
                "nombre='" + nombre + '\'' +
                ", edad=" + edad +
                '}';
    }
}

```

```java
public static void main(String[] args) {
        Alumno a1 = new Alumno("Juan", 21);
        Alumno a2 = new Alumno("María", 23);
        Alumno a3 = new Alumno("Ana", 18);
        Alumno a4 = new Alumno("Pedro", 21);
        System.out.println("Juan y maria: " + a1.compareTo(a2));
        System.out.println("Juan y Ana: " + a1.compareTo(a3));
        System.out.println("Juan y Pedro: " + a1.compareTo(a4));
    }
```

### Ordenación de Collecións e Arrays con Comparable

Unha vez a nosa clase ten implementada a operación **compareTo**, que adoita ser a comparación natural, existen dúas clases con método estáticos auxiliares para traballar con arrays e colleccions:

{% hint style="warning" %}
**Arrays:** <https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html>
{% endhint %}

{% hint style="warning" %}
**Collections**: <https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html>
{% endhint %}

Estas clases contan con un un método sort() que se vai a empregar para realizar a ordenación:

```java
       List<Alumno> lista = new ArrayList<>();
        lista.add(a1);
        lista.add(a2);
        lista.add(a3);
        lista.add(a4);
        System.out.println("Lista: " + lista);
        Collections.sort(lista);
        System.out.println("Lista ordenada" + lista);
//Lista: [Alumno{nombre='Juan', edad=21}, Alumno{nombre='María', edad=23}, Alumno{nombre='Ana', edad=18}, Alumno{nombre='Pedro', edad=21}]
//Lista ordenada[Alumno{nombre='Ana', edad=18}, Alumno{nombre='Juan', edad=21}, Alumno{nombre='Pedro', edad=21}, Alumno{nombre='María', edad=23}]
```

Se intentamos realizar a ordenación para unha clase que non implementa Comparable, imos a recibir unha excepción:

<figure><img src="/files/v06lIYKeBiYdder6105K" alt=""><figcaption></figcaption></figure>

O comportamento indicado no punto anterior e análogo con Arrays.sort()&#x20;

## Comparator\<T>

A interface Comparator\<T> en Java é unha interface tipada que permite definir diferentes estratexias de comparación, mediante clases externas, para os obxectos que se van a implementar.&#x20;

Esta estratexia permite implementar diferentes formas de comparación se ter que modificar a clase orixinal.

{% hint style="warning" %}
**Documentación oficial:** <https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Comparator.html>
{% endhint %}

A interface ten un único método de implementación obligatoria, que vai a recibir dous obxectos a comparar e que vai a realizar a comparación en base ao criterio correspondente:

<pre class="language-java"><code class="lang-java"><strong>public interface Comparator&#x3C;T>{
</strong><strong>    public int compare(T t1, T t2);
</strong><strong>}
</strong></code></pre>

En base a isto, sería posible implementar comparadores en base aos diferentes atributos de unha clase se modificar a propia clase:

```java
public class ComparadorEdadAlumnos implements Comparator<Alumno> {

    @Override
    public int compare(Alumno a1, Alumno a2) {
        if (a1.edad < a2.edad) return -1;
        if (a1.edad > a2.edad) return 1;
        return 0;
    }
}
```

```java
public class ComparadorNombreAlumno implements Comparator<Alumno> {

    @Override
    public int compare(Alumno o1, Alumno o2) {
        return o1.getNombre().compareTo(o2.getNombre());
    }
}
```

### Ordenación de Collections e Arrays con Comparator

A ordenación e análoga a que fixemos no apartado anterior, a única diferencia e que imos a empregar un método sobrecargado que recibe dous parámetros:

* A coleción ou array a ordenar (Que temos que ordenar)
* O comparador que empregar para a ordenación (Como imos a ordenar)

Sobre o exemplo anterior:

```java
        List<Alumno> lista = new ArrayList<>();
        lista.add(a1);
        lista.add(a2);
        lista.add(a3);
        lista.add(a4);
        System.out.println("Lista: " + lista);
        ComparadorEdadAlumnos comEdad = new ComparadorEdadAlumnos();
        Collections.sort(lista, comEdad);
        System.out.println("Lista ordenada edad:" + lista);
        ComparadorNombreAlumno comNombre = new ComparadorNombreAlumno();
        Collections.sort(lista, comNombre);
        System.out.println("Lista ordenada nombre:" + lista);
        
//Lista: [Alumno{nombre='Juan', edad=21}, Alumno{nombre='María', edad=23}, Alumno{nombre='Ana', edad=18}, Alumno{nombre='Pedro', edad=21}]
//Lista ordenada edad:[Alumno{nombre='Ana', edad=18}, Alumno{nombre='Juan', edad=21}, Alumno{nombre='Pedro', edad=21}, Alumno{nombre='María', edad=23}]
//Lista ordenada nombre:[Alumno{nombre='Ana', edad=18}, Alumno{nombre='Juan', edad=21}, Alumno{nombre='María', edad=23}, Alumno{nombre='Pedro', edad=21}]  
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://educacion.gitbook.io/programacion/ud6-estructuras-de-datos-avanzadas/estructuras-de-datos-en-java/interfaces-en-colleccions/comparator-e-comparable.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
