Esta lista resume los 10 errores principales que los desarrolladores de Java cometen con frecuencia.
# 1. Convertir Array en ArrayList
Para convertir una matriz en una ArrayList
, los desarrolladores suelen hacer esto:
List<String> list = Arrays.asList(arr); |
Arrays.asList()
devolverá un ArrayList
que es una clase estática privada dentro Arrays
, no es el java.util.ArrayList
clase. los java.util.Arrays.ArrayList
la clase tiene set()
, get()
, contains()
métodos, pero no tiene ningún método para agregar elementos, por lo que su tamaño es fijo. Para crear un real ArrayList
, deberías hacer:
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr)); |
El constructor de ArrayList
puede aceptar un tipo de colección, que también es un súper tipo para java.util.Arrays.ArrayList
.
# 2. Compruebe si una matriz contiene un valor
Los desarrolladores suelen hacer:
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue); |
El código funciona, pero no es necesario convertir una lista para establecer primero. Convertir una lista en un conjunto requiere más tiempo. Puede ser tan simple como:
Arrays.asList(arr).contains(targetValue); |
o
for(String s: arr){ if(s.equals(targetValue)) return true; } return false; |
El primero es más legible que el segundo.
# 3. Eliminar un elemento de una lista dentro de un bucle
Considere el siguiente código que elimina elementos durante la iteración:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (int i = 0; i < list.size(); i++) { list.remove(i); } System.out.println(list); |
La salida es:
[b, d]
Hay un problema serio en este método. Cuando se elimina un elemento, el tamaño de la lista se reduce y el índice cambia. Entonces, si desea eliminar varios elementos dentro de un bucle utilizando el índice, eso no funcionará correctamente.
Puede saber que usar un iterador es la forma correcta de eliminar elementos dentro de los bucles, y sabe que cada bucle en Java funciona como un iterador, pero en realidad no lo es. Considere el siguiente código:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) { if (s.equals("a")) list.remove(s); } |
Lanzará ConcurrentModificationException.
En cambio, lo siguiente está bien:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); Iterator<String> iter = list.iterator(); while (iter.hasNext()) { String s = iter.next(); if (s.equals("a")) { iter.remove(); } } |
.next()
debe ser llamado antes .remove()
. En el bucle foreach, el compilador hará que el .next()
llamado después de la operación de eliminación de elemento, que causó el ConcurrentModificationException
. Es posible que desee echar un vistazo al código fuente de ArrayList.iterator ().
# 4. Hashtable vs HashMap
Por convenciones en algoritmo, Hashtable es el nombre de la estructura de datos. Pero en Java, el nombre de la estructura de datos es HashMap
. Una de las diferencias clave entre Hashtable
y HashMap
es eso Hashtable
está sincronizado. Muy a menudo no necesitas Hashtable
, en lugar de HashMap
debería ser usado.
HashMap frente a TreeMap frente a Hashtable frente a LinkedHashMap
Las 10 preguntas principales sobre Map
# 5. Usar tipo de colección sin procesar
En Java, tipo crudo y tipo comodín ilimitado son fáciles de mezclar. Tomemos a Set por ejemplo, Set
es de tipo crudo, mientras que Set<?>
es de tipo comodín ilimitado.
Considere el siguiente código que usa un tipo sin formato List
como parámetro:
public static void add(List list, Object o){ list.add(o); } public static void main(String[] args){ List<String> list = new ArrayList<String>(); add(list, 10); String s = list.get(0); } |
Este código arrojará una excepción:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at ...
El uso de la colección de tipos sin formato es peligroso, ya que las colecciones de tipos sin procesar omiten la verificación de tipos genéricos y no son seguras. Hay grandes diferencias entre Set
, Set<?>
, y Set<Object>
. Revisa
Tipo sin formato vs. comodín ilimitado y borrado de tipo.
# 6. Nivel de acceso
Muy a menudo, los desarrolladores utilizan public para el campo de clase. Es fácil obtener el valor del campo haciendo referencia directamente, pero este es un diseño muy malo. La regla general es dar un nivel de acceso a los miembros lo más bajo posible.
público, predeterminado, protegido y privado
# 7. ArrayList frente a LinkedList
Cuando los desarrolladores no conocen la diferencia entre ArrayList
y LinkedList
, a menudo usan ArrayList
, porque parece familiar. Sin embargo, existe una gran diferencia de rendimiento entre ellos. En breve, LinkedList
debería ser preferible si hay una gran cantidad de operaciones de agregar / quitar y no hay muchas operaciones de acceso aleatorio. Revisa ArrayList
vs. LinkedList
para obtener más información sobre su desempeño si esto es nuevo para usted.
# 8. Mutable frente a inmutable
Los objetos inmutables tienen muchas ventajas como simplicidad, seguridad, etc. Pero requiere un objeto separado para cada valor distinto, y demasiados objetos pueden causar un alto costo de recolección de basura. Debe haber un equilibrio al elegir entre mutable e inmutable.
En general, los objetos mutables se utilizan para evitar producir demasiados objetos intermedios. Un ejemplo clásico es la concatenación de una gran cantidad de cadenas. Si usa una cadena inmutable, produciría una gran cantidad de objetos que son elegibles para la recolección de basura de inmediato. Esto desperdicia tiempo y energía en la CPU, utilizando un objeto mutable, la solución correcta (p. Ej. StringBuilder
).
String result=""; for(String s: arr){ result = result + s; } |
Hay otras situaciones en las que se desean objetos mutables. Por ejemplo, pasar objetos mutables a métodos le permite recopilar varios resultados sin pasar por demasiados aros sintácticos. Otro ejemplo es la clasificación y el filtrado: por supuesto, podría crear un método que tome la colección original y devuelva una clasificada, pero eso sería extremadamente inútil para colecciones más grandes. (Desde respuesta de dasblinkenlight en Stack Overflow)
¿Por qué String es inmutable?
# 9. Constructor de Super y Sub
Este error de compilación se produce porque el superconstructor predeterminado no está definido. En Java, si una clase no define un constructor, el compilador insertará un constructor sin argumentos predeterminado para la clase por defecto. Si un constructor está definido en la clase Super, en este caso Super (String s), el compilador no insertará el constructor sin argumentos predeterminado. Esta es la situación de la clase Super anterior.
Los constructores de la clase Sub, ya sea con argumento o sin argumento, llamarán al superconstructor sin argumento. Dado que el compilador intenta insertar super () en los 2 constructores de la clase Sub, pero el constructor predeterminado de Super no está definido, el compilador informa el mensaje de error.
Para solucionar este problema, simplemente 1) agregue un constructor Super () a la clase Super como
public Super(){ System.out.println("Super"); } |
, o 2) eliminar el superconstructor autodefinido, o 3) agregar super(value)
a los subconstructores.
Constructor de Super y Sub
# 10. «» o Constructor?
La cadena se puede crear de dos formas:
//1. use double quotes String x = "abc"; //2. use constructor String y = new String("abc"); |
¿Cuál es la diferencia?
Los siguientes ejemplos pueden proporcionar una respuesta rápida:
String a = "abcd"; String b = "abcd"; System.out.println(a == b); // True System.out.println(a.equals(b)); // True String c = new String("abcd"); String d = new String("abcd"); System.out.println(c == d); // False System.out.println(c.equals(d)); // True |
Para obtener más detalles sobre cómo se asignan en la memoria, consulte Crear cadena Java usando ”” o Constructor ?.
Trabajo futuro
La lista se basa en mi análisis de una gran cantidad de proyectos de código abierto en GitHub, preguntas de Stack Overflow y consultas populares de Google. No hay ninguna evaluación que demuestre que son precisamente los 10 primeros, pero definitivamente son muy comunes. Deje su comentario si no está de acuerdo con alguna parte. Realmente agradecería si pudiera señalar algunos otros errores que son más comunes.