2010-08-25 12 views

Respuesta

18

No, no puedes! Java ArrayList no proporciona una forma de acceder a su capacidad actual.

Solo puede construir un ArrayList especificando una capacidad inicial usando el constructor ArrayList(int initialCapacity) o aumentar la capacidad llamando al ensureCapacity().

+6

"No, no puedes". Una marca de excalmation habría hecho esto gracioso. –

+1

@klez es que ahora :)? – Gopi

+2

¡Ahora recibe mi aval señor! –

1

No necesita preocuparse por la capacidad, que es un detalle de implementación interna. Si el conjunto interno se llena, se expandirá. Puede averiguar cuántos elementos hay actualmente en su ArrayList con el método size().

1

Según la especificación: "La capacidad es el tamaño de la matriz utilizada para almacenar los elementos de la lista. Siempre es al menos tan grande como el tamaño de la lista. Cuando se agregan elementos a una ArrayList, su capacidad crece automáticamente Los detalles de la política de crecimiento no se especifican más allá del hecho de que agregar un elemento tiene un costo de tiempo amortizado constante ".

Así que no hay forma de saber cuál es la capacidad actual, ni cómo crece.

0

¿Lo necesita en tiempo de ejecución o está bien para realizarlo? Si está probando, normalmente puede ver la capacidad usando su depurador IDE favorito. No tengo el número exacto, pero 1.7 es generalmente el tamaño de crecimiento de la capacidad. Por lo tanto, si crea un arraylist con 10 elementos, java lo convertirá en el tamaño 17.

0

La API no lo proporciona. Internamente, la capacidad se multiplica por un factor cada vez que se agrega add (..) mientras está en plena capacidad. Sin embargo, la especificación de Java no dice nada acerca de este factor constante ... La implementación de Sun usa un factor de 1.5, por lo que tiene un límite superior de 1.5 * tamaño() para la capacidad.

Recuerde que puede usar trimToSize() para "compactar" la lista y hacer que la capacidad sea igual al tamaño().

10

El ArrayList es un abstracción para un automáticamente growable List de elementos. Raramente necesita conocer su capacidad. Considere Effective Java 2nd Edition, artículo 52: consulte los objetos por sus interfaces. Tanto como sea práctico, ni siquiera debería importar si es un ArrayList o un LinkedList; es solo un List.

Dicho esto, estos métodos pueden ser de su interés:

  • ArrayList(int initialCapacity)
    • construye una lista vacía con la capacidad inicial especificada.
  • void ensureCapacity(int minCapacity)
    • aumenta la capacidad de este ArrayList ejemplo, si es necesario, para asegurar que puede contener al menos el número de elementos especificados por el argumento de capacidad mínima.
  • void trimToSize()
    • recorta la capacidad de este ArrayList instancia que va a tamaño actual de la lista. Una aplicación puede usar esta operación para minimizar el almacenamiento de una instancia ArrayList.
+0

Creo que la palabra de Bloch es definitiva. – ncmathsadist

63

Tengo curiosidad, ¿qué necesitas? Debe saber que la capacidad no es (como puede parecer) un límite superior de cuánto puede poner en ArrayList. Es un valor que representa la cantidad de datos que puede poner en la lista, sin forzarlo a reasignar su matriz interna. Básicamente, la noción de capacidad solo está ahí para poder modificar ligeramente el rendimiento.

De todos modos, quizás ya lo sepas, así que aquí viene la respuesta real.

La interfaz proporcionada por API para ArrayList simplemente no admite dicho caso de uso. Hay muchas razones para esto. Una razón es que no deberías preocuparte por esto. ArrayList debe considerarse como una matriz ilimitada que se abstrae de detalles como la capacidad.

Lo más cerca que puede llegar a controlar la capacidad es a través del constructor ArrayList(int initialCapacity), y los dos métodos trimToSize() y ensureCapacity(int minCapacity).

Para la diversión sin embargo, he conseguido resolverlo a través de una reflexión fea -Hack (no utilice este):

import java.lang.reflect.Field; 
import java.util.ArrayList; 
public class Test { 

    public static void main(String[] args) throws Exception { 
     ArrayList<Integer> list = new ArrayList<Integer>(3); 
     for (int i = 0; i < 17; i++) { 
      list.add(i); 
      System.out.format("Size: %2d, Capacity: %2d%n", 
           list.size(), getCapacity(list)); 
     } 
    } 

    static int getCapacity(ArrayList<?> l) throws Exception { 
     Field dataField = ArrayList.class.getDeclaredField("elementData"); 
     dataField.setAccessible(true); 
     return ((Object[]) dataField.get(l)).length; 
    } 
} 

Salida:

Size: 1, Capacity: 3 
Size: 2, Capacity: 3 
Size: 3, Capacity: 3 
Size: 4, Capacity: 5 
Size: 5, Capacity: 5 
Size: 6, Capacity: 8 
Size: 7, Capacity: 8 
Size: 8, Capacity: 8 
Size: 9, Capacity: 13 
Size: 10, Capacity: 13 
Size: 11, Capacity: 13 
Size: 12, Capacity: 13 
Size: 13, Capacity: 13 
Size: 14, Capacity: 20 
Size: 15, Capacity: 20 
Size: 16, Capacity: 20 
Size: 17, Capacity: 20 
+3

Estoy tentado de votar esto, incluso aunque sea correcto, en profundidad y advierte sobre los peligros de tratar de eludirlo, solo porque proporciona un código para el feo truco ... –

+16

Claro, se debe enfatizar que este método no se debe usar en el código de producción. Sin embargo * podría ser el caso si alguien desea, por ejemplo, depurar algún problema de rendimiento o similar, en cuyo caso el fragmento de código anterior puede ser útil. Pero como escribí en la respuesta, lo implementé por diversión y realmente no debería usarse en el 99% de los casos. – aioobe

+0

@aiobee nice hack :) Para que su respuesta sea más completa, le sugiero que también mencione java sdk/jvm que usó. Dado que el funcionamiento exitoso de esto se basaría en la implementación de la plataforma java que está utilizando. – Gopi

1

estoy va a cambiar la tendencia aquí ... el usuario tiene una pregunta, aunque sin contexto. Sin contexto, conocer la capacidad es innecesario ya que la matriz de respaldo crecerá para acomodar ...

Puede hacer lo siguiente para saber con certeza cuál es la capacidad de su ArrayList. El efecto secundario es que la matriz de respaldo se recortará al número exacto de elementos en la matriz:

ArrayList list = new ArrayList(); 
//add a bunch of elements 
list.trimToSize(); 
System.out.println("Capacity = " + list.size()); 

¡Disfrútelo!

+1

En ArrayList, el método size() devuelve cuántos elementos (objetos) hay en la lista, no la capacidad. – subhashis

Cuestiones relacionadas