-
将数组转换为ArrayList。
要将数组转换为ArrayList,开发人员经常使用以下方法:
List<String> list = Arrays.asList(arr);
Arrays.asList()
会返回一个类对象,它是该类的ArrayList
内部私有静态类,并且这不是一个类,该类包含方法,,,但不包含任何添加元素的方法,其大小是固定的。要创建一个真正的,请执行以下操作:(private static class)
Arrays
java.util.ArrayList.
java.util.Arrays.ArrayList
set()
get()
contains()
java.util.ArrayList
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
类构造函数
java.util.ArrayList
可以将所有实现接口的对象作为参数Collection
,该接口的实现由类继承。java.util.Arrays.ArrayList
(私有静态类 ArrayList<E> 扩展 AbstractList<E> 实现 RandomAccess、java.io.Serializable)。
-
检查数组中的特定值。
开发人员经常这样做:
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);
该代码可以工作,但无需将其转换
List
为Set
. 转换为Set
将需要额外的时间。其实一切都很简单:Arrays.asList(arr).contains(targetValue);
或者
for(String s: arr){ if(s.equals(targetValue)) return true; } return false;
第一种方法要短得多。
-
List
从循环中删除元素考虑以下在循环中删除元素的代码:
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);
结论:
[b, d]
事实证明这是一个严重的错误。当删除元素时,大小
List
会减小并且元素索引会发生变化。因此,如果您想使用索引删除循环中的多个元素,请避免使用此方法。
您可能知道使用迭代器是删除循环中元素的正确解决方案,并且您知道样式循环的
for-each
工作方式类似于迭代器,但事实并非如此。考虑以下代码:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) { if (s.equals("a")) list.remove(s); }
我们将收到一个ConcurrentModificationException。
正确的做法是:
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()
必须在 之前调用remove()
。for-each
,编译器将调用该方法remove()
,只有在那时next()
,才会引发错误ConcurrentModificationException
。你可以看一下代码ArrayList.iterator()
。 -
Hashtable
反对HashMap
。由于相应的实现,Hashtable是数据结构的名称。
但在Java中,数据结构的名称是
HashMap
。Hashtable
和之间的主要区别之一HashMap
是它是Hashtable
同步的,因此不应该Hashtable
在 where 中使用HashMap
。 -
使用没有内容限制的集合
В 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
这个编译错误是由于祖先类没有定义默认构造函数导致的。在Java中,除非您自己指定类构造函数,否则编译器将创建一个不需要参数的默认构造函数。如果构造函数在类中描述
Super
为Super(String s){}
,则编译器本身不会添加任何内容。这就是我们在示例中看到的。类的构造函数
Sub
,无论是哪一个,都会调用该类的默认构造函数Super
,因为没有指定其他内容。由于类中没有默认构造函数Super
,这将导致编译错误。解决这个问题的第一个方法是给类添加一个默认构造函数
Super
public Super(){ System.out.println("Super"); }
第二个选项是从类中删除我们描述的构造函数
Super
,以便编译器创建默认构造函数。最后一个选项是添加
super(value)
对类构造函数的调用Sub
,以便调用现有的类构造函数而不是默认构造函数Super
-
“”还是构造函数?
创建字符串有两种方法:
//1. использовать двойные кавычки String x = "abc";
//2. использовать конструктор String y = new String("abc");
它们之间有什么区别?
您可以通过以下示例来理解这一点:
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
要了解有关字符串如何存储在内存中的更多信息,请阅读使用“”或构造函数创建 Java 字符串?。
GO TO FULL VERSION