Java의 정석_기초편
ArrayList
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
더보기

list1



Ex11_1
1. ArrayList 생성


// 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에서 삭제
교집합 연산 과정
- get(i)으로 list2에서 하나씩 꺼낸다.
- contains()로 꺼낸 객체가 list1에 있는지 확인
- remove(i)로 해당 객체를 list2에서 삭제
ArrayList에 저장된 객체의 삭제과정 📎
- ArrayList에 저장된 세 번째 데이터(data[2])를 삭제하는 과정. list.remove(2);를 호출
- ① 삭제할 데이터의 아래에 있는 데이터를 한 칸씩 위로 복사해서 삭제할 데이터를 덮어쓴다.
- ② 데이터가 모두 한 칸씩 위로 이동하였으므로 마지막 데이터는 null로 변경해야 한다.
- ③ 데이터가 삭제되어 데이터의 개수(size)가 줄었으므로 size의 값을 1 감소시킨다.
- 마지막 데이터를 삭제하는 경우, ①의 과정(배열의 복사)은 필요없다.
더보기

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

ArrayList에 저장된 세 번째 데이터(data[2])를 삭제하는 과정. list.remove(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
- 탐색기에서 보는 방법
- IDE에서 보는 방법