본문 바로가기

BackEnd/Java

[java] 이것이 자바다 ch15 컬렉션 1

728x90
반응형

1. 컬렉션 프레임워크

   ▷ 널리 알려진 자료구조를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 관련 인터페이스와 클래스들을 포함시켜 놓은 java.util 패키지

   ▷ 주요 인터페이스 : List, Set, Map

 

2. List 컬렉션

   ▷ 객체를 인덱스로 관리하기 때문에 객체를 저장하면 인덱스가 부여되고 인덱스로 객체를 검색, 삭제할 수 있는 기능 제공

 

NO 기능 메소드 설명
1 객체 추가 boolean add(E e) 주어진 객체를 맨 끝에 추가
2 void add(int index, E element) 주어진 인덱스에 객체를 추가
3 set(int index, E element) 주어진 인덱스의 객체를 새로운 객체로 바꿈
4 객체 검색 boolean contains(Object o) 주어진 객체가 저장되어 있는지 여부
5 E get(int index) 주어진 인덱스에 저장된 객체를 리턴
6 isEmpty() 컬렉션이 비어있는지 조사
7 int size() 저장되어 있는 전체 객체 수를 리턴
8 객체 삭제 void clear() 저장된 모든 객체를 삭제
9 E remove(int index) 주어진 인덱스에 저장된 객체를 삭제
10 boolean remove(Object o) 주어진 객체를 삭제

 

◎ ArrayList

   ▷ ArrayList에 객체를 추가하면 내부 배열에 객체가 저장되고 제한 없이 객체를 추가할 수 있음

   ▷ 객체의 번지를 저장. 동일한 객체를 중복 저장시 동일한 번지가 저장, null 저장 가능

   ▷ ArrayList 컬렉션에 객체를 추가시 인덱스 0번부터 차례대로 저장

   ▷ 특정 인덱스의 객체를 제거하거나 삽입하면 전체가 앞/뒤로 1씩 당겨지거나 밀림

   ▷ 빈번한 객체 삭제와 삽입이 일어나는 곳에선 바람직하지 않음

import java.util.ArrayList;
import java.util.List;

public class ArrayListExample {

	public static void main(String[] args) {
		// ArrayList 컬렉션 생성
		List<Board> list = new ArrayList<>();
		
		// 객체 추가
		list.add(new Board("제목1", "내용1", "글쓴이1"));
		list.add(new Board("제목2", "내용2", "글쓴이2"));
		list.add(new Board("제목3", "내용3", "글쓴이3"));
		list.add(new Board("제목4", "내용4", "글쓴이4"));
		list.add(new Board("제목5", "내용5", "글쓴이5"));

		// 저장된 총 객체 수 얻기
		int size = list.size();
		System.out.println("총 객체 수: " + size);
		System.out.println();
		
		// 특정 인덱스의 객체 가져오기
		Board board = list.get(2);
		System.out.println(board.getSubject() + "\t" 
					+ board.getContent() + "\t" + board.getWriter());
		System.out.println();
		
		// 모든 객체를 하나씩 가져오기
		for(int i=0; i<list.size(); i++) {
			Board b = list.get(i);
			System.out.println(b.getSubject() + "\t" 
					+ b.getContent() + "\t" + b.getWriter());
		}
		System.out.println();
		
		// 객체 삭제
		list.remove(2);
		list.remove(2);
		
		for(Board b : list) {
			System.out.println(b.getSubject() + "\t" 
					+ b.getContent() + "\t" + b.getWriter());
		}
	}
}


//	출력 : 
//	총 객체 수: 5
//	
//	제목3		내용3		글쓴이3
//	
//	제목1		내용1		글쓴이1
//	제목2		내용2		글쓴이2
//	제목3		내용3		글쓴이3
//	제목4		내용4		글쓴이4
//	제목5		내용5		글쓴이5
//	
//	제목1		내용1		글쓴이1
//	제목2		내용2		글쓴이2
//	제목5		내용5		글쓴이5

 

 

