모든지 기록하자!

[Java] 컬렉션 프레임워크 (collection framework) 본문

Java

[Java] 컬렉션 프레임워크 (collection framework)

홍크 2021. 5. 21. 00:53
728x90

컬렉션 프레임워크란?

프로그램을 개발할 때 사용하는 자료를 어떤 구조로 관리할 것인지가 중요하다. 이때 사용하는 것이 자료구조(data structure)다. 자료 구조는 프로그램 실행 중 메모리에 자료를 유지, 관리하기 위해 사용한다. 자바에서는 필요한 자료 구조를 미리 구현하여 java.util 패키지에서 제공하고 있는데 이를 컬렉션 프레임워크(collection framework)라고 한다. 자료 구조는 개발자가 직접 만들어 사용할 수도 있지만 자바 컬랙션 프레임워크를 사용하면 직접 개발하는 수고를 덜 수 있고 잘 만들어진 자료 구조 클래스를 활용할 수 있다.

Collection 인터페이스

컬렉션 프레임워크의 전체 구조는 Collection 인터페이스와 Map 인터페이스 기반으로 이루어져 있다.

Collection 인터페이스는 하나의 자료를 모아서 관리하는 데 필요한 기능을 제공하고, Map 인터페이스는 쌍으로 된 자료들을 관리하는 데 유용한 기능을 제공한다. 

분류 설명
List 인터페이스 순서가 있는 자료 관리, 중복 허용, 해당 인터페이스를 구현한 클래스는 ArrayList, Vector,
LinkedList, Stack, Queue 등이 있다.
Set 인터페이스 순서가 정해져 있지 않다. 중복을 허용하지 않는다. 해당 인터페이스를 구현한 클래스는 
HashSet, TreeSet 등이 있다.

 

Collection 인터페이스에 선언된 메서드 중에 자주 사용하는 메서드

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

Map 인터페이스

Map 인터페이스는 하나가 아닌 쌍(Pair)으로 되어 있는 자료를 관리하는 메서드들이 선언되어 있다.

key-value 쌍이라고 표현하는데 키 값은 중복될 수 없다. 학번과 학생 이름처럼 쌍으로 되어 있는 자료를 관리할 때 사용하면 편하다. 

Key Value
이름 홍길동
나이 30세
직업 회사원
취미 농구,서핑
특기 서핑

어떤 사람의 정보가 있을 때 그냥 나열할수도 있지만 위쪽처럼 쓸 수 있다. 이때 이름, 나이 등의 값을 key라고 하고, 홍길동, 30세 등의 값을 value라고 한다. key 값은 중복될 수 없고 value 값은 여러 개일 수도 있고 중복될 수도 있다.

 

Map은 기본적으로 검색용 자료 구조다. 어떤 key 값을 알고 있을 때 value를 찾기 위한 자료구조다. 

Map 인터페이스에 선언된 메서드 중 주요 메서드를 보자

메서드 설명
V put(K ket, V value)  key에 해당하는 value 값을 map에 넣는다.
V get(K key)  key에 해당하는 value 값을 반환한다.
boolean isEmpty( )  Map이 비었는지 여부를 반환한다.
boolean containsKey(Object key)  Map에 해당 key가 있는지 여부를 반환한다.
boolean containsValue(Object value)  Map에 해당 Value가 있는지 여부를 반환한다.
Set keyset( )  key 집합을 Set로 반환한다.
Collection values( )  value를 Collection으로 반환한다.(중복무관)
V remove(key) key가 있는 경우 삭제한다.
boolean remove(Object key, Object value) key가 있는 경우 key에 해당하는 value가 매개변수와 일치할 때 삭제한다.

 

 

collection 패키지 하위 프로그램에서 공통으로 사용할 '회원'을 나타내는 Member 클래스를 만들어 보자

public class Member {
 
	private int memberId; // 회원 아이디
	private String memberName; // 회원 이름
	
	public Member(int memberId, String memberName) {
		this.memberId = memberId;
		this.memberName = memberName;
	}
	
	public int getMemberId() {
		return memberId;
	}
	public void setMemberId(int memberId) {
		this.memberId = memberId;
	}
	public String getMemberName() {
		return memberName;
	}
	public void setMemberName(String memberName) {
		this.memberName = memberName;
	}
	
