Ventajas y desventajas de AarrayList

Ventajas de la lista de matrices (consulta rápida, adición y eliminación lentas)

Desventajas de ArrayList (adición y eliminación lentas, consulta rápida)

De hecho, es relativamente sencillo entender estos dos puntos, es decir, entender la estructura de datos (una comprensión de la matriz), cada estructura de datos tiene su propia complejidad temporal y espacial , lo que significa que el problema de eficiencia es similar a O (1), O (n), O (logn) Estos son la complejidad, y también existe el nivel de implementación de Java . Este artículo hablará sobre los problemas de eficiencia y rendimiento de estos niveles

La primera parte: matriz (estructura de datos)

Se menciona en el libro Estructura de datos: Array puede considerarse como una estructura de datos lineal extendida, su particularidad no se refleja en el funcionamiento de elementos de datos como pilas y colas, sino que se refleja en la composición de elementos de datos. en. Desde la perspectiva de los elementos que componen la tabla lineal, la matriz tiene una determinada estructura de elementos de datos y la matriz es la extensión de la tabla lineal.

Mas cerca de casa:

Array es una estructura de datos con la que todos estamos muy familiarizados, y los lenguajes de alto nivel generalmente admiten este tipo de datos.

La matriz es una tabla lineal , es decir, la estructura de la línea de datos es como una línea recta, excepto por la matriz, como la lista vinculada, la cola y la pila son todas estructuras lineales

La tabla no lineal es un árbol binario, pila, dibujo, etc., no es una relación simple entre los datos que tiene

¿La relación entre matriz y lista vinculada?

Normalmente respondemos: las listas enlazadas son adecuadas para la inserción y eliminación, y la complejidad del tiempo es O (1); las matrices son adecuadas para la búsqueda y la complejidad del tiempo de búsqueda es O (1)

De hecho, esta expresión es inexacta. Las matrices son adecuadas para la búsqueda, pero la complejidad temporal de la búsqueda no es O (1). Por lo tanto, la expresión correcta es que la matriz admite acceso aleatorio, de acuerdo con la siguiente tabla (posición del índice) acceso aleatorio La complejidad del tiempo es O (1)

Para conocer las matrices de estructuras de datos específicas, puede consultar libros específicos para aprender sobre ellas. Los métodos de almacenamiento y cálculo de matrices en computadoras se pueden estudiar y aprender. Para una comprensión profunda del autor, ¿por qué elegir esta forma? ¿Y el diseño será de gran ayuda, y también ayudará a entender por qué estamos preguntando?

Parte 2: Análisis desde el nivel de origen de ArrayList

Ya he dicho algunos conocimientos sobre matrices. Ahora debo tener cierta comprensión de las matrices. De hecho, no importa si no las entiendes demasiado a fondo. Es suficiente conocer las características fijas de las matrices. Por lo tanto, la capa inferior de la lista de matrices se basa en matrices. Entonces, ahora debemos entender por qué arraylist agrega y elimina rápidamente y la consulta es lenta. Analicemos esto desde la perspectiva del código fuente:

  /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
//入参为索引值,也就是下标
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

 // Positional Access Operations

    @SuppressWarnings("unchecked")
    E elementData(int index) {
        return (E) elementData[index];
    }

 El código anterior es la implementación del código fuente de la lista de matrices, porque la capa inferior se implementa en base a matrices, y las características de las matrices también son rápidas para agregar y eliminar consultas. Ahora los datos se obtienen directamente en base a subíndices, por lo que la complejidad de tiempo es O (1), y la lista de matrices Se implementa la interfaz RandomAccess y se admite el acceso aleatorio, lo que deja en claro que la eficiencia de las consultas es muy rápida.

El problema de las adiciones y eliminaciones lentas se puede investigar en profundidad, y no hay mucho que decir: mirar el código fuente puede ser más útil para comprender la estructura de datos de la matriz

/**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
 private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

 private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
  private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

@SuppressWarnings("unchecked")
    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }

  public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

  public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

Lo anterior son los datos de agregar elementos al final de la matriz. La complejidad del tiempo no tiene ningún efecto. Solo verificará una operación de expansión (que también es una operación que consume rendimiento durante el proceso de expansión). Use una imagen para describirlo vívidamente:

Pero si lo agrega en una ubicación específica, afectará en gran medida el rendimiento.

  public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
//在这一步执行native声明的方法的时候,就是耗费时间和性能的一步操作了,在底层具体的实现方式是这样的
        System.arraycopy(elementData, index, elementData, index + 1,
                size - index);
        elementData[index] = element;
        size++;
    }

 Ahora explique, la razón por la que el rendimiento es relativamente bajo es porque cada vez que agrega un elemento, como agregar un elemento en la posición 2, el elemento después de la posición 1 debe moverse hacia atrás. El proceso de movimiento afecta el rendimiento, que es el código anterior Este paso de la operación arrayCopy y la verificación de expansión también existirán.

método de eliminación:

 public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index + 1, elementData, index,
                    numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

Al observar el código fuente anterior, debe quedar muy claro. En realidad, es lo mismo que el método de adición. A continuación, se muestra una descripción de la imagen dinámica:

Ahora debería tener una buena comprensión de la lenta adición y eliminación de consultas de arrayList. Si hay algún problema con la descripción, hablemos juntos. Quizás la descripción de las matrices en este artículo no sea particularmente detallada. Si no la entiende, puede aprenderla usted mismo. Agregaré algunas estructuras de datos básicas en el futuro.

Supongo que te gusta

Origin blog.csdn.net/crossroads10/article/details/99708141
Recomendado
Clasificación