Clases de Estructuras de Datos y Algoritmos en Java para Competencias de Programación

String es una clase inmutable. Cualquier modificación sobre un objeto String crea un nuevo espacio en memoria. Ejemplo:

String texto = "Hola Mundo";
char[] arrChars = {'X', 'Y', 'Z'};
String desdeArr = new String(arrChars);

// Recorrido
for (int i = 0; i < texto.length(); i++)
    System.out.print(texto.charAt(i));
System.out.println();

for (char c : texto.toCharArray())
    System.out.print(c);
System.out.println();

// Métodos comunes
texto.charAt(0);                    // 'H'
texto.compareTo("G");               // 1
texto.equals("Hola Mundo");         // true
texto.startsWith("Ho");             // true
texto.endsWith("do");               // true
texto.indexOf('o');                 // 1
texto.indexOf('o', 3);              // 4
texto.lastIndexOf('o');             // 4
texto.replace('o', 'a');            // "Hala Munda"
texto.split(" ");                   // ["Hola", "Mundo"]
texto.substring(0, 4);              // "Hola"
texto.toLowerCase();                // "hola mundo"
texto.toUpperCase();                // "HOLA MUNDO"

Para modificacionse frecuentes se usan StringBuilder (más rápido, no sincronizado) o StringBuffer (hilo seguro). Ejemplo con StringBuilder:

StringBuilder sb = new StringBuilder("Hola");
sb.append(" Mundo");                // "Hola Mundo"
sb.reverse();                       // "odnuM aloH"
sb.delete(0, 5);                    // "aloH"
sb.insert(2, "X");                  // "alXoH"
sb.replace(0, 2, "AB");             // "ABXoH"
String resultado = sb.toString();   // "ABXoH"

  1. Arrays

La clase java.util.Arrays ofrece métodos estáticos para manipular arreglso:

int[] nums = {5, 2, 4, 1, 3};
int[][] mat = {{1,2},{3,4}};

// Ordenar
Arrays.sort(nums);                    // [1,2,3,4,5]
Integer[] numsW = {5,2,4,1,3};
Arrays.sort(numsW, (a,b) -> b - a);   // [5,4,3,2,1]

// Búsqueda binaria (requiere arreglo ordenado)
int pos = Arrays.binarySearch(nums, 3); // 2

// Comparación
boolean iguales = Arrays.equals(nums, nums);

// Rellenar
Arrays.fill(nums, 0);                 // [0,0,0,0,0]

// Convertir a String
String str1 = Arrays.toString(nums);        // "[0,0,0,0,0]"
String str2 = Arrays.deepToString(mat);     // "[[1,2],[3,4]]"

  1. ArrayList

ArrayList es una implementación dinámica de List basada en arreglo. Declaración y uso:

import java.util.*;

ArrayList<Integer> lista = new ArrayList<>();
ArrayList<Integer> lista2 = new ArrayList<>(Arrays.asList(1,2,3));

// Recorridos
for (int i = 0; i < lista2.size(); i++)
    System.out.print(lista2.get(i));

for (int x : lista2) System.out.print(x);

Iterator<Integer> it = lista2.iterator();
while (it.hasNext()) System.out.print(it.next());

lista2.stream().forEach(x -> System.out.print(x));

// Métodos comunes
lista2.add(4);                // [1,2,3,4]
lista2.add(1, 5);             // [1,5,2,3,4]
lista2.remove(Integer.valueOf(3)); // elimina el objeto 3
lista2.set(0, 9);             // [9,5,2,4]
lista2.subList(0, 2);         // [9,5]
lista2.indexOf(5);            // 1
lista2.isEmpty();             // false
lista2.contains(2);           // true
lista2.sort(Comparator.naturalOrder());   // [2,4,5,9]
lista2.sort(Comparator.reverseOrder());  // [9,5,4,2]
lista2.addAll(Arrays.asList(10,20));      // [9,5,4,2,10,20]
Collections.addAll(lista2, 30,40);        // [9,5,4,2,10,20,30,40]
Collections.reverse(lista2);              // [40,30,20,10,2,4,5,9]

// Convertir a arreglo
Integer[] arr = lista2.toArray(new Integer[0]);
int[] primitivos = lista2.stream().mapToInt(Integer::intValue).toArray();

  1. LinkedList

LinkedList implementa List y Deque como lista doblemente enlazada. Eficiente para inserciones/eliminaciones en cualquier posición. Métodos adicionales:

