Tag: java, algorithms, streams, collections, data structures, coding
Livello: intermedio
TL;DR: Pattern essenziali e strutture dati pronte all'uso per risolvere problemi di algoritmi in Java, puntando su leggibilità e performance.
Sfruttare java.util.stream.Stream per filtrare, mappare e ridurre collezioni in modo conciso.
Usare sempre StringBuilder invece della concatenazione manuale nei cicli per evitare memory leak di stringhe immutabili.
Ottimizzare i conteggi di frequenza con i metodi Map.computeIfAbsent e Map.merge.
Utilizzare HashSet per operazioni di lookup veloci con complessità O(1).
Adottare i record per creare rapidamente DTO o nodi di supporto immutabili senza boilerplate code.
Preferire ArrayDeque a Stack o LinkedList per implementare code (FIFO) e pile (LIFO).
Ricordare l'uso dei metodi factory come List.of(), Set.of() e Map.of() per inizializzare dati di test.
Q: Come inverti una stringa o verifichi se è palindroma senza cicli manuali?R: Uso direttamente new StringBuilder(str).reverse().toString() e verifico l'uguaglianza con equals().
Q: Come trovi gli elementi duplicati in una lista o array?R: Aggiungo gli elementi in un HashSet; il metodo add() restituisce false se l'elemento è già presente.
Q: Perché preferisci ArrayList rispetto a LinkedList per questa iterazione?R: Perché ArrayList offre accesso posizionale O(1) e garantisce una migliore cache locality in memoria.
Dimenticare la gestione di array vuoti, liste vuote o parametri null in ingresso.
Utilizzare l'operatore == invece del metodo .equals() per confrontare il valore degli oggetti (specialmente le stringhe).
Modificare strutturalmente una collezione tramite ciclo for-each (scatena ConcurrentModificationException).
Non considerare l'overflow dei tipi primitivi (es. usare int invece di long per la somma di array di grandi dimensioni).
Iniziare a scrivere classi e interfacce complesse quando basta un metodo statico essenziale.
// Conteggio delle occorrenze in una lista tramite Stream
Map<String, Long> frequenze = list.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
// Incrementare un contatore in una mappa in modo sicuro
Map<Integer, Integer> counter = new HashMap<>();
for (int num : nums) {
counter.merge(num, 1, Integer::sum);
}
// Ordinamento custom di array o liste
Arrays.sort(arr, Comparator.comparingInt(String::length).reversed());
// Conversione rapida tra array primitivi e collezioni
List<Integer> list = Arrays.stream(primitiveArray).boxed().toList();
int[] newArray = list.stream().mapToInt(Integer::intValue).toArray();
[ ] Implementazione manuale di Binary Search per array ordinati (Arrays.binarySearch).
[ ] Sintassi avanzata dei Collectors (es. partitioningBy, mapping).
[ ] Costruzione e attraversamento di un albero binario usando classi annidate.