쉽지않은 블로그
[JAVA] 컬렉션 이란? 본문
컬렉션
컬렉션이란 순서에 관련이 있거나 집합적인 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 구현해놓은 클래스의 집합이다
자바에서 일반적인 배열의 선언은 길이가 고정되어있기 때문에 크기를 한번 할당을 받을 때 크게 받아놓고 하는 경우가 있다.
이러한 불편함을 덜고자 java.util.* 에서 제공하는 클래스와 인터페이스들을 사용해본적이 있을 것이다 이런 것들을
통틀어서 컬렉션 프레임워크 라고한다.
//일반적인 고정길이 배열선언
int []arr = new int [10000];
//컬렉션을 이용한 가변길이 배열(ArrayList)선언
ArrayList<Integer> arr2 = new ArrayList<Integer>();
종류
컬렉션 프레임워크에서 구현되는 여러 자료구조들은 단독적으로 존재하지 않고
항상 인터페이스라는 규격? 을에 맞춰 정형화시켜 구현을 한다
1.List 인터페이스
(ArrayList , LinkedList , Vector 등 과 같은 것들이 있다)
2.Set 인터페이스
(HashSet , SortedSet 등 과 같은 것들이 있다)
3.Map 인터페이스
(Hashtable , HashMap 등 과 같은 것들이 있다)
컬렉션을 사용할 때 반드시 알아야 할 것
//일반적인 고정길이 배열선언
int []arr = new int [10000];
//컬렉션을 이용한 가변길이 배열(ArrayList)선언
ArrayList<Integer> arr2 = new ArrayList<Integer>();
아까 위에서 예시로 말하기로는 두 가지 배열이라고 얘기했지만
내부적으로 작동하는 방식이 아예 다르다
첫 번째 고정적인 배열을 만들어 줄 때는 선언되는 자료형이 int 형 (primitive : 기본 타입)이고
두 번째 ArrayList에서 사용된 숫자를 담는 자료형은 Integer 형(wrapper class 라 불리는 참조형 타입)이라는 점이다
ArrayList를 예를 들어 자세한 이해를 위해 다음 코드를 보면
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
..
....
transient Object[] elementData;
private int size;
..
..
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
..
..
..
}
위의 코드는 ArrayList의 소스코드이다
(java.base jar의 java.util 패키지를 보면 나와있다.)
여기서 눈여겨봐야 할 점은 데이터를 받는 자료형이 Object로 되어있다
(Object [] elementData라고 나와있는 부분)
ArrayList 자료형의 add메서드로 들어가는 인자가 기본 타입이면 안된다는 뜻으로 해석하면 된다.
즉 Object 클래스를 상속받는 (사용자 정의 class , wrapper class 등 참조형) 객체 여야지 들어갈 수가 있다
모든 클래스들은 가장 상위에 Object class라는 것을 자동으로 상속을 받는다
특정 자료형만을 고려하여 ArrayList라는 것을 만들 수 없기 때문에 Object 클래스를 이용한 것이라 볼 수 있다.
ArrayList arr = new ArrayList();
//new ArrayList<Integer>(); 과는 다르게 참조형타입 모두 담을수 있다
arr.add("hello");
arr.add(2323);
Object a = new String("erer");
System.out.println(arr.get(0));
System.out.println(arr.get(1));
위 코드는 에러가 나지 않고 잘 출력이 된다 (ArrayList를 선언할 때 자료형을 명시해달라는 경고는 뜬다)
이런 것들처럼 실제 메모리에 할당되는 것들과 그것들을 참조하는 객체의 타입이 꼭 같지 않아도 된다.
하지만 그렇다고 이렇게 생각하면 안 된다
"Object 가 만능이네~~ 개꿀 다 저걸로 해야지~~~"
Object a = new String("hello");
System.out.println(a.length()); //에러가 난다
String b = new String("java");
System.out.println(b.length());
String c = (String)a;
System.out.println(c.length());
받는 타입이 Stirng으로 선언된 b 변수는 length()를 호출할 수 있지만
Object로 받은 a는 그럴 수 없기 때문에 에러가 난다
굳이 이런 식으로 사용을 하겠다면 강제로 (Stirng)을 이용하여 형 변환을 한 다음 String 클래스의 메서드를 사용해줄 순 있다.
자 그럼 여기서 아래 코드처럼 모든 데이터 타입을 신경 쓰면서 배열을 이용하고 싶은 사람이 있는가??
여러 참조 자료형 (wrapper class 에만 해당됨) 이든 Object에 담아서 사용할 수 있지만
어떤 형의 자료형인지 알고 사용자가 직접 바꿔주어야 한다는 점이 매우 불편하다.
Object []arr = new Object[100];
arr[0] = new Integer(3);
arr[1] = new String("hello");
..
..
..
arr[99] = new ClassA();
Integer a = (Integer)arr[0];
String b = (String) arr[1];
..
..
이렇게 자료형을 구분하기 위해서
컬렉션을 선언과 동시에 자료형까지 명시해주기 위해 제네릭(generic)이란 게 등장한다
ArrayList nums = new ArrayList<Integer>();
ArrayList names = new ArrayList<String>();
..
..
'프로그래밍언어 > JAVA' 카테고리의 다른 글
[JAVA] Object 클래스 (0) | 2021.04.14 |
---|---|
[JAVA] 자바의 String (0) | 2021.04.13 |
[JAVA] Wrapper class 래퍼클래스란? (2) | 2021.04.13 |
[JAVA] 제네릭 이란? (0) | 2021.03.31 |