Как и большинство программистов, я очень занудный. Одним из самых экстравагантных развлечений на выходных является просмотр технологических сайтов, таких как Programcreek, небольшой сайт с очень интересными темами. Например: эти 10 ошибок являются наиболее распространенными ошибками, которые допускают Java-программисты, и такие темы, как эта, которая вызывает у людей любопытство и желание убить кота, очень достойны того, чтобы их поднять и поделиться с вами.
ПС: не спрашивайя«Почему в заголовке написано «ошарашенный»?» На вопрос есть только один ответ — напугать людей — он должен вызвать у всех интерес к чтению (легко ли это для меня).
01. Преобразование массива в ArrayList
Честно говоря, многим Java-программистам нравится преобразовывать Array в ArrayList:
List<String> list = Arrays.asList(arr);
Но на самом деле,Arrays.asList()
Возвращенный ArrayList неjava.util.ArrayList
, но внутренний закрытый класс массивовjava.util.Arrays.ArrayList
. Хотя имена абсолютно одинаковые, обаArrayList
, но эти два класса очень разные.Arrays.ArrayList
Хотя естьset()
,get()
иcontains()
и т.д., но ни один из методов не используется для добавления элементов, поэтому его размер фиксирован.
Если вы хотите создать настоящуюArrayList
, нужно сделать так:
List<String> list = new ArrayList<String>(Arrays.asList(arr));
ArrayList
Конструктор может принимать параметр типа Collection, аArrays.ArrayList
Это подкласс этого, так что его можно преобразовать так.
02. Проверить наличие в массиве определенного значения через Set
Ранее я писал статью "Как проверить, содержится ли определенное значение в массиве в Java” упомянул метод:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
Этот подход работает, но игнорирует проблемы с производительностью, чтобы иметь возможность завершить проверку как можно быстрее, сделайте так:
Arrays.asList(arr).contains(targetValue);
Или используйте обычный цикл for или for-each.
03. Удалить элементы в списке через цикл for
Новичок Терри любит использовать цикл for для удаления элементов из списка, например:
List<String> list = new ArrayList<String>(Arrays.asList("沉", "默", "王", "二"));
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
System.out.println(list);
Цель приведенного выше кода — удалить все элементы в списке, но результат:
[默, 二]
Есть еще два элемента, которые не были удалены, почему?
Когда элемент списка удаляется, егоsize()
уменьшится, а индекс элемента изменится, поэтому попытка удалить элемент через цикл for не сработает.
А как насчет каждого?
for(String s : list) {
if ("沉".equals(s)) {
list.remove(s);
}
}
System.out.println(list);
Он даже выдает исключение:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at com.cmower.java_demo.programcreek.Top10Mistake.main(Top10Mistake.java:15)
Причину выбрасывания исключения можно найти в статье, которую я написал ранее"Java, подскажите, что за хрень отказоустойчивая?".
Опытные программисты уже должны знать ответ, используйте итератор:
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
String s = iter.next();
if (s.equals("沉")) {
iter.remove();
}
}
System.out.println(list);
Вывод программы следующий:
[默, 王, 二]
04. Используйте Hashtable вместо HashMap
Обычно хэш-таблица должна быть Hashtable, но в Java хеш-таблица обычно относится к HashMap. Одно из различий между ними заключается в том, что Hashtable является потокобезопасным. Если нет особых требований, хэш-таблица должна использовать HashMap вместо Hashtable.
05. Используйте примитивные типы
Новичкам в Java легко спутать разницу между бесконечными подстановочными знаками и примитивными типами. Например,List<?> list
бесконечный подстановочный знак,List 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, 18);
add(list, "沉默王二");
String s = list.get(0);
}
Этот код выдает исключение при запуске:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at com.cmower.java_demo.programcreek.Top10Mistake.main(Top10Mistake.java:38)
Использование необработанных типов очень опасно, потому что общие проверки пропускаются. Что касаетсяList<Object>
иList
Разницу между ними смотрите в другой статье, которую я написал: "Почему вам не следует использовать примитивные типы Java".
06. Используйте public для изменения полей
Некоторым новичкам нравится использовать общедоступные оформленные поля, потому что им не нужноgetter/setter
методы доступа к полям. Но на деле это очень плохой дизайн, опытные программисты больше привыкли предоставлять максимально низкий уровень доступа.
07. Используйте ArrayList вместо LinkedList
Новички часто не понимают разницы между ArrayList и LinkedList, поэтому предпочитают использовать ArrayList, потому что они более привычны. Однако между ними существует огромная разница в производительности. Проще говоря, если операций «добавить/удалить» больше, а операций «получить» меньше, следует предпочесть LinkedList.
08. Используйте слишком много неизменяемых объектов
Неизменяемые объекты имеют много преимуществ, таких как простота и безопасность. Но, как и следовало ожидать, у него также есть некоторые непреодолимые недостатки: для каждого отдельного значения требуется отдельный объект для представления, слишком много таких объектов, вероятно, вызовет много мусора, переработка Стоимость становится чрезвычайно высокой.
Чтобы сохранить баланс между изменяемым и неизменяемым, часто используются изменяемые объекты, чтобы избежать создания слишком большого количества промежуточных объектов. Классический пример — использование StringBuilder (изменяемый объект) для объединения большого количества строк, в противном случае String (неизменяемый объект) будет генерировать много мусора для сбора.
Пример счетчика:
String result="";
for(String s: arr){
result = result + s;
}
Положительный пример:
StringBuilder result = new StringBuilder();
for (String s: strs) {
result.append(s);
}
Справочная статья:Почему строки Java неизменяемы?
09. В родительском классе нет конструктора без параметров по умолчанию
В Java, если родительский класс не определяет конструктор, компилятор по умолчанию вставит конструктор без параметров, но если конструктор определен в родительском классе, компилятор не вставит конструктор без параметров. Так что приведенный ниже код выдаст ошибку при компиляции.
Конструктор без аргументов в подклассе пытается вызвать конструктор без аргументов родительского класса, но он не определен в родительском классе, поэтому возникает ошибка компиляции. Решение состоит в том, чтобы определить конструктор без аргументов в родительском классе.
10. Используйте конструктор для создания строк
Существует два способа создания строк:
1) Используйте двойные кавычки
String er = "沉默王二";
2) Используйте конструктор
String san = new String("沉默王三");
Но между ними есть большая разница (см.Создайте строку Java, используйте "" или конструктор), двойные кавычки называются строковыми константами, что позволяет избежать дублирования содержимого строки, созданной в памяти.
Ну что же, читатели и друзья, вышеизложенное и есть все содержание этой статьи. Можно с уверенностью сказать, что нет объективных данных, доказывающих, что они входят в топ-10, но они определенно очень распространены. Если вы не согласны с содержанием, пожалуйста, плюньте в поле сообщения, хорошие люди будут вознаграждены. Если вы не думаете, что это весело, и хотите увидеть больше, вы можете отметить GitHub второго брата【itwanger.github.io], эта статья была включена.
Оригинальность непроста, если сочтете это полезным, пожалуйста, не скупитесь на право лайка в ваших руках—— Это будет моей самой сильной мотивацией для написания; если вы хотите впервые увидеть обновленные статьи второго брата, отсканируйте QR-код ниже и обратите внимание на публичный аккаунт [Silent King Er]. До встречи в нашей следующей статье!