🕐 Tempo di lettura: 3 minuti
Oggi mi sono trovato ad affrontare un problema interessante: estrapolare due liste da una collezione di oggetti di tipo generico Object, sapendo che al suo interno avrei trovato oggetti di due tipi distinti (A e B) di interesse e un insieme di oggetti aventi altro tipo da ignorare.
📌 Soluzione 1
private Tuple2<List<String>, List<Car>> solution1(final List<Object> objects) {
final List<String> strings = new ArrayList<>();
final List<Car> cars = new ArrayList<>();
for (final Object object : objects) {
if (object instanceof String str) {
strings.add(str);
} else if (object instanceof Car car) {
cars.add(car);
}
}
return Tuples.of(strings, cars);
}
- itera la lista una sola volta con un ciclo
fore controlliinstanceof, garantendo una complessità O(n) e riducendo il carico computazionale - popola le liste direttamente durante l'iterazione, con un'allocazione più diretta e contenuta
- più esplicita, chiara per chi non è familiare con lo Stream API, ma più verbosa
📌 Soluzione 2
private Tuple2<List<String>, List<Car>> solution2(final List<Object> objects) {
return Tuples.of(
filterAndCast(objects, String.class),
filterAndCast(objects, Car.class));
}
private static <T> List<T> filterAndCast(final List<?> objects, final Class<T> clazz) {
return objects.stream().filter(clazz::isInstance).map(clazz::cast).toList();
}
- utilizza lo Stream API di Java, con due passaggi per filtrare e castare, aumentando il costo su liste grandi, pur mantenendo una complessità O(n)
- lo stream potrebbe introdurre oggetti intermedi temporanei, aumentando leggermente il consumo di memoria
- più concisa ed elegante, migliora la leggibilità per chi conosce bene gli stream
⚙️ Efficienza, complessità e manutenibilità
In termini di efficienza, la Soluzione 1 è superiore, riducendo il numero di iterazioni. Tuttavia, la Soluzione 2 offre un approccio più elegante, ideale se la leggibilità è la priorità e il volume dei dati è contenuto. Per il mio caso, ho optato per la seconda soluzione: la lista è di dimensioni limitate e ho voluto privilegiare uno stile di codice più pulito e coerente con gli standard di progetto.