	public String toString() { // toString() 메서드 재정의
		return memberName + " 회원님의 아이디는 "+ memberId + "입니다."; 
	}

List 인터페이스

List 인터페이스에는 객체를 순서에 따라 저장하고 유지하는 데 필요한 메서드가 선언되어 있다.

순차 자료 구조의 대표적인 예는 배열이다. 자에서 배열을 구현한 대표 클래스로는 ArrayList, Vector가 있고 구현 방식은 다르지만 순차 자료 구조를 구현한 LinkedList가 있다.

 

ArrayList를 활용해 회원 관리 프로그램 구현

ArrayList를 활용한 MemberArrayList 클래스에서는 메서드 3개를 제공한다. 회원을 추가하는 addMember(), 회원을 삭제하는 removeMember(), 전체 회원을 출력하는 showAllMember()이다. 

import java.util.ArrayList;
import collection.Member;

public class MemberArrayList {

	private ArrayList<Member> arrayList; // ArrayList 선언
	
	public MemberArrayList() { // Member형으로 ArrayList 생성
		arrayList = new ArrayList<Member>();
	}
	
	public void addMember(Member member) {
		arrayList.add(member); //맴버를 추가해주는 메서드
	}
	
	public boolean removeMember(int memberId) {
		
		for(int i = 0; i < arrayList.size(); i++) {
			Member member = arrayList.get(i); // get()으로 회원을 순차적으로 가져온다.
			int tempId = member.getMemberId();
			if(memberId == tempId) { // 회원 아이디가 매개변수와 일치하면
				arrayList.remove(i);      // arrayList에 i번째를 삭제
				return true;
			}
		}
		
		
		System.out.println(memberId + "가 존재하지 않습니다.");
		return false; // 반복문돌아서 찾지못하면 출력
	}
	
	public void showAll() {
		for(Member member : arrayList) {
			System.out.println(member); //toString이 호출됨(미리만듦)
		}
		System.out.println();
	}
}

 

MemberArrayList 테스트 클래스 구현

import collection.Member;

public class MemberArrayListTest {

	public static void main(String[] args) {

		MemberArrayList memberArrayList = new MemberArrayList();
		
		Member memberLee = new Member(101, "이병헌"); // 회원 인스턴스 생성
		Member memberChoi = new Member(102, "최민식");
		Member memberHa = new Member(103, "하정우");
		
		memberArrayList.addMember(memberLee);
		memberArrayList.addMember(memberChoi); // ArrayList에 회원 추가
		memberArrayList.addMember(memberHa);
		
		memberArrayList.showAll(); // 전체 회원 출력
		System.out.println("======================");
		
		memberArrayList.removeMember(memberChoi.getMemberId()); // 최민식 회원 삭제
		//removeMember 메서드 호출할때 매개변수로 memberId넣어야함
		memberArrayList.showAll(); // 최민식 회원 삭제 후 다시 전체 출력
	}
}

결과 출력

ArrayList와 Vector 클래스

Vector는 자바 2 이전부터 제공했고 ArrayList처럼 배열을 구현한 클래스이다. 

ArrayList와 Vector의 가장 큰 차이는 동기화 지원 여부이다. 동기화(synchronization)란 두 개 이상의 스레드가 동시에 Vector를 사용할 때 오류가 나지 않도록 실행 순서를 보장하는 것이다.

스레드를 간단히 말하면 작업 단위다. 하나의 스레드만 수행되면 단일 스레드(single thread)라고 하고 두 개 이상의 스레드가 동시에 실행되는 경우를 멀티스레드(multi-thread)라고 한다. 두 개 이상의 스레드가 동시에 실행되면 같은 메모리 공간에 접근하기 때문에 변수 값이나 메모리 상태에 오류가 생길 수 있다. 이때 메모리에 동시에 접근하지 못하도록 순서를 맞추는 것이 동기화다.

 

두 작업이 동시에 실행되는 멀티스레드 환경이 아닌 경우에는 ArrayList를 권장한다. 이유는 동기화를 구현하기 위해서는 동시에 작업이 이루어지는 자원에 대해 잠금(lock)을 수행하기 때문이다. 메서드를 호출할 때

배열 객체에 잠금을 하고, 메서드 수행이 끝나면 잠금을 헤제한다. Vector의 모든 메서드는 호출될 때마다 잠금과 해체가 반복되므로 ArrayList보다 수행 속도가 느리다. ArrayList를 사용해서 구현했다가 프로그램에서 동기화가 필요하다면 다음과 같이 사용하면 된다.

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

 

 

 

 

728x90
Comments