import java.util.List;

/** Métodos genéricos sobre listas. */
public final class ListUtils {

    private ListUtils() { }     // solo métodos estáticos: no se crean objetos

    /** El primer elemento de la lista, o fallback si está vacía. */
    public static <T> T firstOrDefault(List<T> list, T fallback) {
        return list.isEmpty() ? fallback : list.get(0);
    }

    /** El mayor elemento según su orden natural. La lista no puede estar vacía. */
    public static <T extends Comparable<T>> T max(List<T> list) {
        if (list.isEmpty()) {
            throw new IllegalArgumentException("lista vacía");
        }
        T best = list.get(0);
        for (T x : list) {
            if (x.compareTo(best) > 0) {
                best = x;
            }
        }
        return best;
    }

    /** Suma una lista de cualquier tipo numérico: Integer, Double, Long... */
    public static double sum(List<? extends Number> numbers) {
        double total = 0;
        for (Number n : numbers) {          // leer: sale algo que es un Number
            total += n.doubleValue();
        }
        return total;
    }

    /** Agrega 1, 2, ..., n a una lista que acepte Integer. */
    public static void addCounting(List<? super Integer> out, int n) {
        for (int i = 1; i <= n; i++) {
            out.add(i);                     // escribir: entra un Integer
        }
    }

    /** Copia src al final de dst. src produce T; dst consume T (PECS). */
    public static <T> void copy(List<? super T> dst, List<? extends T> src) {
        for (T x : src) {
            dst.add(x);
        }
    }
}
