Collection, List, Set, Map

인프런 Do it! 자바 프로그래밍 입문 수강 중

컬렉션 프레임워크란?

프로그램 구현에 필요한 자료구조를 구현해 놓은 라이브러리로 java.util 패키지에 구현되어 있다. 개발에 소요된는 시간을 절약하면서 최적화 알고리즘을 사용할 수 있다.

그림1

  • CollectionMapInterface - 구현 코드가 없음
  • Collection 계열은 하나의 데이터만 Handling
  • Map 계열은 쌍으로 된 데이터 Handling
  • List는 선형 자료 구조 - 한 줄로 열거된 순서가 있는 형태
  • set은 중복된 요소가 허용되지 않는 구조 - 순서와 무관하며 ID, 학번 등 관리에 사용
  • TreeSet은 정렬에 주로 사용
  • HashTable은 동기화 지원 HashMap 동기화 지원 X
  • TreeMap 키 값으로 정렬
  • Properties - 파일에서 읽어서 Key-Value 쌍으로 데이터 저장 가능
  • Iterator는 순회한다는 의미

Collection 인터페이스

하나의 객체를 관리하기 위한 메서드가 정의된 인터페이스로 하위에 List, Set 인터페이스가 있다.

Collection 인터페이스 주요 메서드

메서드설명
boolean add( E e )Collection에 객체를 추가
void clear()Collection의 모든 객체 제거
Iterator<E> iteratorCollection을 순환할 반복자(Iterator)를 반환
boolean remove( Objet o )Coolection에 매개변수에 해당하는 인스턴스가 존재하면 제거
int size()Collection에 있는 요소 개수 반환

List 인터페이스

Collection의 하위 인터페이스로 객체를 순서에 따라 저장하고 관리하는데 필요한 메서드가 선언된 인터페이스이다. 배열의 기능을 구현하기 위한 인터페이스라고 할 수 있다.


ArrayList, Vector

객체 배열을 구현한 클래스이다. Vector는 자바2부터 제공된 클래스로 보통 멀티 쓰레드 상태에서 리소스에 대한 동기화가 필요한 경우 사용한다. 하지만 단일 쓰레드에서 동기화를 사용하는 것은 오버헤드이기 때문에 일반적으로는 ArrayList를 사용한다. 그리고 동기화 기능이 추가 되어야 하는 경우에는 아래 synchrodizedList 메서드를 사용된다.

Collections.synchronizedList(new ArrayList<String>());

동기화는 두 개의 쓰레드가 동시에 하나의 리소스에 접근 할 떄 순서를 맞추어서 데이터에 오류가 발생하지 않도록 한다.


LinkedList

논리적으로 순차적인 자료구조가 구현된 클래스로 각 노드가 데이터와 다음 노드의 주소로 구성되어 있다. 데이터 추가/삭제에 드는 배용이 배열보다 적다는 장점이 있다.


Stack, Queue

StackQueue의 기능이 구현된 클래스가 있지만 ArrayListLinkedList를 활용해서 사용할 수도 있다.


Iterator 사용한 순회

  • Collection의 개체를 순회하는 인터페이스
  • iterator() 메서드 호출
    Iterator ir = memberArrayList.iterator( );
    
  • 선언된 메서드
메서드설명
boolean hashNext()이후에 요소가 더 있는지를 체크하는 메서드이며, 요소가 있다면 true 반환
E next()다음에 있는 요소를 반환

예시

Iterator<Member> iterator = arrayList.iterator();
while(iterator.hasNext()) {	//다음 요소가 있나? 없으면 while문 빠져 나옴
  Member member = iterator.next();
  
  int tempId = member.getMemberId();
  if(memberId == tempId) {
    arrayList.remove(member);
    return true;
  }
}

Set 인터페이스

Collection 하위 인터페이스이며 중복을 허용하지 않는다. List는 순서 기반이지만 Set은 순서가 없다는 차이점이 있고 보통 아이디, 주민번호, 사번 등 유일한 값이나 객체 관리에 사용된다. 순서 기반이 아니기 때문에 get(i) 메서드가 제공되지 않는다.

hashCode, equals 재정의

@Override
public int hashCode() {
  return memberId;
}

@Override
public boolean equals(Object obj) {
  if(obj instanceof Member) {
    Member member = (Member) obj;
    
    if(this.memberId == member.memberId) {
      return true;
    }
    else return false;
  }
  return false;
}

main문 예시

