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.