DJDU 2022. 11. 1. 17:37

ArrayList

  • ArrayList는 기존의 Vector를 개선한 것으로 구현원리와 기능적으로 동일
  • ArrayList와 달리 Vector는 자체적으로 동기화처리가 되어 있다.
  • List인터페이스를 구현하므로, 저장순서가 유지되고 중복을 허용한다.
  • 데이터의 저장공간으로 배열을 사용한다.(배열 기반)
더보기

Object[ ] - 객체 배열. 다형성. 모든 종류의 객체 저장 가능

public class ArrayList extends AbstractList
    implemenets List, RandomAccess, Cloneable, java.io.Serializable {
            ...
        transient Object[] elementData; // Object배열
            ...
}

 

ArrayList의 메서드

 

더보기

생성자

추가

삭제

검색

기타

 

예제 11-1

 

더보기

Ex11_1 

1. ArrayList 생성

list1
// ArrayList list2 = new ArrayList(list1.subList(1, 4));
// 풀어쓰면 아래 두 줄과 같다.  
List sub = list1.subList(1, 4);        // sub는 읽기 전용 [4, 2, 0]
ArrayList list2 = new ArrayList(sub);  // sub와 같은 내용의 ArrayList생성

결과

list1:[5, 4, 2, 0, 1, 3]
list2:[4, 2, 0]

 

2. Collection을 정렬할 때는 Collections클래스의 sort메서드를 사용한다.

import java.util.*;

public class Ex11_1 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList(10);
        list1.add(new Integer(5));
        list1.add(new Integer(4));
        list1.add(new Integer(2));
        list1.add(new Integer(0));
        list1.add(new Integer(1));
        list1.add(new Integer(3));
		
        ArrayList list2 = new ArrayList(list1.subList(1, 4));
        print(list1, list2);
		
        Collections.sort(list1);  	// list1과 list2를 정렬한다.
        Collections.sort(list2);  	// Collections.sort(List l)
        print(list1, list2);
    } // main의 끝

    static void print(ArrayList list1, ArrayList list2) {
        System.out.println("list1:" + list1);
        System.out.println("list2:" + list2);
        System.out.println();
    }
} // class

결과

list1:[5, 4, 2, 0, 1, 3]
list2:[4, 2, 0]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4]

 

3. list1.containsAll(list2) - list1이 list2의 모든 요소를 포함하고 있는지 여부(true)

import java.util.*;

public class Ex11_1 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList(10);
        list1.add(new Integer(5));
        list1.add(new Integer(4));
        list1.add(new Integer(2));
        list1.add(new Integer(0));
        list1.add(new Integer(1));
        list1.add(new Integer(3));
		
        ArrayList list2 = new ArrayList(list1.subList(1, 4));
        print(list1, list2);
		
        Collections.sort(list1);  	// list1과 list2를 정렬한다.
        Collections.sort(list2);  	// Collections.sort(List l)
        print(list1, list2);
        
        System.out.println("list1.containsAll(list2):" + list1.containsAll(list2));
    } // main의 끝

    static void print(ArrayList list1, ArrayList list2) {
        System.out.println("list1:" + list1);
        System.out.println("list2:" + list2);
        System.out.println();
    }
} // class

결과

list1:[5, 4, 2, 0, 1, 3]
list2:[4, 2, 0]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4]

list1.containsAll(list2):true

 

4. add메서드 테스트 - 중간에 무언가 끼워넣는 것은 기존 요소를 옮겨야 할 수 있기 때문에 부담이 가는 작업이다.

 

결과

list1:[5, 4, 2, 0, 1, 3]
list2:[4, 2, 0]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4]

list1.containsAll(list2):true
list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, A, B, C]

 

5. set메서드 테스트

import java.util.*;

public class Ex11_1 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList(10);
        list1.add(new Integer(5));
        list1.add(new Integer(4));
        list1.add(new Integer(2));
        list1.add(new Integer(0));
        list1.add(new Integer(1));
        list1.add(new Integer(3));
		
        ArrayList list2 = new ArrayList(list1.subList(1, 4));
        print(list1, list2);
		
        Collections.sort(list1);  	// list1과 list2를 정렬한다.
        Collections.sort(list2);  	// Collections.sort(List l)
        print(list1, list2);
        
        System.out.println("list1.containsAll(list2):" + list1.containsAll(list2));
        
        list2.add("B");
        list2.add("C");
        list2.add(3, "A");
        print(list1, list2);

        list2.set(3,  "AA");
        print(list1, list2);
    } // main의 끝

    static void print(ArrayList list1, ArrayList list2) {
        System.out.println("list1:" + list1);
        System.out.println("list2:" + list2);
        System.out.println();
    }
} // class

결과

list1:[5, 4, 2, 0, 1, 3]
list2:[4, 2, 0]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4]

