-
Convertir una matriz en una ArrayList .
Para convertir una matriz en ArrayList , los desarrolladores suelen utilizar este método:
List<String> list = Arrays.asList(arr);
Arrays.asList()
devolverá un objeto de claseArrayList
que es una clase estática privada interna(private static class)
de la claseArrays
, y esta no es una clase .java.util.ArrayList.
La clasejava.util.Arrays.ArrayList
contiene métodosset()
, pero no contiene ningún método para agregar elementos, su tamaño es fijo . Para crear uno real , haga esto:get()
contains()
java.util.ArrayList
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
Un constructor de clase
java.util.ArrayList
puede tomar como parámetro todos los objetos que implementan una interfazCollection
, cuya implementación es heredada por la clase.java.util.Arrays.ArrayList
(La clase estática privada ArrayList<E> extiende AbstractList<E> implementa RandomAccess, java.io.Serializable).
-
Comprobando una matriz para un valor específico.
Los desarrolladores suelen hacer esto:
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);
El código funciona, pero no es necesario convertirlo
List
aSet
. La conversión aSet
llevará más tiempo. De hecho, todo es sencillo:Arrays.asList(arr).contains(targetValue);
o
for(String s: arr){ if(s.equals(targetValue)) return true; } return false;
El primer método es mucho más corto.
-
Eliminar un elemento de
List
un bucleConsidere el siguiente código que elimina elementos en un bucle:
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);
Conclusión:
[b, d]
Esto resulta ser un grave error. Cuando se elimina un elemento, el tamaño
List
se reduce y los índices del elemento cambian.Evite este método si desea eliminar varios elementos en un bucle utilizando un índice.
Es posible que sepa que usar un iterador es la solución correcta para eliminar elementos en un bucle y que un bucle de estilo
for-each
funciona como un iterador, pero no es así.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); }
Recibiremos una excepción ConcurrentModificationException .
Lo correcto es:
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(); } }
El método
En un estilo de buclenext()
debe llamarse antes delremove()
.for-each
, el compilador llamará al métodoremove()
, y sólo entoncesnext()
, lo que generará un errorConcurrentModificationException
. Puedes mirar el códigoArrayList.iterator()
. -
Hashtable
contraHashMap
.Debido a la implementación correspondiente, Hashtable es el nombre de la estructura de datos.
Pero en Java el nombre de una estructura de datos es
HashMap
. Una de las diferencias clave entreHashtable
yHashMap
es que estáHashtable
sincronizado, por lo que no debe usarseHashtable
dondeHashMap
.HashMap vs. Mapa de árbol vs. Tabla hash vs. LinkedHashMap .
-
Utilice colecciones sin restricciones de contenido
В Java часто путают коллекции без ограничений по содержимому, и коллекции с маской по типу содержимого. К примеру, для множеств -
Set
это коллекция без ограничений по содержимому, аSet<?>
— коллекция у которой все-таки есть ограничения, но эти ограничения ничего на самом деле не ограничивают. Рассмотрим следующий código, гдеList
без ограничений используется в качестве параметра метода: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); }
Данный código выбросит исключение:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at …
Использование коллекций без ограничений по содержимому очень опасно, потому что вы не можете быть уверенными в том что там лежит внутри. А для того чтобы понять всю глубину разницы между
Set
,Set<?>
иSet<Object>
— почитайте вот эту и эту ссылки. -
Уровень доступа
Очень часто для полей класса разработчики используют модификатор доступа
public
. Так проще получить significado поля напрямую. Правильнее использовать Cómo можно более ограниченный доступ к членам класса. ArrayList
противLinkedList
Когда разработчики не знают чем отличается
ArrayList
отLinkedList
, они используют первый в силу его большей известности. Однако, есть огромная разница в производительности между ними. На самом деле, выбор между ними должен быть продиктован их внутренними особенностями —ArrayList
позволяет быстро производить доступ к произвольному элементу массива, аLinkedList
— быстро добавлять/удалять элементы в массиве. Почитайте статью по ссылке ArrayList vs. LinkedList чтобы понять причины их разной производительности.Mutable
(Изменяемый) противImmutable
(Неизменяемый)Неизменяемый un objeto имеет много преимуществ: простота, безопасность и т.д. Но он требует отдельного un objetoа для каждого нового значения, и за слишком большое количество un objetoов придется заплатить понижением производительности. Должен быть баланс при выборе между изменяемым и неизменяемым обьектом.
В основном чтобы избежать подготовки промежуточных un objetoов используется изменяемый un objeto. Один из классических примеров это конкатенация большого количества строк. Если вы используете неизменяемый un objeto типа
String
, то вы создаете много un objetoов, которые сразу попадут в сборщик мусора. Это тратит время и энергию процессора, поэтому правильное решение это использование изменяемых обьектов (напримерStringBuilder
).String result=""; for(String s: arr){ result = result + s; }
Еще один пример использования изменяемых un objetoов — передача такого un objetoа в метод. Это позволит вернуть результат в нем же, без создания лишних un objetoов. При работе с un objetoами большого размера, к примеру коллекциями, передача коллекции в метод для сортировки и возвращение результата в другой коллекции приводит к совершенно излишнему расходу ресурсов. (Ответ пользователя dasblinkenlight на Stack Overflow).
-
Конструкторы классов
Super
иSub
Este error de compilación se debe al hecho de que la clase ancestral no tiene definido un constructor predeterminado. En Java , a menos que usted mismo especifique un constructor de clase, el compilador creará un constructor predeterminado que no requiere argumentos. Si el constructor se describe en la clase
Super
comoSuper(String s){}
, el compilador en sí no agregará nada. Esto es lo que vemos en nuestro ejemplo.El constructor de la clase
Sub
, no importa cuál, llamará al constructor predeterminado de la claseSuper
, ya que no se especifica nada más. Dado que no hay un constructor predeterminado en la claseSuper
, esto provocará un error de compilación.La primera solución a este problema es agregar un constructor predeterminado a la clase.
Super
public Super(){ System.out.println("Super"); }
La segunda opción es eliminar el constructor que describimos de la clase
Super
para que el compilador cree un constructor predeterminado.Y la última opción es agregar una llamada
super(value)
a los constructores de clasesSub
para que se llame al constructor de clases existente en lugar del constructor predeterminado.Super
-
" " o constructor?
Hay dos formas de crear una cadena:
//1. использовать двойные кавычки String x = "abc";
//2. использовать конструктор String y = new String("abc");
¿Cuál es la diferencia entre ellos?
Puedes entender esto a partir de los siguientes ejemplos:
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 información sobre cómo se almacenan las cadenas en la memoria, lea ¿ Crear una cadena Java usando "" o Constructor? .
GO TO FULL VERSION