MemberHashSet memberHashSet = new MemberHashSet();

		Member memberLee = new Member(101, "이순신");
		Member memberKim = new Member(102, "김유신");
		Member memberShin = new Member(103, "신사임당");

		
		memberHashSet.addMember(memberLee);
		memberHashSet.addMember(memberKim);
		memberHashSet.addMember(memberShin);
		
		memberHashSet.showAll();
		Member memberLee2 = new Member(101, "이몽룡");  //HashSet은 중복을 허용하지 않는다.
		memberHashSet.addMember(memberLee2);
		memberHashSet.showAll();

해시코드는 중복을 허용하지 않기 때문에 위 예시에서는 오버라이딩을 통해 memberIdhashCode로 설정하고 memberId가 동일하면 동일인으로 설정하여 중복을 방지해주었다.


TreeSet 클래스

TreeSet은 중복을 허용하지 않으면서 오름차순이나 내림차순으로 객체를 정렬이 가능하기 때문에 정렬에 사용되는 클래스이다. 내부적으로 이진 검색 트리(binary search tree)로 구현되어 있으며 이진 검색 트리에 자료가 저장 될 때 비교하여 저장될 위치를 정한다. 객체 비교를 위해서는 Comparable이나 Comparator 인터페이스를 구현 해야 한다.

Comparable, Comparator 인터페이스

  • 정렬 대상이 되는 클래스가 구현해야 하는 인터페이스
  • ComparablecompareTo() 메서드를 구현
    • 매개 변수와 객체 자신(this)를 비교
  • Comparatorcompare() 메서드를 구현
    • 두 개의 매개 변수를 비교
  • TreeSet 생성자에 Comparator가 구현된 객체를 매개변수를 전달
    TreeSet<Member> treeSet = new TreeSet<Member>(new Member());
    
  • 일반적으로 Comparable을 더 많이 사용
  • 이미 Comparable이 구현된 경우 Comparator를 이용하여 다른 정렬 방식을 정의할 수 있음

1. Comparable 구현

public class Member implements Comparable<Member>{
  ...
}

Comparable 인터페이스를 구현해주고

@Override
public int compareTo(Member member) {

  return (this.memberId - member.memberId) ;  //양수면 오름차순, 음수면 내림차순
}

compareTo() 메서드를 재정의하여 memberId에 따라 정렬이 된다.

2. Comparator 구현

public class Member implements Comparable<Member>, Comparator<Member>{
  ...
}

Comparator 인터페이스를 구현해주고

@Override
public int compare(Member member1, Member member2) {
  return member1.memberId - member2.memberId;
}

compare() 메서드를 재정의하여 memberId에 따라 정렬이 된다.

예시
TreeSet에서 String은 오름차순으로 정렬 되어 있는데 내림차순으로 정렬하고 싶다!

class MyCompare implements Comparator<String>{

	@Override
	public int compare(String str1, String str2) {
		return str1.compareTo(str2) * -1;
	}
}

Comparator 인터페이스를 구현한 클래스를 하나 생성해서 compare 메서드를 재정의

public class ComparatorTest {
	public static void main(String[] args) {
		TreeSet<String> tree = new TreeSet<String>(new MyCompare());  //비교를 위한 MyCompare 추가
		
		tree.add("aaa");
		tree.add("ccc");
		tree.add("bbb");
		
		System.out.println(tree); //[ccc, bbb, aaa] 출력
	}
}

Map 인터페이스

쌍(pair)로 이루어진 객체를 관리하는 데 사용되며 key-value의 쌍으로 이루어진다. 여기서 key는 중복될 수 없다.

  • key-value pair의 객체를 관리하는데 필요한 메서드가 정의 됨
  • key는 중복될 수 없음
  • 검색을 위한 자료 구조
  • key를 이용하여 값을 저장하거나 검색, 삭제 할 때 사용하면 편리함
  • 내부적으로 hash 방식으로 구현 됨
index = hash(key) //index는 저장 위치
  • key가 되는 객체는 객체의 유일성함의 여부를 알기 위해 equals()hashCode() 메서드를 재정의

TreeMap 클래스

  • Key 객체를 정렬하여 key-value를 pair로 관리하는 클래스
  • key에 사용되는 클래스에 Comparable, Comparator 인터페이스를 구현
  • java에 많은 클래스들은 이미 Comparable이 구현되어 있음
  • 구현 된 클래스를 key로 사용하는 경우는 구현할 필요 없음
public final class Integer extends Number implements Comparable<integer>{
  ...
  public int compareTo(Integer anotherInteger){
    return compare(this.value, anotherInteger.value);
  }
}

끝!