Algoritmos e estruturas de dados em Java: guia prático
\n\nDominar algoritmos e estruturas de dados é uma etapa fundamental na formação de um desenvolvedor Java. Isso não é apenas teoria: entender como funcionam listas, tabelas hash e algoritmos de ordenação impacta diretamente o desempenho e a escalabilidade do seu código. Neste artigo, abordaremos as principais estruturas de dados e algoritmos em Java com exemplos práticos que ajudarão você a escrever programas mais eficientes.
\n\n1. Arrays dinâmicos: ArrayList
\n\nArrayList é uma implementação de array dinâmico em Java. Ao contrário de um array comum, seu tamanho aumenta automaticamente à medida que novos elementos são adicionados. Esta é uma das estruturas de dados mais utilizadas.
Operações principais
\n- \n
- Adicionar elemento:
add(element)— O(1) na média, O(n) ao expandir o array. \n - Obter elemento por índice:
get(index)— O(1). \n - Remover elemento:
remove(index)— O(n), pois requer deslocamento de elementos. \n
import java.util.ArrayList;\n\npublic class ArrayListExample {\n public static void main(String[] args) {\n ArrayList<Integer> numbers = new ArrayList<>();\n \n numbers.add(10);\n numbers.add(20);\n numbers.add(30);\n \n System.out.println("Elemento no índice 1: " + numbers.get(1)); // 20\n \n numbers.remove(0); // Remove o primeiro elemento\n System.out.println("Tamanho após remoção: " + numbers.size()); // 2\n }\n}\n\n\nQuando usar: Quando você precisa de acesso rápido por índice e adiciona elementos com frequência ao final da lista.
\n\n2. Tabelas hash: HashMap
\n\nHashMap é uma estrutura de dados que armazena pares "chave-valor". Ela usa uma função hash para busca rápida. Em Java, HashMap é uma das coleções mais eficientes para operações de busca, inserção e remoção.
Como funciona?
\nCada chave é convertida em um código hash, que determina o "bucket" onde o valor será armazenado. Em caso de colisões (quando chaves diferentes geram o mesmo hash), são usadas listas encadeadas ou árvores rubro-negras (a partir do Java 8).
\n\nExemplo de uso
\n\nimport java.util.HashMap;\n\npublic class HashMapExample {\n public static void main(String[] args) {\n HashMap<String, Integer> studentGrades = new HashMap<>();\n \n studentGrades.put("Alice", 90);\n studentGrades.put("Bob", 85);\n studentGrades.put("Charlie", 92);\n \n // Busca de nota\n int aliceGrade = studentGrades.get("Alice");\n System.out.println("Nota da Alice: " + aliceGrade); // 90\n \n // Verificação de existência da chave\n if (studentGrades.containsKey("David")) {\n System.out.println("David está na lista");\n } else {\n System.out.println("David não encontrado");\n }\n \n // Iteração sobre todas as entradas\n for (String name : studentGrades.keySet()) {\n System.out.println(name + ": " + studentGrades.get(name));\n }\n }\n}\n\n\nComplexidade das operações: Em média O(1) para inserção, busca e remoção. No pior caso (com muitas colisões) — O(n).
\n\n3. Algoritmos de ordenação em Java
\n\nOrdenação é uma das operações básicas. O Java fornece métodos embutidos, mas entender seu funcionamento interno é fundamental para escrever código eficiente.
\n\nQuickSort (Ordenação rápida)
\n\nEste é um dos algoritmos de ordenação mais rápidos. Ele funciona pelo princípio de "dividir para conquistar": seleciona um elemento pivô e divide o array em duas partes — menores e maiores que o pivô.
\n\npublic class QuickSort {\n public static v