list1.containsAll(list2):true
list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, A, B, C]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, AA, B, C]

6. indexOf메서드 테스트

import java.util.*;

public class Ex11_1 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList(10);
        list1.add(new Integer(5));
        list1.add(new Integer(4));
        list1.add(new Integer(2));
        list1.add(new Integer(0));
        list1.add(new Integer(1));
        list1.add(new Integer(3));
		
        ArrayList list2 = new ArrayList(list1.subList(1, 4));
        print(list1, list2);
		
        Collections.sort(list1);  	// list1과 list2를 정렬한다.
        Collections.sort(list2);  	// Collections.sort(List l)
        print(list1, list2);
        
        System.out.println("list1.containsAll(list2):" + list1.containsAll(list2));
        
        list2.add("B");
        list2.add("C");
        list2.add(3, "A");
        print(list1, list2);

        list2.set(3,  "AA");
        print(list1, list2);
        
        list1.add(0, "1");
        // indexOf()는 지정된 객체의 위치(인덱스)를 알려준다.
        System.out.println("index=" + list1.indexOf("1"));
        System.out.println("index=" + list1.indexOf(1));
        // System.out.println("index=" + list1.indexOf(new Integer(1)));

        print(list1, list2);
    } // main의 끝

    static void print(ArrayList list1, ArrayList list2) {
        System.out.println("list1:" + list1);
        System.out.println("list2:" + list2);
        System.out.println();
    }
} // class

결과

7. remove메서드 테스트 📎

index 5에 있는 객체를 삭제

import java.util.*;

public class Ex11_1 {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList(10);
        list1.add(new Integer(5));
        list1.add(new Integer(4));
        list1.add(new Integer(2));
        list1.add(new Integer(0));
        list1.add(new Integer(1));
        list1.add(new Integer(3));
		
        ArrayList list2 = new ArrayList(list1.subList(1, 4));
        print(list1, list2);
		
        Collections.sort(list1);  	// list1과 list2를 정렬한다.
        Collections.sort(list2);  	// Collections.sort(List l)
        print(list1, list2);
        
        System.out.println("list1.containsAll(list2):" + list1.containsAll(list2));
        
        list2.add("B");
        list2.add("C");
        list2.add(3, "A");
        print(list1, list2);

        list2.set(3,  "AA");
        print(list1, list2);
        
        list1.add(0, "1");
        // indexOf()는 지정된 객체의 위치(인덱스)를 알려준다.
        System.out.println("index=" + list1.indexOf("1"));
        System.out.println("index=" + list1.indexOf(1));
        // System.out.println("index=" + list1.indexOf(new Integer(1)));
        
        list1.remove(1);              // 인덱스가 1인 객체를 삭제
        list1.remove(new Integer(1)); // 1을 삭제
        
        print(list1, list2);
    } // main의 끝

    static void print(ArrayList list1, ArrayList list2) {
        System.out.println("list1:" + list1);
        System.out.println("list2:" + list2);
        System.out.println();
    }
} // class

결과

boolean remove(Object obj)를 호출하려 했는데 Object remove(int index)를 호출해버렸다.

        list1.remove(1);              // 인덱스가 1인 객체를 삭제 
        list1.remove(new Integer(1)); // 1을 삭제

기본기 | 매개변수 자리에 1을 작성하면 Object remove(int index)가 호출되고, new Integer(1)을 작성하면 boolean remove(Object obj)가 호출된다는 것을 반드시 알아야 한다. ⭐️

list1.add(1);                  // 1을 추가
// ...
list1.remove(new Integer(1));  // 1을 삭제

add할 때는 1만 써줘도 되지만, 삭제할 땐 반드시 new Integer(1)로 작성해야 한다.

8. retainAll메서드 &  contains메서드 테스트 

package ch11;

import java.util.*;

public class Ex11_1 {
    public static void main(String[] args) {
        // 기본 길이(용량, capacity)가 10인 ArrayList를 생성
        ArrayList list1 = new ArrayList(10);
        // ArrayList에는 객체만 저장 가능
        // autoboxing에 의해 기본형이 참조형으로 자동 변환
        // list1.add(new Integer(5));
        list1.add(5);
        list1.add(new Integer(4));
        list1.add(new Integer(2));
        list1.add(new Integer(0));
        list1.add(new Integer(1));
        list1.add(new Integer(3));

        ArrayList list2 = new ArrayList(list1.subList(1, 4));
        print(list1, list2);

        // Collection은 인터페이스, Collections는 유틸 클래스
        Collections.sort(list1);  	// list1과 list2를 정렬한다.(기본 : 오름차순 정렬)
        Collections.sort(list2);  	// Collections.sort(List l)
        print(list1, list2);

        System.out.println("list1.containsAll(list2):" + list1.containsAll(list2));

        list2.add("B");
        list2.add("C");
        list2.add(3, "A");
        print(list1, list2);

        list2.set(3,  "AA");
        print(list1, list2);

        list1.add(0, "1");
        print(list1, list2);
        // indexOf()는 지정된 객체의 위치(인덱스)를 알려준다.
        System.out.println("index=" + list1.indexOf("1"));
        // System.out.println("index=" + list1.indexOf(1));
        System.out.println("index=" + list1.indexOf(new Integer(1)));
        list1.remove(1);              // 인덱스가 1인 객체를 삭제
        list1.remove(new Integer(1)); // 1을 삭제

        print(list1, list2);

        // list1에서 list2와 겹치는 부분만 남기고 나머지는 삭제한다.
        System.out.println("list1.retainAll(list2):" + list1.retainAll(list2));

        print(list1, list2);

        // list2에서 list1에 포함된 객체들을 삭제한다.
        for(int i = list2.size() - 1; i >= 0; i--) {
            if(list1.contains(list2.get(i)))
                list2.remove(i);
        }
        print(list1, list2);
    } // main의 끝

    static void print(ArrayList list1, ArrayList list2) {
        System.out.println("list1:" + list1);
        System.out.println("list2:" + list2);
        System.out.println();
    }
} // class

결과

list1:[5, 4, 2, 0, 1, 3]
list2:[4, 2, 0]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4]

list1.containsAll(list2):true
list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, A, B, C]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, AA, B, C]

list1:[1, 0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, AA, B, C]

index=0
index=2
list1:[1, 2, 3, 4, 5]
list2:[0, 2, 4, AA, B, C]

list1.retainAll(list2):true
list1:[2, 4]
list2:[0, 2, 4, AA, B, C]

list1:[2, 4]
list2:[0, AA, B, C]
// list2에서 list1에 포함된 객체를 삭제한다.
for (int i = list2.size() - 1; i >= 0 ; i--) {
    if(list1.contains(list2.get(i)))  // 1. get(i)로 list2에서 하나씩 꺼낸다.
        list2.remove(i);              // 2. contains()로 꺼낸 객체가 list1에 있는지 확인
}                                     // 3. remove(i)로 해당 객체를 list2에서 삭제

교집합 연산 과정

  1. get(i)으로 list2에서 하나씩 꺼낸다.
  2. contains()로 꺼낸 객체가 list1에 있는지 확인
  3. remove(i)로 해당 객체를 list2에서 삭제

 

ArrayList에 저장된 객체의 삭제과정 📎

  • ArrayList에 저장된 세 번째 데이터(data[2])를 삭제하는 과정. list.remove(2);를 호출
  • ① 삭제할 데이터의 아래에 있는 데이터를 한 칸씩 위로 복사해서 삭제할 데이터를 덮어쓴다.
  • ② 데이터가 모두 한 칸씩 위로 이동하였으므로 마지막 데이터는 null로 변경해야 한다.
  • ③ 데이터가 삭제되어 데이터의 개수(size)가 줄었으므로 size의 값을 1 감소시킨다.
  • 마지막 데이터를 삭제하는 경우, ①의 과정(배열의 복사)은 필요없다.

 

더보기

ArrayList에 저장된 세 번째 데이터(data[2])를 삭제하는 과정. list.remove(2);를 호출

list.remove(2); - index가 2인 객체 삭제

① 삭제할 데이터의 아래에 있는 데이터를 한 칸씩 위로 복사해서 삭제할 데이터를 덮어쓴다.

② 데이터가 모두 한 칸씩 위로 이동하였으므로 마지막 데이터는 null로 변경해야 한다.

data[size-1] = null;

③ 데이터가 삭제되어 데이터의 개수(size)가 줄었으므로 size의 값을 1 감소시킨다.

size--;

마지막 데이터를 삭제하는 경우, ①의 과정(배열의 복사)은 필요없다.

 

ArrayList에 저장된 객체의 삭제과정 2

  • ① ArrayList에 저장된 첫 번째 객체부터 삭제하는 경우(배열 복사 발생)
  • ② ArrayList에 저장된 마지막 객체부터 삭제하는 경우 ⭐️

 

더보기

① ArrayList에 저장된 첫 번째 객체부터 삭제하는 경우(배열 복사 발생) - 전체 삭제 실패

for(int i = 0; i < list.size(); i++) {
    list.remove(i);
}

이렇게 위에서 부터 지우면 성능상도 안 좋고, 다 지워지지도 않는다.

ArrayList에 저장된 마지막 객체부터 삭제하는 경우 - 빠름, 전체 삭제 성공

끝에서부터 지워야 성능도 빠르고, 전체 삭제도 할 수 있다.

 

Java API 소스 보기 - /jdk설치경로/src.zip

  1. 탐색기에서 보는 방법
  2. IDE에서 보는 방법