자바/Java 컬렉션 강의 정리(1)
이 글은 뉴렉쳐님의 강의를 듣고 정리하는 글입니다. youtube.com/playlist?list=PLq8wAnVUcTFWKOIbvo18pJZ9zsxtXz_-k
컬렉션이란 데이터를 (배열형태로?) 수집하고 관리해주는 객체이다. 간단히 말해서 가변 길이를 가진 배열이다.
대표적인 기능들은 다음과 같은 것이 있다.
- .add(value) 요소 추가
- .remove(index) 요소 제거
- .clear() 전체 삭제
- .size() 전체 길이 반환
- .get(index) index에 있는 값 반환
그럼 컬렉션은 왜 사용할까?
- 데이터 관리를 직접할 필요 없다. 제공하는 메소드를 통해 쉽게 값을 추가하고 뺄 수 있다.
- 배열의 크기를 알아서 늘려준다.
직접 만들어본 컬렉션. 정수형을 담는 컬렉션이다.
package app.util;
public class IntList {
private int[] numbers;
private int current;
public IntList() {
numbers = new int[3]; //크기는 3으로 한다.
current = 0;
}
public void add(int num) {
numbers[current] = num; //값을 추가하면 현재 위치를 가리키는 변수를 +1 한다.
current += 1;
}
public void clear() {
// for (int i=0; i<current; i++)
// numbers[i] = 0;
// 이렇게 for문으로 지워도 되지만 어차피 current로 접근하는 거라서
// current값만 0으로 초기화해도 된다.
//
// numbers = new int[3]; 또는 새롭게 배열을 생성해줘도 된다.
current = 0;
}
public int size() {
return current;
}
public int get(int index) {
if(current <= index)
throw new IndexOutOfBoundsException();
//리스트의 크기보다 더 큰 값을 요청하면 예외처리를 한다.
return numbers[index];
}
}
다음은 실행 코드와 결과이다.
public static void main(String[] args) {
IntList list = new IntList();
list.add(3);
list.add(5);
int size = list.size();
System.out.println(size); // 2
list.clear();
size = list.size();
System.out.println(size); //0
list.add(7);
int num = list.get(0);
System.out.println("num: "+ num); // num: 7
list.get(1); // 예외 발생. IndexOutOfBoundsException
}
그러나 위에서 만든 배열은 정수형 밖에 담지 못한다. 여러 타입의, 서로 다른 타입의 데이터를 담을 수 있는 방법이 있다.
모든 클래스는 Object 클래스의 하위 클래스이다. 따라서 Object 타입의 배열을 만든다면 모든 객체를 Object 클래스로 업캐스팅하여 참조하게 할 수 있다.
하지만 여기서 또 한가지 문제가 생긴다. Object 클래스에는 객체를 담을 수는 있어도 기본값을 넣을 수는 없다. 10이라는 숫자를 Object 객체로 업캐스팅할 수는 없다. 그래서 Wrapper 클래스를 사용한다.(Wrapper 클래스에 대한 기본 설명: jang-sn.tistory.com/21)
Wrapper클래스를 기본값들을 래핑하여 Object 클래스로 업캐스팅이 가능해져 배열에서 참조할 수 있게 된다. 기본형 데이터에는 각각 Wrapper 클래스가 있다. 그 Wrapper 클래스는 Number 추상 클래스의 하위 클래스이고, Number 클래스는 Object의 하위 클래스가 된다.
Object obj = new Integer(3); // 3을 박싱한 후 Object 클래스에 담았다.
//현재는 Auto Boxing 기능이 제공되 다음과 같이 바로 사용할 수 있다.
Object obj = 3; // -> Object obj = new Integer(3);와 동일.
int x = obj.intValue(); // 언박싱
int x = 3; // 변수에 직접 값을 담았다.
Integer x = 3; // 3이라는 값을 박싱했다. -> Integer x = new Integer(3);
이렇게 하면 Object 배열의 모든 타입의 값을 넣을 수 있다. 이런 컬렉션을 범용 컬렉션이라고 한다.
그러면 간단하게 위에 코드를 수정해보자
package app.util;
public class ObjectList {
private Object[] numbers;
private int current;
public ObjectList() {
numbers = new Object[3];
current = 0;
}
public void add(Object num) {
numbers[current] = num; //값을 추가하면 현재 위치를 가리키는 변수를 +1 한다.
current += 1;
}
public void clear() {
current = 0;
}
public int size() {
return current;
}
public Object get(int index) {
if(current <= index)
throw new IndexOutOfBoundsException();
return numbers[index];
}
}
이렇게 수정하면 모든 타입의 데이터를 담을 수 있는 배열이 완성된다. 그러나 이 배열의 문제점은 데이터를 배열로부터 꺼낼 때 어떤 타입으로 받아야 할 지 모른다는 것다. 배열의 3번 인덱스가 정수인지, 문자열인지 모른다면 값을 받을 수가 없다. 그래서 등장한 것이 제네릭이다.