수색…


소개

java.util 의 콜렉션 프레임 워크는 일반 배열로는 제공 할 수없는 기능을 가진 일련의 데이터 세트에 대한 다수의 일반 클래스를 제공합니다.

컬렉션 프레임 워크는 List<O>Set<O> 주 하위 인터페이스와 Map<K,V> 매핑을 포함하는 Collection<O> 인터페이스를 포함합니다. 컬렉션은 루트 인터페이스이며 다른 많은 컬렉션 프레임 워크에서 구현됩니다.

비고

컬렉션은 그 안에 다른 개체의 컬렉션을 저장할 수있는 개체입니다. Generics를 사용하여 콜렉션에 저장된 데이터 유형을 지정할 수 있습니다.

컬렉션은 일반적으로 java.util 또는 java.util.concurrent 네임 스페이스를 사용합니다.

Java SE 1.4

Java 1.4.2 이하는 제네릭을 지원하지 않습니다. 따라서 컬렉션에 포함 된 유형 매개 변수를 지정할 수 없습니다. 형식 안전성이없는 것 외에도 컬렉션에서 올바른 형식을 다시 가져 오기 위해 캐스트를 사용해야합니다.

Collection<E> 외에도 여러 주요 유형의 컬렉션이 있으며 그 중 일부는 하위 유형이 있습니다.

  • List<E> 는 객체의 정렬 된 컬렉션입니다. 이것은 배열과 유사하지만 크기 제한을 정의하지 않습니다. 구현은 일반적으로 새로운 요소를 수용하기 위해 내부적으로 크기가 커집니다.
  • Set<E> 는 중복을 허용하지 않는 객체의 모음입니다.
    • SortedSet<E> 는 요소 순서를 지정하는 Set<E> 입니다.
  • Map<K,V> 는 키 / 값 쌍의 모음입니다.
    • SortedMap<K,V> 는 요소 순서를 지정하는 Map<K,V> 입니다.
Java SE 5

Java 5는 새로운 콜렉션 유형을 추가합니다.

  • Queue<E> 는 특정 순서로 처리 될 요소의 집합입니다. 구현시 FIFO 또는 LIFO인지 여부를 지정합니다. Stack 클래스를 사용하지 않습니다.
Java SE 6

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 등의 추상 클래스를 상속하는 것이 쉬울 가능성이 있습니다.

Java SE 1.2

1.2 이전에는 대신 다음 클래스 / 인터페이스를 사용해야했습니다.

  • ArrayList 대신 Vector
  • Map 대신 Dictionary . Dictionary는 인터페이스가 아닌 추상 클래스이기도합니다.
  • HashMap 대신 Hashtable

이 클래스는 쓸모가 없으므로 현대 코드에서 사용해서는 안됩니다.

ArrayList 선언 및 객체 추가

List 인터페이스 다음에 ArrayList 를 만들 수 있습니다.

List aListOfFruits = new ArrayList();
Java SE 5
List<String> aListOfFruits = new ArrayList<String>();
Java SE 7
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 입니다. ListsSets :

 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.toMapMapUtils.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
 }
Java SE 8

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);
Java SE 8

스트림을 사용하면

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 문 반복에서 제거 "바나나"건너 뛰기 :

코드 샘플은 AppleStrawberry 만 인쇄합니다. Banana 는 일단 Apple 이 삭제되면 인덱스 0 이동하기 때문에 건너 뛴다. 그러나 동시에 i1 증가한다.

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 작성으로부터 ListmodCount 가 변경되었을 때에, ConcurrentModificationException 가 Throw됩니다. 이것은 동일한 스레드 또는 동일한 목록을 공유하는 다중 스레드 응용 프로그램에서 발생할 수 있습니다.

modCount 는이리스트가 구조적으로 수정 된 횟수를 세는 int 변수입니다. 구조 변경은 기본적으로 Collection 객체에서 호출되는 add() 또는 remove() 작업을 의미합니다 ( Iterator 에 의한 변경은 계산되지 않음). Iterator 가 생성 될 때,이 modCount 저장하고 현재 modCountIterator 가 생성 될 때와 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 SE 8

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"));
Java SE 8
names.forEach(System.out::println);

병렬 처리가 필요한 경우

names.parallelStream().forEach(System.out::println);
Java SE 5
for (String name : names) {
    System.out.println(name);
}
Java SE 5
for (int i = 0; i < names.size(); i++) {
    System.out.println(names.get(i));
}
Java SE 1.2
//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"));
Java SE 8
names.forEach(System.out::println);
Java SE 5
for (Iterator<String> iterator = names.iterator(); iterator.hasNext(); ) {
    System.out.println(iterator.next());
}

for (String name : names) {
    System.out.println(name);
}
Java SE 5
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");
Java SE 8
names.forEach((key, value) -> System.out.println("Key: " + key + " Value: " + value));
Java SE 5
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);
}
Java SE 5
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
    }
}

메소드를 호출하고 nameListremoveNameList 를 다음과 같이 전달하십시오. removeNames(nameList,removeNameList);
다음 출력을 생성합니다.

이름을 제거하기 전에 배열 목록 : James Smith Sonny Huckle Berry 핀 앨런
이름 제거 후 배열 목록 : James Smith Finn Allan

목록 내의 반복되는 요소를 제거하기 위해 편리하게 사용할 수있는 컬렉션에 대한 간단한 사용법.

Iterator 또는 for-each 루프와 함께 사용하기위한 자체 Iterable 구조 만들기.

반복자 또는 for-each 루프를 사용하여 컬렉션을 반복 할 수있게하려면 다음 단계를 수행해야합니다.

  1. 우리가에 반복하려는 물건이어야 Iterable 및 노출 iterator() .
  2. hasNext() , next()remove() 를 오버라이드 hasNext() override hasNext() , 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); 
  1. 지정된 범위에리스트가 존재하지 않는 경우, IndexOutofBoundException를 Throw합니다.
  2. 목록 1에서 이루어진 변경 사항은 목록의 동일한 변경 사항에 영향을 미칩니다. 이는 백업 된 콜렉션이라고합니다.
  3. 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합니다.

모든 콜렉션은 지원 콜렉션을 지원합니다. 서브 콜렉션의 변경 사항은 메인 콜렉션에서 동일한 변경 사항을 갖게됩니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow