Técnicas Avanzadas de Ordenación
En aplicaciones del mundo real, a menudo necesitamos una lógica de ordenación más compleja, como:
- Ordenar por múltiples criterios (por ejemplo, ordenar por GPA y, si los GPA son iguales, ordenar por nombre)
- Ordenar en orden inverso
- Crear cadenas de comparadores personalizados
Exploremos estas técnicas avanzadas.
Ordenación por Múltiples Criterios
- Crea un nuevo archivo llamado
MultiCriteriaDemo.java
en el directorio ~/project
:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class MultiCriteriaDemo {
public static void main(String[] args) {
// Create a list of students with some having the same GPA
List<Student> students = new ArrayList<>();
students.add(new Student("John", 3.5, 101));
students.add(new Student("Mary", 3.8, 102));
students.add(new Student("Alice", 3.5, 103)); // Same GPA as John
students.add(new Student("Bob", 3.8, 104)); // Same GPA as Mary
students.add(new Student("Charlie", 3.2, 105));
// Print the unsorted list
System.out.println("Unsorted Student List:");
for (Student student : students) {
System.out.println(student);
}
// Sort first by GPA, then by name
Comparator<Student> byGpa = Comparator.comparing(Student::getGpa);
Comparator<Student> byName = Comparator.comparing(Student::getName);
// Combine the comparators using thenComparing
Comparator<Student> byGpaThenName = byGpa.thenComparing(byName);
// Sort the list
Collections.sort(students, byGpaThenName);
// Print the sorted list
System.out.println("\nStudents sorted by GPA, then by name:");
for (Student student : students) {
System.out.println(student);
}
}
}
Este programa:
-
Crea una lista de estudiantes, algunos con el mismo GPA
-
Crea un comparador para el GPA y un comparador para el nombre
-
Combina estos comparadores utilizando el método thenComparing()
-
Ordena a los estudiantes primero por GPA y luego por nombre si los GPA son iguales
-
Compila y ejecuta el código:
cd ~/project
javac Student.java MultiCriteriaDemo.java
java MultiCriteriaDemo
Deberías ver una salida similar a:
Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
Bob, GPA: 3.8, Reg No: 104
Charlie, GPA: 3.2, Reg No: 105
Students sorted by GPA, then by name:
Charlie, GPA: 3.2, Reg No: 105
Alice, GPA: 3.5, Reg No: 103
John, GPA: 3.5, Reg No: 101
Bob, GPA: 3.8, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
Observa que los estudiantes con el mismo GPA (Alice y John con 3.5, Bob y Mary con 3.8) se ordenan alfabéticamente.
Ordenación en Orden Inverso
- Crea un nuevo archivo llamado
ReverseOrderDemo.java
en el directorio ~/project
:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ReverseOrderDemo {
public static void main(String[] args) {
// Create a list of students
List<Student> students = new ArrayList<>();
students.add(new Student("John", 3.5, 101));
students.add(new Student("Mary", 3.8, 102));
students.add(new Student("Alice", 3.2, 103));
students.add(new Student("Bob", 3.9, 104));
students.add(new Student("Charlie", 3.0, 105));
// Print the unsorted list
System.out.println("Unsorted Student List:");
for (Student student : students) {
System.out.println(student);
}
// Method 1: Using Collections.reverseOrder() with a comparator
Comparator<Student> byGpa = Comparator.comparing(Student::getGpa);
Comparator<Student> byGpaReversed = Collections.reverseOrder(byGpa);
Collections.sort(students, byGpaReversed);
System.out.println("\nStudents sorted by GPA in descending order (Method 1):");
for (Student student : students) {
System.out.println(student);
}
// Method 2: Using the reversed() method of Comparator
Collections.sort(students, Comparator.comparing(Student::getName).reversed());
System.out.println("\nStudents sorted by name in reverse alphabetical order (Method 2):");
for (Student student : students) {
System.out.println(student);
}
}
}
Este programa demuestra dos formas de ordenar en orden inverso:
-
Utilizando Collections.reverseOrder()
para invertir un comparador
-
Utilizando el método reversed()
de un comparador
-
Compila y ejecuta el código:
cd ~/project
javac Student.java ReverseOrderDemo.java
java ReverseOrderDemo
Deberías ver una salida similar a:
Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104
Charlie, GPA: 3.0, Reg No: 105
Students sorted by GPA in descending order (Method 1):
Bob, GPA: 3.9, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
John, GPA: 3.5, Reg No: 101
Alice, GPA: 3.2, Reg No: 103
Charlie, GPA: 3.0, Reg No: 105
Students sorted by name in reverse alphabetical order (Method 2):
Mary, GPA: 3.8, Reg No: 102
John, GPA: 3.5, Reg No: 101
Charlie, GPA: 3.0, Reg No: 105
Bob, GPA: 3.9, Reg No: 104
Alice, GPA: 3.2, Reg No: 103
La primera ordenación muestra a los estudiantes en orden descendente por GPA, y la segunda ordenación muestra a los estudiantes en orden alfabético inverso por nombre.
Cadena de Ordenación Compleja
- Vamos a crear un ejemplo más que combine múltiples criterios y ordenación inversa. Crea un archivo llamado
ComplexSortingDemo.java
en el directorio ~/project
:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComplexSortingDemo {
public static void main(String[] args) {
// Create a list of students with varied data
List<Student> students = new ArrayList<>();
students.add(new Student("John", 3.5, 101));
students.add(new Student("Mary", 3.8, 102));
students.add(new Student("Alice", 3.5, 103)); // Same GPA as John
students.add(new Student("Bob", 3.8, 104)); // Same GPA as Mary
students.add(new Student("Charlie", 3.2, 105));
students.add(new Student("David", 3.2, 106)); // Same GPA as Charlie
// Print the unsorted list
System.out.println("Unsorted Student List:");
for (Student student : students) {
System.out.println(student);
}
// Create a complex sorting chain:
// 1. Sort by GPA in descending order
// 2. If GPAs are equal, sort by name in ascending order
// 3. If names are also equal, sort by registration number in descending order
Comparator<Student> complexComparator = Comparator
.comparing(Student::getGpa, Comparator.reverseOrder())
.thenComparing(Student::getName)
.thenComparing(Student::getRegNo, Comparator.reverseOrder());
Collections.sort(students, complexComparator);
System.out.println("\nStudents sorted by complex criteria:");
System.out.println("(GPA descending, then name ascending, then reg. number descending)");
for (Student student : students) {
System.out.println(student);
}
}
}
Este programa crea una cadena de ordenación compleja que:
-
Ordena primero a los estudiantes por GPA en orden descendente
-
Si los GPA son iguales, ordena por nombre en orden ascendente
-
Si tanto el GPA como el nombre son iguales, ordena por número de registro en orden descendente
-
Compila y ejecuta el código:
cd ~/project
javac Student.java ComplexSortingDemo.java
java ComplexSortingDemo
Deberías ver una salida similar a:
Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
Bob, GPA: 3.8, Reg No: 104
Charlie, GPA: 3.2, Reg No: 105
David, GPA: 3.2, Reg No: 106
Students sorted by complex criteria:
(GPA descending, then name ascending, then reg. number descending)
Bob, GPA: 3.8, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
John, GPA: 3.5, Reg No: 101
Charlie, GPA: 3.2, Reg No: 105
David, GPA: 3.2, Reg No: 106
En esta salida:
- Bob y Mary tienen un GPA de 3.8, pero Bob aparece primero alfabéticamente
- Alice y John tienen un GPA de 3.5, pero Alice aparece primero alfabéticamente
- Charlie y David tienen un GPA de 3.2, y Charlie aparece primero alfabéticamente
Esto demuestra cómo se puede crear una lógica de ordenación compleja y de múltiples niveles encadenando comparadores.