🕐 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);
}

📌 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();
}

⚙️ 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.