sets retainall remove metodos linkedset java collections enumset

java - retainall - ¿Por qué EnumSet tiene muchos métodos "de" sobrecargados?



set toarray java (4)

Al pasar por EnumSet<E> of método, he visto varias implementaciones of método of sobrecarga:

public static <E extends Enum<E>> EnumSet<E> of(E e) public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) . . public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5)

y luego otro método sobrecargado con varargs

public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) { EnumSet<E> result = noneOf(first.getDeclaringClass()); result.add(first); for (E e : rest) result.add(e); return result; }

Cuando este varargs podría haber manejado las otras implementaciones, ¿por qué este método está sobrecargado de esta manera? ¿Hay alguna razón específica para esto?

Había revisado el Javadoc de la misma, pero no pude encontrar ninguna explicación convincente.


Los métodos de Varargs crean una matriz.

public static void foo(Object... args) { System.out.println(args.length); }

Esto funciona, debido a la creación de matriz implícita. EnumSet es una clase diseñada para ser muy, muy rápida, por lo que al crear todas las sobrecargas adicionales pueden omitir el paso de creación de matriz en los primeros casos. Esto es especialmente cierto, ya que en muchos casos Enum no tiene tantos elementos, y si lo hacen, EnumSet posible que EnumSet no los contenga a todos.

Javadoc para EnumSet<E> of(E e1, E e2, E e3, E e4, E e5) :

Crea un conjunto de enumeraciones que contiene inicialmente los elementos especificados. Existen sobrecargas de este método para inicializar un conjunto de enumeraciones con uno a cinco elementos. Se proporciona una sexta sobrecarga que usa la función varargs. Esta sobrecarga puede usarse para crear un conjunto de enumeraciones que contiene inicialmente una cantidad arbitraria de elementos, pero es probable que se ejecute más lento que las sobrecargas que no usan varargs.


Desde el javadoc :

Existen sobrecargas de este método para inicializar un conjunto de enumeraciones con uno a cinco elementos. Se proporciona una sexta sobrecarga que usa la función varargs. Esta sobrecarga puede usarse para crear un conjunto de enumeraciones que contiene inicialmente una cantidad arbitraria de elementos, pero es probable que se ejecute más lento que las sobrecargas que no usan varargs.


Porque esa clase fue diseñada por Josh Bloch, y ese tipo sabe cómo funcionan las cosas. :) Además de crear una matriz, el método varargs contiene el bucle, que es más trabajo para el JIT para optimizar el código.

Por ejemplo, si miramos la implementación de la versión sobrecargada con cinco parámetros:

result.add(e1); result.add(e2); result.add(e3); result.add(e4); result.add(e5);

notamos que se trata de un tipo de bucle ya desenrollado que podría verse así:

for (E e : Arrays.asList(e1, e2, e3, e4, e5)) { result.add(e); }

Además, los métodos más cortos y simples son más propensos a estar en línea que los más largos y más complejos.


varags crea una matriz, que es cuando llamamos

void x(int...x) {...} .. x(1);

El compilador reemplaza la última línea con esto:

x(new int[] {1});

No sucederá si tenemos un método sobrecargado con 1 arg:

void x(int...x) {...} void x(int x) {...}

Entonces el compilador elegirá el segundo método.