
89. ¿En qué se diferencia una ArrayList de una LinkedList?
Esta es una de las preguntas más populares, junto con la pregunta sobre la estructura interna de un HashMap . Ninguna entrevista está completa sin él, por lo que su respuesta debería salir fácilmente de su lengua. Además de lo obvio (tienen nombres diferentes), se diferencian en su estructura interna. Anteriormente, analizamos la estructura interna de ArrayList y LinkedList , por lo que no profundizaré en los detalles de su implementación. Sólo te recordaré que ArrayList se implementa utilizando una matriz interna cuyo tamaño aumenta dinámicamente según esta fórmula:<size of the current array> * 3 / 2 + 1
Además, la implementación de una LinkedList utiliza una lista interna doblemente enlazada, es decir, cada elemento tiene una referencia al elemento anterior y siguiente, excepto los elementos al inicio y al final de la lista. A los entrevistadores les encanta hacer esta pregunta: "¿Cuál es mejor, ArrayList o LinkedList ?" esperando atraparte. Al fin y al cabo, si dices que uno u otro es mejor, entonces has dado la respuesta equivocada. 
-
Si no se especifica un índice, se agregará automáticamente un nuevo elemento al final para ambos tipos de listas. En LinkedList , el nuevo elemento se convertirá en la nueva cola (solo se reescribirán un par de referencias, por lo que la complejidad algorítmica es O(1) ).
El método add agrega un elemento a la última celda vacía de la matriz ( O(1) ).
-
Agregar un elemento por índice generalmente significa insertarlo en algún lugar en el medio de la lista. En una LinkedList , el método primero buscará la ubicación deseada iterando sobre los elementos de la cola y la cabeza ( O(n/2) ) y luego insertará el valor sobrescribiendo las referencias de los elementos en ambos lados de donde está Se inserta un nuevo elemento ( O(1) ). La complejidad algorítmica general de esta operación será O(n/2) .
En la misma situación (agregando por índice), un ArrayList encuentra la ubicación deseada ( O(1) ) y luego desplaza todos los elementos ubicados a la derecha (incluido el elemento ya almacenado en el índice especificado) hacia la derecha en uno (que puede requerir la creación de una nueva matriz interna y copiar elementos en ella) ( O(n/2) ). La complejidad general es O(n/2) .
-
Agregar un elemento al principio de una LinkedList es similar a agregar un elemento al final: el nuevo elemento se convierte en el nuevo encabezado ( O(1) ). Pero para una ArrayList, esa operación requiere mover todos los elementos hacia la derecha ( O(n) ).
90. ¿En qué se diferencia un ArrayList de un HashSet?
Si pudiéramos comparar ArrayList y LinkedList operación por operación para determinar cuál es mejor, no nos resultaría tan fácil hacer esa comparación entre ArrayList y HashSet , porque son colecciones completamente diferentes. Puedes comparar un postre con otro, pero comparar un postre y un plato salado es un desafío: son dolorosamente diferentes. Aún así, intentaré señalar algunas de las diferencias entre ellos:-
ArrayList implementa la interfaz List mientras que HashSet implementa la interfaz Set .
-
ArrayList le permite acceder a un elemento por índice: la operación de obtención tiene una complejidad algorítmica O(1) , pero HashSet solo le permite acceder a un elemento deseado mediante iteración, lo que produce una complejidad algorítmica que va de O(1) a O(n) .
-
ArrayList permite elementos duplicados. En un HashSet , todos los elementos son únicos: cualquier intento de agregar un elemento que ya esté presente en un HashSet fallará (los duplicados se verifican mediante código hash, de ahí el nombre de esta colección).
-
ArrayList se implementa usando una matriz interna, pero HashSet se implementa usando un HashMap interno .
-
ArrayList mantiene el orden de inserción de los elementos, pero HashSet es un conjunto desordenado y no mantiene el orden de los elementos.
-
ArrayList permite cualquier número de valores nulos, pero solo puede agregar un valor nulo a un HashSet (después de todo, los elementos deben ser únicos).
91. ¿Por qué Java tiene tantas implementaciones de matrices dinámicas diferentes?
Ésta es más una cuestión filosófica. También podríamos preguntarnos ¿por qué se les ocurren tantas tecnologías nuevas y variadas? Por conveniencia. Y lo mismo ocurre con una gran cantidad de implementaciones de matrices dinámicas. Ninguno de ellos puede considerarse la implementación mejor o ideal. Cada uno tiene sus ventajas en situaciones específicas. Nuestro trabajo es conocer sus diferencias y sus fortalezas/debilidades para poder utilizar la colección que mejor se adapte a cada situación.92. ¿Por qué Java tiene tantas implementaciones diferentes de almacenamiento de valores-clave?
Aquí la situación es la misma que con las implementaciones de matrices dinámicas. Definitivamente no hay ninguno que sea universalmente mejor que los demás: cada uno tiene fortalezas y debilidades. Y hay que aprovechar sus puntos fuertes, por supuesto. Ejemplo: el paquete concurrente, que tiene muchas clases multiproceso, tiene sus propias colecciones concurrentes . La clase ConcurrentHashMap tiene una ventaja sobre el HashMap estándar en términos de seguridad cuando se trabaja con datos en un entorno de subprocesos múltiples, pero eso tiene el costo de un rendimiento más lento. Y las implementaciones que no son la mejor opción en ninguna situación dejan de utilizarse gradualmente. Por ejemplo: Hashtable , que originalmente estaba destinado a ser un HashMap seguro para subprocesos , se ha olvidado y ha dejado de usarse, porque ConcurrentHashMap es incluso mejor que Hashtable cuando se trabaja en un entorno de subprocesos múltiples.93. ¿Cómo clasifico una colección de elementos?
Lo primero que hay que decir es que la clase que representa los elementos de la colección debe implementar la interfaz Comparable , que consta del método compareTo . O necesita una clase que implemente la interfaz Comparator , incluido su método de comparación . Ambos métodos indican cómo comparar objetos de un tipo determinado. Esto es fundamental a la hora de ordenar, porque el algoritmo de clasificación necesita comprender qué principio utilizar para comparar elementos. Esto se hace principalmente implementando Comparable directamente en la clase que desea ordenar. Usar Comparator es menos común. Supongamos que estás usando una clase de alguna biblioteca y no implementa Comparable , pero necesitas ordenar una colección de sus objetos. Como no puedes cambiar el código de esta clase (excepto extendiéndolo), puedes escribir una implementación de Comparator que indique cómo comparar objetos de la clase. Y un ejemplo más. Si necesita ordenar objetos del mismo tipo de diferentes maneras, puede escribir múltiples implementaciones de Comparator para usarlas en diferentes situaciones. Como regla general, muchas clases listas para usar, por ejemplo String , ya implementan la interfaz Comparable . Eso significa que no necesita preocuparse por cómo comparar estas clases. Puedes seguir adelante y usarlos. La primera y más obvia forma es utilizar la clase TreeSet o TreeMap . Estas clases almacenan elementos en orden según el comparador implementado por los elementos de la clase. No olvide que TreeMap ordena claves, no valores. Si usa Comparator en lugar de Comparable , entonces deberá pasar un objeto Comparator al constructor de la colección cuando la cree:TreeSet treeSet = new TreeSet(customComparator);
¿Pero qué pasa si tienes un tipo diferente de colección? ¿Cómo lo ordenas? En este caso, la segunda forma de la clase de utilidad Colecciones , el método sort() , es adecuada. El método es estático, por lo que todo lo que necesita es anteponer el nombre de la clase y luego pasar la lista para ordenar. Por ejemplo:
Collections.sort(someList);
Si está utilizando una implementación de Comparator en lugar de Comparable , debe pasarla como segundo argumento:
Collections.sort(someList, customComparator);
Esta operación cambiará el orden interno de los elementos en la lista pasada: la lista se ordenará usando el comparador. Tenga en cuenta que la lista pasada debe ser mutable; de lo contrario, el método fallará y generará una excepción UnsupportedOperationException . Una tercera opción es utilizar el método ordenado de la clase Stream , que ordena los elementos de la colección. Si usamos Comparable :
someList = someList.stream().sorted().collect(Collectors.toList());
Si usamos Comparador :
someList = someList.stream().sorted(customComparator).collect(Collectors.toList());
La cuarta forma es implementar manualmente un algoritmo de clasificación, por ejemplo, clasificación por burbujas
o clasificación por fusión
.
Clase de objeto. es igual () y hashCode ()
94. Dé una breve descripción de la clase Objeto en Java.
En la segunda parte de la revisión, ya analizamos los métodos de la clase Objeto . Aquí les recordaré que la clase Objeto es un antepasado de todas las clases en Java. Tiene 11 métodos, que a su vez son heredados por todas las clases.
95. ¿Para qué se utilizan iguales () y hashCode () en Java?
hashCode() es un método de la clase Object que heredan todas las clases. Su trabajo es generar un número que represente un objeto específico. Se puede encontrar un ejemplo de este método en acción en HashMap , donde se llama a objetos clave para obtener el código hash local, que determinará en qué depósito (celda de la matriz interna) se almacenará el par clave-valor. Además, Este método se usa generalmente en el método equals() como una de sus principales formas de identificar objetos. equals() es un método de la clase Object cuyo trabajo es comparar objetos y determinar si son iguales. Este método se utiliza en todos los lugares donde necesitamos comparar objetos, porque el operador de comparación estándar == no es adecuado para objetos, ya que solo compara referencias de objetos.96. ¿Cuéntenos sobre el contrato entre iguales () y hashCode () en Java?
Primero, déjame decirte que para que los métodos equals() y hashCode() funcionen correctamente, deben anularse correctamente. Sus nuevas implementaciones deben seguir estas reglas:- Los objetos idénticos para los cuales igual devuelve verdadero deben tener los mismos códigos hash.
- Los objetos con los mismos códigos hash no son necesariamente iguales.
GO TO FULL VERSION