Dominando los Algoritmos de Colecciones de Java: Ordenación, Mezcla y Más
Algoritmos de Java
En este tutorial, exploramos los potentes algoritmos proporcionados por el framework Collections de Java a través de ejemplos claros y prácticos.
El framework Collections de Java proporciona un rico conjunto de métodos estáticos—a menudo llamados algoritmos genéricos—que te permiten manipular estructuras de datos sin escribir código repetitivo. Estas utilidades funcionan con cualquier colección que implemente la interfaz Collection, ofreciendo simplicidad y rendimiento.
A continuación, recorremos los algoritmos más utilizados, ilustrando su sintaxis, comportamiento y casos de uso prácticos.
1. Ordenación con Collections.sort()
El método sort() ordena los elementos en orden natural (ascendente). Para ordenación personalizada, proporciona una implementación de Comparator.
import java.util.ArrayList;
import java.util.Collections;
class Main {
public static void main(String[] args) {
ArrayList<Integer> numeros = new ArrayList<>();
numeros.add(4);
numeros.add(2);
numeros.add(3);
System.out.println("ArrayList sin ordenar: " + numeros);
Collections.sort(numeros);
System.out.println("ArrayList ordenado: " + numeros);
}
}
Salida
ArrayList sin ordenar: [4, 2, 3] ArrayList ordenado: [2, 3, 4]
Para orden descendente o criterios específicos del dominio, usa un Comparator personalizado—consulta la guía de Ordenación en Java para más detalles.
2. Aleatorización con Collections.shuffle()
Usa shuffle() para aleatorizar la secuencia de elementos, ideal para juegos o escenarios de muestreo.
import java.util.ArrayList;
import java.util.Collections;
class Main {
public static void main(String[] args) {
ArrayList<Integer> numeros = new ArrayList<>();
numeros.add(1);
numeros.add(2);
numeros.add(3);
System.out.println("ArrayList ordenado: " + numeros);
Collections.shuffle(numeros);
System.out.println("ArrayList después de shuffle: " + numeros);
}
}
Salida
ArrayList ordenado: [1, 2, 3] ArrayList después de shuffle: [2, 1, 3]
Cada ejecución produce una permutación diferente, gracias al algoritmo Fisher-Yates subyacente.
3. Manipulación Rutinaria de Datos
Java ofrece un conjunto de métodos utilitarios para transformar colecciones:
reverse()– invierte el orden de los elementos.fill()– reemplaza cada elemento con un valor especificado.copy()– copia elementos de una colección a otra (del mismo tamaño).swap()– intercambia dos elementos por índice.addAll()– añade todos los elementos de una colección a otra.
import java.util.ArrayList;
import java.util.Collections;
class Main {
public static void main(String[] args) {
ArrayList<Integer> numeros = new ArrayList<>();
numeros.add(1);
numeros.add(2);
System.out.println("ArrayList1: " + numeros);
Collections.reverse(numeros);
System.out.println("ArrayList1 invertido: " + numeros);
Collections.swap(numeros, 0, 1);
System.out.println("ArrayList1 después de swap(): " + numeros);
ArrayList<Integer> nuevosNumeros = new ArrayList<>();
nuevosNumeros.addAll(numeros);
System.out.println("ArrayList2 usando addAll(): " + nuevosNumeros);
Collections.fill(numeros, 0);
System.out.println("ArrayList1 después de fill(): " + numeros);
Collections.copy(nuevosNumeros, numeros);
System.out.println("ArrayList2 después de copy(): " + nuevosNumeros);
}
}
Salida
ArrayList1: [1, 2] ArrayList1 invertido: [2, 1] ArrayList1 después de swap(): [1, 2] ArrayList2 usando addAll(): [1, 2] ArrayList1 después de fill(): [0, 0] ArrayList2 después de copy(): [0, 0]
Nota: El método copy() requiere que la colección de destino tenga al menos tantos elementos como la fuente.
4. Búsqueda Binaria con Collections.binarySearch()
Localiza eficientemente un elemento en una colección ordenada. El método retorna el índice del elemento o un punto de inserción negativo si no se encuentra.
import java.util.ArrayList;
import java.util.Collections;
class Main {
public static void main(String[] args) {
ArrayList<Integer> numeros = new ArrayList<>();
numeros.add(1);
numeros.add(2);
numeros.add(3);
int pos = Collections.binarySearch(numeros, 3);
System.out.println("La posición de 3 es " + pos);
}
}
Salida
La posición de 3 es 2.
Consejo: Siempre ordena la colección antes de llamar a binarySearch(); de lo contrario, el resultado es indefinido.
Explora más en el artículo de Búsqueda Binaria en Java.
5. Composición de Colecciones
Estas utilidades analizan relaciones entre colecciones:
frequency()– cuenta ocurrencias de un elemento específico.disjoint()– verifica si dos colecciones no comparten elementos comunes.
import java.util.ArrayList;
import java.util.Collections;
class Main {
public static void main(String[] args) {
ArrayList<Integer> numeros = new ArrayList<>();
numeros.add(1);
numeros.add(2);
numeros.add(3);
numeros.add(2);
System.out.println("ArrayList1: " + numeros);
int cuenta = Collections.frequency(numeros, 2);
System.out.println("Cuenta de 2: " + cuenta);
ArrayList<Integer> nuevosNumeros = new ArrayList<>();
nuevosNumeros.add(5);
nuevosNumeros.add(6);
System.out.println("ArrayList2: " + nuevosNumeros);
boolean disjuntos = Collections.disjoint(numeros, nuevosNumeros);
System.out.println("Las dos listas son disjuntas: " + disjuntos);
}
}
Salida
ArrayList1: [1, 2, 3, 2] Cuenta de 2: 2 ArrayList2: [5, 6] Las dos listas son disjuntas: true
6. Encontrar Valores Mínimo y Máximo
Recupera el elemento más pequeño o más grande con min() y max()—útil para análisis y comprobaciones de límites.
import java.util.ArrayList;
import java.util.Collections;
class Main {
public static void main(String[] args) {
ArrayList<Integer> numeros = new ArrayList<>();
numeros.add(1);
numeros.add(2);
numeros.add(3);
int min = Collections.min(numeros);
System.out.println("Elemento Mínimo: " + min);
int max = Collections.max(numeros);
System.out.println("Elemento Máximo: " + max);
}
}
Salida
Elemento Mínimo: 1 Elemento Máximo: 3
Java
- Dominar Operadores en Java: Tipos, Sintaxis y Ejemplos Prácticos
- Comentarios en Java: Tipos, Uso y Mejores Prácticas
- Dominar if…else en Java: Control de Flujo Explicado
- Dominar el Bucle for Mejorado en Java: Sintaxis, Ejemplos y Mejores Prácticas
- Dominar Strings en Java: Creación, Métodos y Mejores Prácticas
- Dominando interfaces en Java: Conceptos, implementación y mejores prácticas
- Dominando las clases internas anónimas en Java: Definición, sintaxis y ejemplos prácticos
- Dominando Try‑with‑Resources en Java: Gestión automática de recursos explicada
- Anotaciones en Java explicadas: Tipos, ubicación y ejemplos prácticos
- Aserciones en Java: Guía práctica para detectar bugs y asegurar fiabilidad del código
- Generar números aleatorios en Java: Guía práctica con Random y Math.random