Java Language
컬렉션
수색…
소개
java.util
의 콜렉션 프레임 워크는 일반 배열로는 제공 할 수없는 기능을 가진 일련의 데이터 세트에 대한 다수의 일반 클래스를 제공합니다.
컬렉션 프레임 워크는 List<O>
및 Set<O>
주 하위 인터페이스와 Map<K,V>
매핑을 포함하는 Collection<O>
인터페이스를 포함합니다. 컬렉션은 루트 인터페이스이며 다른 많은 컬렉션 프레임 워크에서 구현됩니다.
비고
컬렉션은 그 안에 다른 개체의 컬렉션을 저장할 수있는 개체입니다. Generics를 사용하여 콜렉션에 저장된 데이터 유형을 지정할 수 있습니다.
컬렉션은 일반적으로 java.util
또는 java.util.concurrent
네임 스페이스를 사용합니다.
Java 1.4.2 이하는 제네릭을 지원하지 않습니다. 따라서 컬렉션에 포함 된 유형 매개 변수를 지정할 수 없습니다. 형식 안전성이없는 것 외에도 컬렉션에서 올바른 형식을 다시 가져 오기 위해 캐스트를 사용해야합니다.
Collection<E>
외에도 여러 주요 유형의 컬렉션이 있으며 그 중 일부는 하위 유형이 있습니다.
-
List<E>
는 객체의 정렬 된 컬렉션입니다. 이것은 배열과 유사하지만 크기 제한을 정의하지 않습니다. 구현은 일반적으로 새로운 요소를 수용하기 위해 내부적으로 크기가 커집니다. -
Set<E>
는 중복을 허용하지 않는 객체의 모음입니다.-
SortedSet<E>
는 요소 순서를 지정하는Set<E>
입니다.
-
-
Map<K,V>
는 키 / 값 쌍의 모음입니다.-
SortedMap<K,V>
는 요소 순서를 지정하는Map<K,V>
입니다.
-
Java 5는 새로운 콜렉션 유형을 추가합니다.
-
Queue<E>
는 특정 순서로 처리 될 요소의 집합입니다. 구현시 FIFO 또는 LIFO인지 여부를 지정합니다.Stack
클래스를 사용하지 않습니다.
Java 6에서는 일부 새로운 컬렉션 하위 유형을 추가합니다.
-
NavigableSet<E>
는, 특별한 네비게이션 메소드가 짜 넣어지고있는Set<E>
입니다. -
NavigableMap<K,V>
는 특수 네비게이션 메소드가 내장 된Map<K,V>
입니다. -
Deque<E>
는 어느 쪽의 끝에서도 읽을 수있는Queue<E>
입니다.
위의 항목은 모든 인터페이스입니다. 이들을 사용하려면 ArrayList
, HashSet
, HashMap
또는 PriorityQueue
와 같은 적절한 구현 클래스를 찾아야합니다.
컬렉션의 각 유형에는 다양한 성능 메트릭 및 사용 사례가있는 여러 구현이 있습니다.
Liskov Substitution Principle 은 컬렉션 하위 유형에 적용됩니다. 즉, SortedSet<E>
를 Set<E>
를 요구하는 함수에게 건네 줄 수가 있습니다. 또한 클래스 상속과 함께 콜렉션을 사용하는 방법에 대한 자세한 내용은 Generics 섹션의 Bounded Parameters 를 읽는 것이 유용합니다.
독자적인 콜렉션을 작성하고 싶은 경우는, 인터페이스를 구현하는 것이 아니라, AbstractList
등의 추상 클래스를 상속하는 것이 쉬울 가능성이 있습니다.
1.2 이전에는 대신 다음 클래스 / 인터페이스를 사용해야했습니다.
-
ArrayList
대신Vector
-
Map
대신Dictionary
. Dictionary는 인터페이스가 아닌 추상 클래스이기도합니다. -
HashMap
대신Hashtable
이 클래스는 쓸모가 없으므로 현대 코드에서 사용해서는 안됩니다.
ArrayList 선언 및 객체 추가
List
인터페이스 다음에 ArrayList
를 만들 수 있습니다.
List aListOfFruits = new ArrayList();
List<String> aListOfFruits = new ArrayList<String>();
List<String> aListOfFruits = new ArrayList<>();
이제 add
메서드를 사용하여 String
을 추가합니다.
aListOfFruits.add("Melon");
aListOfFruits.add("Strawberry");
위의 예제에서 ArrayList
는 인덱스 0에 String
"Melon"을 포함하고 인덱스 1에 String
"Strawberry"를 포함합니다.
또한 addAll(Collection<? extends E> c)
메소드를 사용하여 여러 요소를 추가 할 수 있습니다.
List<String> aListOfFruitsAndVeggies = new ArrayList<String>();
aListOfFruitsAndVeggies.add("Onion");
aListOfFruitsAndVeggies.addAll(aListOfFruits);
이제 "Onion"은 aListOfFruitsAndVeggies
0 인덱스에 배치되고 "Melon"은 인덱스 1에 있고 "Strawberry"는 인덱스 2에 있습니다.
기존 데이터에서 컬렉션 만들기
표준 컬렉션
자바 컬렉션 프레임 워크
개별 데이터 값으로부터 List
를 생성하는 간단한 방법은 java.utils.Arrays
메소드를 사용하는 것입니다. Arrays.asList
:
List<String> data = Arrays.asList("ab", "bc", "cd", "ab", "bc", "cd");
모든 표준 컬렉션 구현은 생성시에 새로운 컬렉션에 모든 요소를 추가하는 인수로 다른 컬렉션을 사용하는 생성자를 제공합니다.
List<String> list = new ArrayList<>(data); // will add data as is
Set<String> set1 = new HashSet<>(data); // will add data keeping only unique values
SortedSet<String> set2 = new TreeSet<>(data); // will add data keeping unique values and sorting
Set<String> set3 = new LinkedHashSet<>(data); // will add data keeping only unique values and preserving the original order
Google Guava Collections 프레임 워크
또 다른 위대한 프레임 워크는 다양한 유형의 표준 콜렉션을 구축하는 데 유용한 유틸리티 클래스 (편리한 정적 메소드 제공) 인 Google Guava
입니다. Lists
및 Sets
:
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
...
List<String> list1 = Lists.newArrayList("ab", "bc", "cd");
List<String> list2 = Lists.newArrayList(data);
Set<String> set4 = Sets.newHashSet(data);
SortedSet<String> set5 = Sets.newTreeSet("bc", "cd", "ab", "bc", "cd");
컬렉션 매핑
자바 컬렉션 프레임 워크
Map의 경우와 같이, Map<String, Object> map
하면 (자), 다음과 같이 모든 요소를 가지는 새로운 맵을 작성할 수 있습니다.
Map<String, Object> map1 = new HashMap<>(map);
SortedMap<String, Object> map2 = new TreeMap<>(map);
Apache Commons Collections 프레임 워크
Apache Commons
를 사용하면 ArrayUtils.toMap
과 MapUtils.toMap
배열을 사용하여 Map을 만들 수 있습니다.
import org.apache.commons.lang3.ArrayUtils;
...
// Taken from org.apache.commons.lang.ArrayUtils#toMap JavaDoc
// Create a Map mapping colors.
Map colorMap = MapUtils.toMap(new String[][] {{
{"RED", "#FF0000"},
{"GREEN", "#00FF00"},
{"BLUE", "#0000FF"}});
배열의 각 요소는 Map.Entry 또는 Array 여야하며, 두 개 이상의 요소가 포함되어 있습니다. 첫 번째 요소는 키로 사용되고 두 번째 요소는 값으로 사용됩니다.
Google Guava Collections 프레임 워크
Google Guava
프레임 워크의 유틸리티 클래스 이름은 Maps
.
import com.google.common.collect.Maps;
...
void howToCreateMapsMethod(Function<? super K,V> valueFunction,
Iterable<K> keys1,
Set<K> keys2,
SortedSet<K> keys3) {
ImmutableMap<K, V> map1 = toMap(keys1, valueFunction); // Immutable copy
Map<K, V> map2 = asMap(keys2, valueFunction); // Live Map view
SortedMap<K, V> map3 = toMap(keys3, valueFunction); // Live Map view
}
Stream
사용하여,
Stream.of("xyz", "abc").collect(Collectors.toList());
또는
Arrays.stream("xyz", "abc").collect(Collectors.toList());
가입 목록
다음 방법으로 소스 목록을 수정하지 않고 목록에 참여할 수 있습니다.
첫 번째 접근 방식. 줄이 많지만 이해하기 쉽습니다.
List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);
두 번째 접근법. 줄은 하나 적지 만 읽을 수는 적습니다.
List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);
세 번째 접근법. 타사 Apache commons-collections 라이브러리가 필요합니다.
ListUtils.union(listOne,listTwo);
스트림을 사용하면
List<String> newList = Stream.concat(listOne.stream(), listTwo.stream()).collect(Collectors.toList());
참조. 인터페이스 목록
루프 내의 목록에서 항목 제거
루프 내에서 항목을 목록에서 제거하는 것은 까다로운 작업입니다. 이는 목록의 색인과 길이가 변경된다는 사실 때문입니다.
다음 목록에서 예상치 못한 결과를 줄 수있는 몇 가지 예와 올바른 결과를 얻을 수있는 몇 가지 예가 나와 있습니다.
List<String> fruits = new ArrayList<String>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Strawberry");
부정확 한
for
문 반복에서 제거 "바나나"건너 뛰기 :
코드 샘플은 Apple
과 Strawberry
만 인쇄합니다. Banana
는 일단 Apple
이 삭제되면 인덱스 0
이동하기 때문에 건너 뛴다. 그러나 동시에 i
는 1
증가한다.
for (int i = 0; i < fruits.size(); i++) {
System.out.println (fruits.get(i));
if ("Apple".equals(fruits.get(i))) {
fruits.remove(i);
}
}
향상된 for
문에서 제거 예외 예외가 발생했습니다.
컬렉션을 반복하고 동시에 수정하기 때문에.
오류 : java.util.ConcurrentModificationException
for (String fruit : fruits) {
System.out.println(fruit);
if ("Apple".equals(fruit)) {
fruits.remove(fruit);
}
}
옳은
Iterator
사용하여 while 루프에서 제거
Iterator<String> fruitIterator = fruits.iterator();
while(fruitIterator.hasNext()) {
String fruit = fruitIterator.next();
System.out.println(fruit);
if ("Apple".equals(fruit)) {
fruitIterator.remove();
}
}
Iterator
인터페이스에는이 경우에 대해서만 remove()
메소드가 내장되어있다. 다만,이 메소드는 문서에서는 「옵션」으로서 마크되어 UnsupportedOperationException
슬로우 할 가능성이 있습니다.
UnsupportedOperationException -이 반복자가 remove 오퍼레이션을 지원하지 않는 경우
따라서 문서가 실제로이 서포트가 지원되는지 확인하는 것이 좋습니다 (실제적으로, 콜렉션이 제 3 자 라이브러리 또는 Collections.unmodifiable...()
메소드 중 하나를 사용하여 얻은 변경 불가능한 것이 아니면, 작업은 거의 항상 지원됩니다).
Iterator
사용하고있을 때, Iterator
작성으로부터 List
의 modCount
가 변경되었을 때에, ConcurrentModificationException
가 Throw됩니다. 이것은 동일한 스레드 또는 동일한 목록을 공유하는 다중 스레드 응용 프로그램에서 발생할 수 있습니다.
modCount
는이리스트가 구조적으로 수정 된 횟수를 세는 int
변수입니다. 구조 변경은 기본적으로 Collection
객체에서 호출되는 add()
또는 remove()
작업을 의미합니다 ( Iterator
에 의한 변경은 계산되지 않음). Iterator
가 생성 될 때,이 modCount
저장하고 현재 modCount
가 Iterator
가 생성 될 때와 modCount
가 생성 될 때 List
검사의 매 반복마다 검사한다. modCount
값이 변경되면 (자), ConcurrentModificationException
가 Throw됩니다.
따라서 위에 선언 된 목록의 경우 아래와 같은 작업에서 예외가 발생하지 않습니다.
Iterator<String> fruitIterator = fruits.iterator();
fruits.set(0, "Watermelon");
while(fruitIterator.hasNext()){
System.out.println(fruitIterator.next());
}
다만, Iterator
를 초기화 한 후에 List
새로운 요소를 추가하면 (자), ConcurrentModificationException
가 throw됩니다.
Iterator<String> fruitIterator = fruits.iterator();
fruits.add("Watermelon");
while(fruitIterator.hasNext()){
System.out.println(fruitIterator.next()); //ConcurrentModificationException here
}
거꾸로 반복
for (int i = (fruits.size() - 1); i >=0; i--) {
System.out.println (fruits.get(i));
if ("Apple".equals(fruits.get(i))) {
fruits.remove(i);
}
}
이것은 아무것도 건너 뛰지 않습니다. 이 접근법의 단점은 출력이 반대라는 것입니다. 그러나 대부분의 경우 중요하지 않은 항목을 제거합니다. LinkedList
해서는 안됩니다.
순회 반복, 루프 인덱스 조정
for (int i = 0; i < fruits.size(); i++) {
System.out.println (fruits.get(i));
if ("Apple".equals(fruits.get(i))) {
fruits.remove(i);
i--;
}
}
이것은 아무것도 건너 뛰지 않습니다. i
번째 요소가 List
에서 제거되면 원래 인덱스 i+1
있던 요소가 새 i
번째 요소가됩니다. 따라서 루프는 다음 반복이 다음 요소를 건너 뛰지 않고 처리 할 수 있도록 i
를 감소시킬 수 있습니다.
"제거해야 할 목록"사용
ArrayList shouldBeRemoved = new ArrayList();
for (String str : currentArrayList) {
if (condition) {
shouldBeRemoved.add(str);
}
}
currentArrayList.removeAll(shouldBeRemoved);
이 솔루션을 사용하면 개발자는 올바른 요소가 더 깨끗한 방식으로 제거되었는지 확인할 수 있습니다.
Java 8에서는 다음과 같은 대안이 가능합니다. 이러한 제거 작업이 루프에서 발생하지 않아도되는 경우 더욱 깨끗하고 직선적입니다.
스트림 필터링
List
을 스트리밍하고 필터링 할 수 있습니다. 적절한 필터를 사용하여 원하지 않는 요소를 모두 제거 할 수 있습니다.
List<String> filteredList =
fruits.stream().filter(p -> !"Apple".equals(p)).collect(Collectors.toList());
여기의 다른 모든 예제와 달리이 예제는 새 List
인스턴스를 생성하고 원래 List
변경되지 않게 유지합니다.
removeIf
사용 removeIf
스트림을 구성하는 데 필요한 오버 헤드가 있으면 일련의 항목을 제거하는 것입니다.
fruits.removeIf(p -> "Apple".equals(p));
수정 불가능한 컬렉션
변경 될 수있는 특성으로 인해 악성 코드 취약점이 발생할 수 있으므로 내부 컬렉션을 노출하는 것이 좋지 않은 경우가 있습니다. "읽기 전용"컬렉션을 제공하기 위해 Java는 수정 불가능한 버전을 제공합니다.
수정 불가능한 콜렉션은 종종 콜렉션 자체가 변경 될 수 없다는 것을 보장하는 수정 가능한 콜렉션의 사본입니다. 이를 수정하려고하면 UnsupportedOperationException 예외가 발생합니다.
컬렉션 내부에있는 개체는 여전히 변경 될 수 있습니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MyPojoClass {
private List<Integer> intList = new ArrayList<>();
public void addValueToIntList(Integer value){
intList.add(value);
}
public List<Integer> getIntList() {
return Collections.unmodifiableList(intList);
}
}
수정 불가능한 컬렉션을 수정하려고하면 다음과 같은 예외가 throw됩니다.
import java.util.List;
public class App {
public static void main(String[] args) {
MyPojoClass pojo = new MyPojoClass();
pojo.addValueToIntList(42);
List<Integer> list = pojo.getIntList();
list.add(69);
}
}
산출:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Collections.java:1055)
at App.main(App.java:12)
컬렉션 반복하기
리스트 반복하기
List<String> names = new ArrayList<>(Arrays.asList("Clementine", "Duran", "Mike"));
names.forEach(System.out::println);
병렬 처리가 필요한 경우
names.parallelStream().forEach(System.out::println);
for (String name : names) {
System.out.println(name);
}
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));
}
//Creates ListIterator which supports both forward as well as backward traversel
ListIterator<String> listIterator = names.listIterator();
//Iterates list in forward direction
while(listIterator.hasNext()){
System.out.println(listIterator.next());
}
//Iterates list in backward direction once reaches the last element from above iterator in forward direction
while(listIterator.hasPrevious()){
System.out.println(listIterator.previous());
}
세트 반복
Set<String> names = new HashSet<>(Arrays.asList("Clementine", "Duran", "Mike"));
names.forEach(System.out::println);
for (Iterator<String> iterator = names.iterator(); iterator.hasNext(); ) {
System.out.println(iterator.next());
}
for (String name : names) {
System.out.println(name);
}
Iterator iterator = names.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
지도 반복
Map<Integer, String> names = new HashMap<>();
names.put(1, "Clementine");
names.put(2, "Duran");
names.put(3, "Mike");
names.forEach((key, value) -> System.out.println("Key: " + key + " Value: " + value));
for (Map.Entry<Integer, String> entry : names.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
// Iterating over only keys
for (Integer key : names.keySet()) {
System.out.println(key);
}
// Iterating over only values
for (String value : names.values()) {
System.out.println(value);
}
Iterator entries = names.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
변경할 수없는 빈 컬렉션
때로는 변경 불가능한 빈 콜렉션을 사용하는 것이 적절합니다. Collections
클래스는 이러한 컬렉션을 효율적으로 가져 오는 메소드를 제공합니다.
List<String> anEmptyList = Collections.emptyList();
Map<Integer, Date> anEmptyMap = Collections.emptyMap();
Set<Number> anEmptySet = Collections.emptySet();
이러한 메소드는 일반적이며 반환 된 콜렉션을 할당 된 유형으로 자동 변환합니다. 즉, emptyList()
호출은 모든 유형의 List
할당 될 수 있으며 마찬가지로 emptySet()
및 emptyMap()
에도 할당 될 수 있습니다.
이 메소드가 돌려주는 콜렉션 put
, 내용을 변경하는 메소드 ( add
, put
등)를 호출하려고하면 (자), UnsupportedOperationException
를 Throw하는 점에서 불변입니다. 이러한 콜렉션은 기본적으로 null
을 사용하거나 new
를 사용하여 객체를 만드는 대신 빈 메소드 결과 또는 다른 기본값을 대체하는 데 유용합니다.
컬렉션 및 프리미티브 값
Java의 콜렉션은 오브젝트에 대해서만 작동합니다. 즉 Map<int, int>
Java Map<int, int>
가 없습니다. 대신, Map<Integer, Integer>
에서와 같이 기본 값을 객체로 묶어야 합니다. Java auto-boxing을 사용하면 이러한 콜렉션을 투명하게 사용할 수 있습니다.
Map<Integer, Integer> map = new HashMap<>();
map.put(1, 17); // Automatic boxing of int to Integer objects
int a = map.get(1); // Automatic unboxing.
불행히도이 오버 헤드는 상당 합니다. HashMap<Integer, Integer>
는 엔트리 당 약 72 바이트가 필요합니다 (예 : 압축 포인터가있는 64 비트 JVM의 경우, 정수가 256보다 크고 50 %로드가 있다고 가정). 실제 데이터는 8 바이트이기 때문에 엄청난 오버 헤드가 발생합니다. 또한 불필요하게 느린 두 단계의 간접 지정 (Map -> Entry -> Value)이 필요합니다.
기본 데이터 유형 (50 %로드에서 엔트리 당 ~ 16 바이트, 즉 4 배 적은 메모리 및 간접적 인 1 단계 레벨 만 필요로 함)에 대한 최적화 된 콜렉션을 가진 여러 라이브러리가 있으며, 대형 프리미티브 콜렉션을 사용할 때 상당한 성능 이점을 얻을 수 있습니다 Java의 값.
Iterator를 사용하여 목록에서 일치 항목 제거.
위 루프에서 List에서 항목을 제거하는 예제를 발견했으며 이번에는 Iterator
인터페이스를 사용하여 편리하게 사용할 수있는 또 다른 예제를 생각했습니다.
이것은 제거하려는 목록에서 중복 된 항목을 처리 할 때 유용 할 수있는 트릭을 보여주는 데모입니다.
참고 : 이것은 루프 예제 에서 목록의 항목 제거 에만 추가됩니다.
그럼 평소와 같이 목록을 정의합시다.
String[] names = {"James","Smith","Sonny","Huckle","Berry","Finn","Allan"};
List<String> nameList = new ArrayList<>();
//Create a List from an Array
nameList.addAll(Arrays.asList(names));
String[] removeNames = {"Sonny","Huckle","Berry"};
List<String> removeNameList = new ArrayList<>();
//Create a List from an Array
removeNameList.addAll(Arrays.asList(removeNames));
다음 메소드는 두 개의 Collection 객체를 nameList
요소와 일치하는 removeNameList
의 요소를 제거하는 마법을 수행합니다.
private static void removeNames(Collection<String> collection1, Collection<String> collection2) {
//get Iterator.
Iterator<String> iterator = collection1.iterator();
//Loop while collection has items
while(iterator.hasNext()){
if (collection2.contains(iterator.next()))
iterator.remove(); //remove the current Name or Item
}
}
메소드를 호출하고 nameList
와 removeNameList
를 다음과 같이 전달하십시오. removeNames(nameList,removeNameList);
다음 출력을 생성합니다.
이름을 제거하기 전에 배열 목록 : James Smith Sonny Huckle Berry 핀 앨런
이름 제거 후 배열 목록 : James Smith Finn Allan
목록 내의 반복되는 요소를 제거하기 위해 편리하게 사용할 수있는 컬렉션에 대한 간단한 사용법.
Iterator 또는 for-each 루프와 함께 사용하기위한 자체 Iterable 구조 만들기.
반복자 또는 for-each 루프를 사용하여 컬렉션을 반복 할 수있게하려면 다음 단계를 수행해야합니다.
- 우리가에 반복하려는 물건이어야
Iterable
및 노출iterator()
. -
hasNext()
,next()
및remove()
를 오버라이드hasNext()
overridehasNext()
,java.util.Iterator
를 설계합니다.
위의 엔티티를 사용하여 링크 된 목록을 반복 가능하게 만드는 간단한 일반 연결 목록 구현을 추가했습니다.
package org.algorithms.linkedlist;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedList<T> implements Iterable<T> {
Node<T> head, current;
private static class Node<T> {
T data;
Node<T> next;
Node(T data) {
this.data = data;
}
}
public LinkedList(T data) {
head = new Node<>(data);
}
public Iterator<T> iterator() {
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator<T> {
Node<T> node = head;
@Override
public boolean hasNext() {
return node != null;
}
@Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
Node<T> prevNode = node;
node = node.next;
return prevNode.data;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Removal logic not implemented.");
}
}
public void add(T data) {
Node current = head;
while (current.next != null)
current = current.next;
current.next = new Node<>(data);
}
}
class App {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>(1);
list.add(2);
list.add(4);
list.add(3);
//Test #1
System.out.println("using Iterator:");
Iterator<Integer> itr = list.iterator();
while (itr.hasNext()) {
Integer i = itr.next();
System.out.print(i + " ");
}
//Test #2
System.out.println("\n\nusing for-each:");
for (Integer data : list) {
System.out.print(data + " ");
}
}
}
산출
using Iterator:
1 2 4 3
using for-each:
1 2 4 3
이것은 Java 7 이상에서 실행됩니다. Java 5 및 Java 6에서도 다음을 대체하여 실행할 수 있습니다.
LinkedList<Integer> list = new LinkedList<>(1);
와
LinkedList<Integer> list = new LinkedList<Integer>(1);
또는 호환 가능한 변경 사항을 통합하여 다른 버전을 사용할 수 있습니다.
Pitfall : 동시 수정 예외
이 예외는 iterator 객체가 제공하는 메소드가 아닌 다른 메소드를 사용하여 컬렉션을 반복하면서 컬렉션이 수정 될 때 발생합니다. 예를 들어, 모자 목록이 있고 귀 플랩이있는 모든 것을 제거하고 싶습니다.
List<IHat> hats = new ArrayList<>();
hats.add(new Ushanka()); // that one has ear flaps
hats.add(new Fedora());
hats.add(new Sombrero());
for (IHat hat : hats) {
if (hat.hasEarFlaps()) {
hats.remove(hat);
}
}
이 코드를 실행하면 반복되는 동안 코드가 컬렉션을 수정하기 때문에 ConcurrentModificationException 이 발생합니다. 동일한 목록에서 작업하는 여러 스레드 중 하나가 컬렉션을 수정하려고 시도하는 동안 다른 스레드가 반복하는 경우에도 동일한 예외가 발생할 수 있습니다. 여러 스레드에서 콜렉션을 동시에 수정하는 것은 당연한 일이지만 동시 잠금과 같은 동시 프로그래밍 도구 상자의 일반적인 도구로 처리해야합니다. 동시 수정을 위해 채택 된 특수 콜렉션, 초기 복제 된 콜렉션을 수정하는 것 등
하위 모음
리스트 subList (int fromIndex, int toIndex)
여기서 fromIndex는 포괄적이며 toIndex는 독점적입니다.
List list = new ArrayList();
List list1 = list.subList(fromIndex,toIndex);
- 지정된 범위에리스트가 존재하지 않는 경우, IndexOutofBoundException를 Throw합니다.
- 목록 1에서 이루어진 변경 사항은 목록의 동일한 변경 사항에 영향을 미칩니다. 이는 백업 된 콜렉션이라고합니다.
- fromIndex가 toIndex (fromIndex> toIndex)보다 큰 경우, IllegalArgumentException가 Throw됩니다.
예:
List<String> list = new ArrayList<String>();
List<String> list = new ArrayList<String>();
list.add("Hello1");
list.add("Hello2");
System.out.println("Before Sublist "+list);
List<String> list2 = list.subList(0, 1);
list2.add("Hello3");
System.out.println("After sublist changes "+list);
산출:
서브리스트 이전 [Hello1, Hello2]
하위 목록 변경 후 [Hello1, Hello3, Hello2]
subSet (fromIndex, toIndex)을 설정합니다.
여기서 fromIndex는 포괄적이며 toIndex는 독점적입니다.
Set set = new TreeSet();
Set set1 = set.subSet(fromIndex,toIndex);
돌려 주어진 세트는, 그 범위 외의 요소를 삽입하려고하면 (자) IllegalArgumentException를 throw합니다.
지도 서브맵 (fromKey, toKey)
fromKey는 포괄적이며 toKey는 배타적입니다.
Map map = new TreeMap();
Map map1 = map.get(fromKey,toKey);
fromKey가 toKey보다 큰 경우, 또는이 맵 자체가 제한된 범위를 가지고있어 fromKey 또는 toKey가 범위의 경계 외에있는 경우는 IllegalArgumentException를 Throw합니다.
모든 콜렉션은 지원 콜렉션을 지원합니다. 서브 콜렉션의 변경 사항은 메인 콜렉션에서 동일한 변경 사항을 갖게됩니다.