-
배열을 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.Serialized를 구현합니다).
-
배열에서 특정 값을 확인합니다.
개발자는 종종 다음과 같은 작업을 수행합니다.
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
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