LinkedList<Integer&gt> enlazada = new LinkedList<>(Arrays.asList(1,2,3));
enlazada.addLast(4);          // [1,2,3,4]
enlazada.addFirst(5);         // [5,1,2,3,4]
enlazada.removeLast();        // elimina 4 → [5,1,2,3]
enlazada.removeFirst();       // elimina 5 → [1,2,3]
enlazada.getFirst();          // 1
enlazada.getLast();           // 3

  1. HashSet / TreeSet

HashSet es un conjunto sin orden ni duplicados, basado en HashMap. TreeSet mantiene orden natural.

HashSet<Integer> conjunto = new HashSet<>(Arrays.asList(3,1,2,1));
// conjunto = {1,2,3}
conjunto.add(4);                    // {1,2,3,4}
conjunto.remove(2);                 // {1,3,4}
conjunto.contains(3);               // true
conjunto.size();                    // 3

TreeSet<Integer> ordSet = new TreeSet<>(Arrays.asList(5,2,4,2));
// ordSet = {2,4,5}
ordSet.ceiling(3);  // 4 (mayor o igual)
ordSet.floor(3);    // 2 (menor o igual)

  1. HashMap / TreeMap

HashMap almacena pares clave-valor sin orden. TreeMap ordena por clave ascendente.

HashMap<String, Integer> mapa = new HashMap<>();
mapa.put("A", 10);
mapa.put("B", 20);
mapa.put("A", 30);  // sobrescribe

// Recorridos
for (String k : mapa.keySet()) System.out.println(k);
for (int v : mapa.values()) System.out.println(v);
for (Map.Entry<String,Integer> e : mapa.entrySet())
    System.out.println(e.getKey()+" "+e.getValue());

// Métodos
mapa.get("A");                 // 30
mapa.remove("B");              // elimina B
mapa.containsKey("A");         // true
mapa.containsValue(30);        // true

// TreeMap
TreeMap<String,Integer> tMap = new TreeMap<>();
tMap.put("Z", 1);
tMap.put("A", 2);
tMap.ceilingKey("B");          // "Z" (clave mínima >= "B")
tMap.floorKey("B");            // "A" (clave máxima <= "B")

  1. Stack

Se recomienda usar ArrayDeque como pila en lugar de la vieja clase Stack:

Deque<String> pila = new ArrayDeque<>();
pila.push("primero");
pila.push("segundo");
pila.push("tercero");
while (!pila.isEmpty())
    System.out.print(pila.pop() + " "); // tercero segundo primero

  1. Queue / PriorityQueue

LinkedList implementa Queue (FIFO). PriorityQueue ordena por prioridad.

Queue<Integer> cola = new LinkedList<>();
cola.offer(10); cola.offer(20); cola.offer(30);
while (cola.peek() != null)
    System.out.print(cola.poll() + " "); // 10 20 30

PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(5); pq.offer(1); pq.offer(3);
while (!pq.isEmpty())
    System.out.print(pq.poll() + " "); // 1 3 5

// Orden inverso
PriorityQueue<Integer> pqInv = new PriorityQueue<>(Collections.reverseOrder());
pqInv.addAll(Arrays.asList(5,1,3));
while (!pqInv.isEmpty())
    System.out.print(pqInv.poll() + " "); // 5 3 1

  1. Iterator y Collection

La interfaz Collection es la raíz de todas las colecciones. Permite escribir código genérico:

public static void mostrar(Iterator<?> it) {
    while (it.hasNext())
        System.out.print(it.next() + " ");
}

public static void mostrar(Collection<?> col) {
    for (Object o : col)
        System.out.print(o + " ");
}

// Uso
List<Integer> l = Arrays.asList(1,2,2);
Set<Integer> s = new HashSet<>(Arrays.asList(1,2,2));
mostrar(l.iterator());  // 1 2 2
mostrar(s.iterator());  // 1 2
mostrar(l);             // 1 2 2
mostrar(s);             // 1 2

  1. Ordenación de arreglos de objetos personalizados

Implementar Comparable<T> y sobrescribir compareTo:

class Dato implements Comparable<Dato> {
    int id;
    String nombre;
    Dato(int id, String nombre) {
        this.id = id;
        this.nombre = nombre;
    }
    @Override
    public int compareTo(Dato otro) {
        return otro.id - this.id; // orden descendente por id
    }
    @Override
    public String toString() {
        return "[" + id + ", " + nombre + "]";
    }
}

Dato[] datos = {new Dato(3, "Ana"), new Dato(1, "Luis"), new Dato(2, "Pedro")};
Arrays.sort(datos);
System.out.println(Arrays.toString(datos)); // [3, Ana] [2, Pedro] [1, Luis]

Etiquetas: java estructuras de datos StringBuilder ArrayList LinkedList

Publicado el 6-2 20:26