◎ Vector

   ▷ 동기화된 메소드로 구성되어 있어 멀티 스레드가 동시에 Vector() 메소드를 실행할 수 없습니다.

   ▷ 멀티 스레드 환경에서는 안전하게 객체를 추가 또는 삭제할 수 있습니다.

   ▷ ArrayList와 가장 큰 차이점은 동기화의 차이입니다.(하나의 스레드가 동작할동안 다른 값으로 바뀌지 않습니다.)

 

◎ Vector 예제

import java.util.List;
import java.util.Vector;
import java.util.ArrayList;

import array.Board;

public class VectorExample {
	public static void main(String[] args) {
		// Vector 컬렉션 생성
		List<Board> list = new Vector<>();

//		List<Board> list = new ArrayList<>();
		
		// 작업 스레드 객체 생성
		Thread threadA = new Thread() {
			@Override
			public void run() {
				// 객체 1000개 추가
				for(int i=1; i<=1000; i++) {
					list.add(new Board("제목"+i, "내용"+i, "글쓴이"+i));
				}
			}
		};
		
		// 작업 스레드 객체 생성
		Thread threadB = new Thread() {
			@Override
			public void run() {
				// 객체 1000개 추가
				for(int i=1001; i<=2000; i++) {
					list.add(new Board("제목"+i, "내용"+i, "글쓴이"+i));
				}
			}
		};
		
		// 작업 스레드 실행
		threadA.start();
		threadB.start();
		
		// 작업 스레드들이 모두 종료될 때까지 메인 스레드를 기다리게 함
		try {
			threadA.join();
			threadB.join();
		} catch(Exception e) {
		}
		
		// 저장된 총 객체 수 얻기
		int size = list.size();
		System.out.println("총 객체 수: " + size);
		System.out.println();
	}
}

//	Vector 출력 : 
//	총 객체 수: 2000

//	ArrayList 출력 : 
//	총 객체 수: 1983


▷ ArrayList를 사용하면 총 객체수는 계속 변동이 있고 에러가 나타날 수도 있습니다.
 이는 동기화의 차이 때문입니다.
 Vector는 add 한 번이 끝나면 다른 add가 실행되지만 ArrayList는 동시에 실행되기 때문에 오류가 나타납니다.

 

 

◎ LinkedList

   ▷ 인접 객체를 체인처럼 연결해서 관리합니다. 객체 삭제와 삽입이 빈번한 곳에서 ArrayList보다 유리합니다.

   ▷ 수정이 빈번한 곳에서는 유리하지만 검색에서는 불리합니다. 주소 포인터를 찾다보니 검색에서 취약합니다.

 

◎ LinkedList 예제

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class LinkedListExample {
	public static void main(String[] args) {
		// ArrayList 컬렉션 객체 생성
		List<String> list1 = new ArrayList<String>();

		// LinkedList 컬렉션 객체 생성
		List<String> list2 = new LinkedList<String>();
		
		// 시작 시간과 끝 시간을 저장할 변수 선언
		long startTime;
		long endTime;
		
		// ArrayList 컬렉션에 저장하는 시간 측정
		startTime = System.nanoTime();
		for(int i=0; i<10000; i++) {
			list1.add(0, String.valueOf(i));
		}
		
		endTime = System.nanoTime();
		System.out.printf("%-17s %8d ns \n", "ArrayList 걸린 시간:  ", (endTime-startTime));
		
		// LinkedList 컬렉션에 저장하는 시간 측정
		startTime = System.nanoTime();
		for(int i=0; i<10000; i++) {
			list2.add(0, String.valueOf(i));
		}
		endTime = System.nanoTime();
		System.out.printf("%-17s %8d ns \n", "LinkedList 걸린 시간: ", (endTime-startTime));		
	}
}

//	출력 :
//	ArrayList 걸린 시간:    8727800 ns 
//	LinkedList 걸린 시간:   1862400 ns


 ArrayList보다 LinkedList의 실행 시간이 훨씬 더 짧습니다.

 

3. Set 컬렉션

   ▷ Set 컬렉션은 저장 순서가 유지되지 않음

   ▷ 객체를 중복해서 저장할 수 없고, 하나의 null만 저장할 수 있음(수학의 집합 개념)

