-
Convertendo um array em um ArrayList .
Para converter um array em ArrayList , os desenvolvedores costumam usar este método:
List<String> list = Arrays.asList(arr);
Arrays.asList()
retornará um objeto de classeArrayList
que é uma classe estática privada interna(private static class)
da classeArrays
, e esta não é uma classe.java.util.ArrayList.
A classejava.util.Arrays.ArrayList
contém métodos ,,,,set()
mas não contém nenhum método para adicionar elementos, seu tamanho é fixo . Para criar um real , faça o seguinte:get()
contains()
java.util.ArrayList
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
Um construtor de classe
java.util.ArrayList
pode tomar como parâmetro todos os objetos que implementam uma interfaceCollection
, cuja implementação é herdada pela classejava.util.Arrays.ArrayList
(classe estática privada ArrayList<E> estende AbstractList<E> implementa RandomAccess, java.io.Serializable).
-
Verificando uma matriz em busca de um valor específico.
Os desenvolvedores costumam fazer isso:
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);
O código funciona, mas não há necessidade de convertê-lo
List
paraSet
. A conversão paraSet
levará mais tempo. Na verdade, tudo é simples:Arrays.asList(arr).contains(targetValue);
ou
for(String s: arr){ if(s.equals(targetValue)) return true; } return false;
O primeiro método é muito mais curto.
-
Removendo um elemento de
List
um loopConsidere o seguinte código que remove elementos de um loop:
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);
Conclusão:
[b, d]
Isso acaba sendo um erro grave. Quando um elemento é removido, o tamanho
List
é reduzido e os índices do elemento mudam.Portanto, evite esse método se quiser remover vários elementos em um loop usando um índice.
Você deve saber que usar um iterador é a solução correta para remover elementos em um loop e sabe que um loop de estilo
for-each
funciona como um iterador, mas não funciona.Considere o seguinte 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); }
Receberemos uma ConcurrentModificationException .
A coisa correta a fazer é:
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(); } }
O método
Em um estilo loopnext()
deve ser chamado antes doremove()
.for-each
, o compilador chamará o métodoremove()
, e só entãonext()
, o que gerará um erroConcurrentModificationException
. Você pode olhar o códigoArrayList.iterator()
. -
Hashtable
contraHashMap
.Devido à implementação correspondente, Hashtable é o nome da estrutura de dados.
Mas em Java o nome de uma estrutura de dados é
HashMap
. Uma das principais diferenças entreHashtable
eHashMap
é que ele éHashtable
sincronizado, portanto não deve ser usadoHashtable
ondeHashMap
. -
Use coleções sem restrições de conteúdo
В Java часто путают коллекции без ограничений по содержимому, и коллекции с маской по типу содержимого. К примеру, для множеств -
Set
это коллекция без ограничений по содержимому, аSet<?>
— коллекция у которой все-таки есть ограничения, но эти ограничения ничего на самом деле не ограничивают. Рассмотрим следующий code, где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); }
Данный code выбросит исключение:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at …
Использование коллекций без ограничений по содержимому очень опасно, потому что вы не можете быть уверенными в том что там лежит внутри. А для того чтобы понять всю глубину разницы между
Set
,Set<?>
иSet<Object>
— почитайте вот эту и эту ссылки. -
Уровень доступа
Очень часто для полей класса разработчики используют модификатор доступа
public
. Так проще получить meaning поля напрямую. Правильнее использовать How можно более ограниченный доступ к членам класса. ArrayList
противLinkedList
Когда разработчики не знают чем отличается
ArrayList
отLinkedList
, они используют первый в силу его большей известности. Однако, есть огромная разница в производительности между ними. На самом деле, выбор между ними должен быть продиктован их внутренними особенностями —ArrayList
позволяет быстро производить доступ к произвольному элементу массива, аLinkedList
— быстро добавлять/удалять элементы в массиве. Почитайте статью по ссылке ArrayList vs. LinkedList чтобы понять причины их разной производительности.Mutable
(Изменяемый) противImmutable
(Неизменяемый)Неизменяемый an object имеет много преимуществ: простота, безопасность и т.д. Но он требует отдельного an object для каждого нового значения, и за слишком большое количество an objectов придется заплатить понижением производительности. Должен быть баланс при выборе между изменяемым и неизменяемым обьектом.
В основном чтобы избежать подготовки промежуточных an objectов используется изменяемый an object. Один из классических примеров это конкатенация большого количества строк. Если вы используете неизменяемый an object типа
String
, то вы создаете много an objectов, которые сразу попадут в сборщик мусора. Это тратит время и энергию процессора, поэтому правильное решение это использование изменяемых обьектов (напримерStringBuilder
).String result=""; for(String s: arr){ result = result + s; }
Еще один пример использования изменяемых an objectов — передача такого an object в метод. Это позволит вернуть результат в нем же, без создания лишних an objectов. При работе с an objectми большого размера, к примеру коллекциями, передача коллекции в метод для сортировки и возвращение результата в другой коллекции приводит к совершенно излишнему расходу ресурсов. (Ответ пользователя dasblinkenlight на Stack Overflow).
-
Конструкторы классов
Super
иSub
Este erro de compilação é causado pelo fato da classe ancestral não possuir um construtor padrão definido. Em Java , a menos que você mesmo especifique um construtor de classe, o compilador criará um construtor padrão que não requer argumentos. Se o construtor for descrito na classe
Super
comoSuper(String s){}
, o próprio compilador não adicionará nada. Isto é o que vemos em nosso exemplo.O construtor da classe
Sub
, não importa qual, chamará o construtor padrão da classeSuper
, já que nada mais é especificado. Como não há construtor padrão na classeSuper
, isso causará um erro de compilação.A primeira solução para este problema é adicionar um construtor padrão à classe
Super
public Super(){ System.out.println("Super"); }
A segunda opção é remover o construtor que descrevemos da classe
Super
para que o compilador crie um construtor padrão.E a última opção é adicionar uma chamada
super(value)
aos construtores de classeSub
para que o construtor de classe existente seja chamado em vez do construtor padrãoSuper
-
" " ou construtor?
Existem duas maneiras de criar uma string:
//1. использовать двойные кавычки String x = "abc";
//2. использовать конструктор String y = new String("abc");
Qual a diferença entre eles?
Você pode entender isso a partir dos seguintes exemplos:
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 saber mais sobre como as strings são armazenadas na memória, leia Criar string Java usando "" ou Construtor? .
GO TO FULL VERSION