dev_dbdb1114

자바 Collection 본문

카테고리 없음

자바 Collection

dbdb1114 2023. 9. 7. 23:38

관계도

관계도를 그려보면 아래와 같다. List와 Set은 Collection을 상속하고있고, 그 아래에 있는 ArrayList, Vector, LinkedList, HashSet, TreeSet 은 모두 각각 List와 Set을 구현하는 구현체이다. 특성에 맞게 각자 여러가지 다른점을 가지고 있다.

List 컬렉션

List 컬렉션은 객체를 일렬로 늘어놓은 구조를 가지고 있다. 인덱스로 관리하기 때문에 객체 저장시 자동 인덱스가 부여되고, 인덱스를 통해서 검색 및 삭제가 가능하다.

List 구현체의 공통 메소드

메소드 기능 설명

boolean add(E e) 주어진 객체를 맨 끝에 추가
void add(int index, E element) 주어진 인덱스에 객체를 추가
E set(int index, E element) 주어진 인덱스에 저장된 객체를 주어진 객체로 바꾼후 이전 객체 반환
boolean contains(Object O) 주어진 객체가 저장되어있는지 확인
E get(int index) 주어진 인덱스에 저장된 객체를 반환
boolean isEmpty() 컬렉션이 비었는지 확인
int size() 저장되어 있는 전체 객체 수를 리턴
void clear() 저장된 모든 객체를 삭제
E remove(int index) 해당 인덱스 객체를 삭제후 삭제된 객체를 반환한다
boolean remove(Object o ) 주어진 객체가 있다면 삭제후 true/false로 결과를 알려준다.

ArrayList

List<String> sample = new ArrayList<String>();

ArrayList는 일반적인 배열의 업그레이드 버전이라고 보면 조금 편할 수 있다. 크기를 처음에 정해주지 않아도 되며, 요소를 추가시키는 만큼 계속해서 늘어난다. 크기를 지정하고싶다면, 생성자 괄호 안에 숫자를 넣어주면 된다. 더하여 위 표에 있는 모든 메소드를 사용할 수 있다.

다만, ArrayList는 생성시 메모리 구조가 아래 사진과 같다. 그렇기 때문에 삽입 혹은 삭제가 일어날 때 굉장히 불리하다. 인덱스에 값을 삭제 했을 때는 뒤의 인덱스를 한칸씩 앞당겨야하고, 값을 중간에 삽입하고자 한다면 해당 인덱스 뒤의 인덱스들을 모두 한칸씩 뒤로 밀어야한다.

 

그렇기 때문에 삽입과 삭제가 많이 일어날 수 있는 자료에 대해서는 LinkedList를 보통 권장한다.

LinkedList

LinkedList도 ArrayList와 사용법은 거의 유사하다. 하지만 내부적인 구조는 매우 다르다. ArrayList의 경우 특정 크기의 연결된 셀을 확보하여 인덱스를 할당하는 반면 LinkedList는 연결된 셀을 사용하는 것이 아니라 떨어져 있는 셀들을 연결하는 것이다.

연결하는 방식은 특정셀마다 자신의 주소, 바로 다음 연결된 셀의 주소를 가지고 있다. 즉 셀의 주소를 공유하여 List형태를 갖추는 것이다.

위 사진과 같은 방식으로 구현되어 있기 때문에 중간에 삽입을 하거나 삭제를 했을때 간단하게 참조하는 주소만 다르게 설정해줌으로써 변경이 가능하다. 아래 사진이 삭제가 일어났을 때의 LinkedList 형태이다. (참고로 여기 나오는 숫자들은 인덱스가 아닌 값이다.)

Set 컬렉션

Set컬렉션은 저장 순서가 유지되지 않는다. 또한 객체를 중복해서 저장할 수 없다. 수학의 집합과 비슷한 느낌이라고 생각할 수 있다. 또한 인덱스가 없기 때문에 인덱스를 이용하는 메소드는 없다.

메소드 설명

boolean add(E e) 주어진 객체를 저장하고 성공시 true, 실패시 false를 반환한다.
boolean containse(Object o) 주어진 객체가 있는지 확인
boolean isEmpty 컬렉션이 비어있는지 확인
Iterator<E> Iterator 저장된 객체를 한 번씩 가져오는 반복자를 리턴
int size() 저장되어 있는 전체 객체 수 리턴
void clear() 저장된 모든 객체를 삭제
boolean remove(Object O ) 주어진 객체를 삭제

Iterator

iterator는 요소를 하나씩 반환하는 객체이다. Set은 자체적으로 인덱스를 사용하지도 않고 주소를 가진 특정한 요소가 없기 때문에 set이나 map 같은 경우는 iterator를 사용해야 요소들에 접근할 수 있다. 보통 자주 쓰는 메서드는 아래와 같다. 보통 iterator에서 빈 값에 다음 요소를 불렀을 때는 nullPointException이 발생할 수 있기 때문에 hasNext() 메소드로 다음 요소가 존재하는지 확인한 이후에 요소에 접근해야한다.

Iterator<String> setIter = set.iterator();

setIter.hasNext() => 다음 요소가 있는지 확인한다.
setIter.next() => 다음 요소를 가져온다. 

while(setIter.hasNext()){
	String str = setIter.next();
	System.out.print(setIter.next);
	if( str.equals("할라") ){
		strIter.remove(); => set의 객체를 삭제한다.
	}
}

HashSet

HashSet은 위에서 이미 언급했듯 객체들을 순서 없이 저장하고 동일한 객체는 중복 저장하지 않는다. 또한 이름에서 알 수 있듯이 저장하기 전에 hashCode 메소드를 통해 해시코드를 얻고, 다른 객체를 저장할 때마다 해시코드를 비교하여 동일 객체는 저장하지 않는다. 일반적으로 hashCode메소드는 같은 객체여도 다른 값을 만들지만, 이를 HashSet에서 재정의 해서 사용하기 때문에 가능한 것이다. HashSet의 경우 삽입, 검색 모두 빠르다. 또한 재밌는 사실인데 내부적으로 보면 HashMap을 사용하여 정의하는 것을 알 수 있다.

 

Comments