NO 기능 메소드 설명
1 객체 추가 boolean add(E e) 주어진 객체를 성공적으로 저장하면 true를 리턴하고 중복 객체면
false를 리턴
2 객체 검색 boolean contains(Object o) 주어진 객체가 저장되어 있는지 여부
3 isEmpty() 컬렉션이 비어있는지 조사
4 Iterator<E> iterator() 저장된 객체를 한 번씩 가져오는 반복자 리턴
5 int size() 저장되어 있는 전체 객체 수 리턴
6 객체 삭제 void clear() 저장된 모든 객체를 삭제
7 boolean remove(Object o) 주어진 객체를 삭제

 

◎ Set 컬렉션 사용 예제 

import java.util.*;

public class HashSetExample {
	public static void main(String[] args) {
		// HashSet 컬렉션 생성
		Set<String> set = new HashSet<String>();
		
		// 객체 저장
		set.add("Java");
		set.add("JDBC");
		set.add("JSP");
		set.add("Java");	// 중복 객체이므로 저장하지 않음
		set.add("Spring");
		
		// 저장된 객체 수 출력
		int size = set.size();
		System.out.println("총 객체 수: " + size);
	}
}

 

 

◎ HashSet

   ▷ 동등 객체를 중복 저장하지 않음

   ▷ 다른 객체라도 hashCode() 메소드의 리턴값이 같고, equals() 메소드가 true를 리턴하면 동일한 객체라고 판단하고 중복 저장하지않음

 

◎ HashSet 사용 예제

1. Member 클래스
public class Member {
	public String name;
	public int age;
	
	public Member(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	// hashCode 재정의
	@Override
	public int hashCode() {
		return name.hashCode() + age;
	}
	
	// equals 재정의
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Member) {
			Member target = (Member) obj;
			return target.name.equals(name) && (target.age == age);
		} else {
			return false;
		}
	}
}​


2. HashSetExample 메인 클래스
import java.util.*;

public class HashSetExample {
	public static void main(String[] args) {
		// HashSet 컬렉션 생성
		Set<Member> set = new HashSet<Member>();
		
		// Member 객체 저장
		set.add(new Member("홍길동", 30));
		set.add(new Member("홍길동", 30));
		
		// 저장된 객체 수 출력
		System.out.println("총 객체 수 : " + set.size());
	}
}

//	출력 : 
//	총 객체 수 : 1​

 

 

   ▷ iterator() 메소드 : 반복자를 얻어 Set 컬렉션의 객체를 하나씩 가져옴

 

NO 리턴 타입 메소드명 설명
1 boolean hasNext() 가져올 객체가 있으면 true를 리턴하고 없으면 false를 리턴합니다.
2 E next() 컬렉션에서 하나의 객체를 가져옵니다.
3 void remove() next()로 가져온 객체를 Set 컬렉션에서 제거합니다.

 

◎ iterator 사용 예제

import java.util.*;

public class HashSetExample {
	public static void main(String[] args) {
		// HashSet 컬렉션 생성
		Set<String> set = new HashSet<String>();
		
		// 객체 저장
		set.add("Java");
		set.add("JDBC");
		set.add("JSP");
		set.add("Spring");
		
		// 객체를 하나씩 가져와서 처리
		Iterator<String> iterator = set.iterator();
		while(iterator.hasNext()) {
			// 객체를 하나 가져오기
			String element = iterator.next();
			System.out.println(element);
			if(element.equals("JSP")) {
				//가져온 객체를 컬렉션에서 제거
				iterator.remove();
			}
		}
		System.out.println();
		
		// 객체 제거
		set.remove("JDBC");
		
		// 객체를 하나씩 가져와서 처리
		for(String element : set) {
			System.out.println(element);
		}
	}
}

//	출력 : 
//	Java
//	JSP
//	JDBC
//	Spring
//	
//	Java
//	Spring

 

컬렉션은 객체들을 유용하게 사용하기 위해서 추가, 제거 등을 할 수 있는 역할을 합니다.

생성자를 생성할 때 제네릭을 사용해 다양한 자료형을 적용할 수도 있습니다!

 

다음 글에서 좀 더 다양한 기능들에 대해서 알아볼게요!!

 

많은 분들의 피드백은 언제나 환영합니다! 많은 댓글 부탁드려요~~

 

728x90
반응형