이것이 자바다 - Part 15

mj·2023년 1월 10일
0
post-thumbnail

Part 15 컬렉션 자료구조

컬렉션 프레임워크

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

주요 인터페이스로는 List, Set, Map 이 있는데 인터페이스로 사용 가능한 컬렉션 객체 종류는 다음과 같다.

인터페이스 분류특징구현 클래스
List순서를 유지하고 저장, 중복 저장 가능ArrayList, Vector, LinkedList
Set순서를 유지하지 않고 저장, 중복 저장 안됨HashSet, TreeSet
Map키와 값으로 구성된 엔트리 저장, 키는 중복 저장 안됨.HashMap, Hashtable, TreeMap, Properties

List 컬렉션

List 컬렉션은 객체를 인덱스로 관리하기 때문에 객체를 저장하면 인덱스가 부여되고 인덱스로 객체를 검색, 삭제할 수 있는 기능을 제공한다.

List 컬렉션에서 공통적으로 사용가능한 List 인터페이스 메소드는 다음과 같다.

메소드설명
boolean add(E e)주어진 객체를 맨 끝에 추가
void add(int index, E element)주어진 인덱스에 객체를 추가
set(int index, E element)주어진 인덱스의 객체를 새로운 객체로 바꿈
boolean contain(Object o)주어진 객체가 저장되어 있는지 여부
E get(int index)주어진 인텍스에 저장된 객체를 리턴
isEmpty()컬렉션이 비어 있는지 조사
int size()저장되어 있는 전체 객체 수를 리턴
void clear()저장된 모든 객체를 삭제
E remove(int index)주어진 인덱스에 저장된 객체를 삭제
boolean remove(Object o)주어진 객체를 삭제

ArrayList

ArrayList 는 List 컬렉션에서 가장 많이 사용하는 컬렉션이다.

ArrayList에 객체를 추가하면 내부 배열에 객체가 저장된다. 일반 배열과의 차이점은 ArrayList는 제한 없이 객체를 추가할 수 있다는 것이다.

List 컬렉션은 객체 자체를 저장하는 것이 아니라 객체의 번지를 저장한다. 동일한 객체를 중복 저장하게 되면 기존의 객체와 동일한 번지가 저장된다. null 또한 저장 가능하다.

ArrayList 객체는 다음과 같이 생성할 수 있다.

  • ArrayList 생성
List<E> list = new ArrayList<E>();	//E에 지정된 타입의 객체만 저장
List<E> list = new ArrayList<>();	//E에 지정된 타입의 객체만 저장
List list = new ArrayList();		//모든 타입의 객체의 저장

List에 지정한 객체 타입과 동일하다면 ArrayList<>와 같이 객체 타입을 생략할 수도 있다.

객체 타입을 모두 생략하면 모든 종류의 객체를 저장할 수 있다.

Vector

Vector 는 ArrayList와 동일한 내부 구조를 가지고 있다. 차이점은 Vector는 동기화된 메소드로 구성되어 있기 때문에 멀티 쓰레드가 동시에 Vector() 메소드를 실행할 수 없다는 것이다.

때문에 멀티 쓰레드를 사용해서 List 타입의 데이터를 다룰때는 ArrayList 보다는 Vector를 사용하는 것이 좋다.

Vector 컬렉션은 다음과 같이 생성할 수 있다.

  • Vector 생성
List<E> list = new Vector<E>();		//E에 지정된 타입의 객체만 저장
List<E> list = new Vector<>();		//E에 지정된 타입의 객체만 저장
List list = new Vector();			//모든 타입의 객체의 저장

LinkedList

LinkedList 는 ArrayList 와 사용 방법은 동일하지만 내부 구조는 완전히 다르다.

ArrayList는 내부 배열에 객체를 저장하지만, LinkedList는 인접 객체를 체인처럼 연결해서 관리한다.

LinkedList는 객체 삽입, 삭제 시 앞뒤 링크만 관리해주면 되므로 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList보다 좋은 성능을 발취한다.

추가 내용
ArrayList는 내부에 특정 크기의 배열이 구현되어 있다.
그래서 만약 특정 크기 이상의 데이터가 ArrayList에 저장된다면 ArrayList 내부에 있는 배열의 크기가 재설정되고, 기존의 배열에 들어있는 값이 새로운 내부 배열에 복사된다.
그리고 LinkedList와 달리 ArrayList에서 삽입과 삭제 시, 삽입이나 삭제된 데이터 인덱스 뒤쪽에 있는 모든 데이터들이 1씩 옮겨지기 때문에, 빈번한 객체 삭제 삽입이 있어나는 곳에서는 LinkedList 사용하는 것이 성능 향상에 도움이 된다.

  • LinkedList 생성
List<E> list = new LinkedList<E>();		//E에 지정된 타입의 객체만 저장
List<E> list = new LinkedList<>();		//E에 지정된 타입의 객체만 저장
List list = new LinkedLis();			//모든 타입의 객체의 저장

Set 컬렉션

List 컬렉션은 저장 순서를 유지하지만, Set 컬렉션은 저장 순서가 유지되지 않는다. 또한 null 을 포함해서 객체를 중복 저장할 수 없다.

Set 컬렉션은 또한 구슬 주머니와도 같다. 저장할 때와 찾을 때의 순서가 다를 수도 있기 때문이다.

Set 컬렉션에는 HashSet, LinkedHashSet, TreeSet 등이 있는데, Set 컬렉션에서 공통적으로 사용 가능한 Set 인터페이스의 메소드는 다음과 같다. 인덱스로 관리하지 않기 때문에 인덱스를 매개값으로 갖는 메소드가 없다.

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

HashSet

Set 컬렉션 중에서 가장 많이 사용되는 것이 Hashset 이다.
다음은 HashSet 컬렉션을 생성하는 방법이다.

Set<E> set = new HashSet<E>();	//E에 지장된 타입의 객체만 저장
Set<E> set = new HashSet<E>();	//E에 지장된 타입의 객체만 저장
Set set = new HashSet();	//모든 타입의 객체를 저장

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

Set 컬렉션은 인덱스로 객체를 검색해서 가져오는 메소드가 없다. 대신 객체를 한 개씩 반복해서 가져와야 하는데, 여기에는 두가지 방법이 있다.

1. for 문을 이용

Set<E> set = new HashSet<>();
for(E e : set) {
	...
}

2. 반복자 객체 이용

Set 컬렉션의 iterator() 메소드로 반복자를 얻어 객체를 하나씩 가져올 수 있다.
타입 파라미터 E 는 Set 컬렉션에 저장되어 있는 객체의 타입이다.

Set<E> set = new HashSet<>();
Iterator<E> iterator = set.iterator();

그럼 객체의 타입 지정되지 않은 set 은 반복자도 객체를 지정안해도 되나?

Set set = new HashSet();
Iterator iterator = set.iterator();

이렇게?

iterator 는 Set 컬렉션의 객체를 가져오거나 제거하기 위해 다음 메소드를 제공한다.

리턴 타입메소드명설명
booleanhashHext()가져올 객체가 있으면 true를 리턴하고 없으면 false를 리턴한다.
Enext()컬렉션에서 하나의 객체를 가져온다.
voidremove()next() 로 가져온 객체를 Set 컬렉션에서 제거한다.
while(iterator.hashNext()) {
	E e = iterator.next();
}

Map 컬렉션

Map 컬렉션은 카와 값으로 구성된 엔트리 객체를 저장한다. 여기서 키와 값은 모두 객체이다.

키는 중복 젖아할 수 없지만 값은 중복 저장할 수 있다. 기존에 저장된 키와 동일한 키로 값을 저장하면 기존의 값은 없어지고 새로운 값으로 대치된다.

Map 컬렉션에는 HashMap, HashTable, LinkedHashMap, Properties, TreeMap 등이 있다.

Map 컬렉션에서 사용 가능한 Map 인터페이스 메소드는 다음과 같다.

기능메소드설명
객체 추가V put(K key, V value)주어진 키와 값을 추가, 저장이 되면 값을 리턴
객체 검색boolean containsKey(Object key)주어진 키가 있는지 여부
객체 검색boolean containsValue(Object value)주어진 값이 있는지 여부
객체 검색Set<Map.Entry<K, V>> entrySet()키와 값의 쌍으로 구성된 모든 Map.Entry 객체를 Set에 담아서 리턴
객체 검색V get(Object key)주어진 키의 값을 리턴
객체 검색boolean isEmpty()컬렉션이 비어있는지 여부
객체 검색Set\<K> keySet()모든 키를 Set 객체에 담아서 리턴
객체 검색int size()저장된 키의 총 수를 리턴
객체 검색Collection\<V> values()저장된 모든 값 Collection에 담아서 리턴
객체 삭제void clear()모든 Map.Entry(키와 값) 를 삭제
객체 삭제V remove(Object key)주어진 키와 일치하는 Map.Entry 삭제, 삭제가 되면 값을 리턴

HashMap

HashMap은 키로 사용할 객체가 hashCode() 메소드의 리턴값이 같고 equals() 메소드가 true를 리턴할 경우, 동일 키로 보고 중복 저장을 허용하지 않는다.

다음은 HashMap 컬렉션을 생성하는 방법이다. K와 V는 각각 키와 값의 타입을 지정할 수 있는 타입 파라미터이다.

Map<K, V> map = new HashMap<K, V>();

Map<String, Integer> map = new HashMap<String, Integer>();
Map<String, integer> map = new HashMap<>();

모든 타입의 키와 객체를 저장할 수 있도록 HashMap을 다음과 같이 생성할 수 있지만, 이런 경우는 거의 없다.

Map map = new HashMap();

Hashtable

Hashtable은 HashMap과 동일한 내부 구조를 가지고 있다. 차이점은 Hashtable은 동기화된 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 Hashtable 의 메소드들을 실행할 수 없다는 것이다. 따라서 멀티 스레드 환경에서도 안전하게 객체를 추가, 삭제할 수 있다.

다음은 키 타입으로 String을, 값 타입으로 Integer 를 갖는 Hashtable을 생성한다.

Map<String, Integer> map = new Hashtable<String, Integer>();
Map<String, Integer> map = new Hashtable<>();

Properties

Properties 는 Hashtable 의 자식 클래스이기 때문에 Hashtable 의 특징을 그대로 가지고 있다.
Properties 는 키와 값을 String 타입으로 제한한 컬렉션이다. 주로 확장자가 .properties 인 프로퍼티 파일을 읽을 때 사용한다.

프로퍼티 파일
키와 값이 = 기호로 연결되어 있는 텍스트 파일이다.
일반 텍스트 파일과 다르게 ISO 8859-1 문자셋으로 저장되며, 한글일 경우에는 \u + 유니코드로 표현되어 저장된다.

사용법은 다음과 같다.
Properties 객체를 생성하고, load() 메소드로 프로퍼티 파일의 내용을 메모리로 로드한다.

Properties properties = new Properties();
properties.load(Xxx.class.getResoureAsStream("database.properties"));

일반적으로 프로퍼티 파일은 클래스 파일들과 함께 저장된다.
따라서 클래스 파일을 기준으로 상태 경로를 이용해서 읽는 것이 편리하다.
Class 객체의 getResourceAsStream() 메소드는 주어진 상대 경로의 리소스 파일을 읽는 InputStream 을 리턴한다.

검색 기능을 강화시킨 컬렉션

컬렉션 프레임 워크는 검색 기능을 강화시킨 TreeSet 과 TreeMap 을 제공한다.

TreeSet

TreeSet 은 이진 트리를 기반으로 한 Set 컬렉션이다.
이진 트리는 여러 개의 노드가 트리형태로 연결된 구조로, 루트 노드라고 불리는 하나의 노드에서 시작해 각 노드에 최대 2개의 노드를 연결할 수 있는 구조를 가지고 있다.

TreeSet 에 객체를 저장하면 부모 노드의 객체와 비교해서 낮은 것은 왼쪽 자식 노드에, 높은 것은 오른쪽 자식 노드에 자동으로 저장한다.

TreeSet<E> treeset = new TreeSet<E>();
TreeSet<E> treeset = new TreeSet<E>();

Set 타입 변수에 대입해도 되지만 TreeSet 타입으로 대입한 이유는 검색 관련 메소드가 TreeSet에만 정의되어 있기 때문이다.
다음은 TreeSet 이 가지고 있는 검색 관련 메소드들이다.

리턴 타입메소드설명
Efirst()제일 낮은 객체를 리턴
Elast()제일 높은 객체를 리턴
Elower(E e)주어진 객체보다 바로 아래 객체를 리턴
Ehigher(E e)주어진 객체보다 바로 위 객체를 리턴
Efloor(E e)주어진 객체와 동등한 객체가 있으면 리턴, 만약 없다면 주어진 객체의 바로 아래의 객체를 리턴
Eceiling(E e)주어진 객체와 동등한 객체가 있으면 리턴, 만약 없다면 주어진 객체의 바로 위의 객체를 리턴
EpollFirst()제일 낮은 객체를 꺼내오고 컬렉션에서 제거함
EpollLast()제일 높은 객체를 꺼내오고 컬렉션에서 제거함
Iterator<E>descendingIterator()내림차순으로 정렬된 Iterator 를 리턴
NavigableSet<E>descendingSet()내림차순으로 정렬된 NavigableSet 을 리턴
NavigableSet<E>headset(E toElement, boolean inclusive)주어진 객체보다 낮은 객체들을 NavigableSet 으로 리턴, 주어진 객체 포함 여부는 두 번째 매개값에 따라 달라짐
NavigableSet<E>tailSet(E fromElement, boolean inclusive)주어진 객체보다 높은 객체들을 NavigableSet 으로 리턴, 주어진 객체 포함 여부는 두 번째 매개값에 따라 달라짐
NavigableSet<E>subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)시작과 끝으로 주어진 객체 사이의 객체들을 NavigableSet 으로 리턴, 시작과 끝 객체의 포함 여부는 두 번째, 네 번째 매개값에 따라 달라짐

TreeMap

TreeMap 은 이진 트리를 기반으로 한 Map 컬렉션이다. TreeSet 과의 차이점은 키와 값이 저장된 Entry 를 저장한다는 점이다.
TreeMap 에 엔트리를 저장하면 키를 기준으로 자동 정렬되는데, 부모키 값과 비교해서 낮은 것은 왼쪽, 높은 것은 오른쪽 자식 노드에 Entry 객체를 저장한다.

TreeMap<K, V> treeMap = new TreeMap<K, V>();
TreeMap<K, V> treeMap = new TreeMap<>();

Map 타입 변수에 대입해도 되지만 TreeMap 타입으로 한 이유는 검색 관련 메소드가 TreeMap 에만 정의되어 있기 때문이다.

리턴 타입메소드설명
Map.Entry<K, v>firstMap()제일 낮은 Map.Entry 를 리턴
Map.Entry<K, v>lastMap()제일 높은 Map.Entry 를 리턴
Map.Entry<K, v>lowerEntry(K key)주어진 키보다 바로 아래 Map.Entry 를 리턴
Map.Entry<K, v>higherEntry(K key)주어진 키보다 바로 위 Map.Enrty 를 리턴
Map.Entry<K, v>floorEntry(K key)주어진 키와 동등한 키가 있으면 해당 Map.Entry 를 리턴, 없다면 주어진 키 바로 아래의 Map.Entry 를 리턴
Map.Entry<K, v>ceilingEntry(K key)주어진 키와 동등한 키가 있으면 해당 Map.Entry 를 리턴, 없다면 주어진 키 바로 위의 Map.Entry 를 리턴
Map.Entry<K, v>pollFirstEntry()제일 낮은 Map.Entry 를 꺼내오고 컬렉션에서 제거
Map.Entry<K, v>pollLastEntry()제일 높은 Map.Entry 를 꺼내오고 컬렉션에서 제거
Map.Entry<K, V>descendingKeySet()내림차순으로 정렬된 키의 NavigableMap 을 리턴
NavigableMap<K, V>descendingMap()오름차순으로 정렬된 키의 NavigableMap 을 리턴
NavigableMap<K, V>headMap(K toKey, boolean inclusive)주어진 키보다 낮은 Map.Entry 들을 NavigableMap으로 리턴, 주어진 키의 Map.Entry 포함 여부는 두 번째 매개값에 따라 달라짐
NavigableMap<K, V>tailMap(K fromKey, boolean inclusive)주어진 키보다 높은 Map.Entry 들을 NavigableMap으로 리턴, 주어진 키의 Map.Entry 포함 여부는 두 번째 매개값에 따라 달라짐
NavigableMap<K, V>subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)시작과 끝으로 주어진 키 사이의 Map.Entry 들을 NavigableMap 컬렉션으로 반환, 시작과 끝 키의 Map.Entry 포함 여부는 두 번째, 네 번째 매개값에 따라 달라짐.

Comparable 과 Comparator

TreeSet 에 저장되는 객체와 TreeMap 에 저장되는 키 객체는 저장과 동시에 오름차순으로 정렬되는데, 객체가 Comparable 인터페이스를 구현하고 있어야 정렬이 가능하다.

Comparable 인터페이스에는 compareTo() 메소드가 정의되어 있다.
따라서 사용자 정의 클래스에서 이 메소드를 재정의해서 비교 결과를 정수 값으로 리턴해야 한다.

리턴 타입메소드설명
intcompareTo(T o)주어진 객체와 같으면 0, 적으면 음수, 크면 양수를 리턴

비교 기능이 없는 Comparable 비구현 객체를 저장하고 싶다면 TreeSet, TreeMap 을 생성할 때 비교자를 다음과 같이 제공하면 된다.

TreeSet<E> treeSet = new TreeSet<E>( new ComparatorIml() );

TreeMet<K, V> treeMet = new TreeMet<K, V>( new ComparatorIml() );

비교자는 Comparator 인터페이스를 구현한 객체를 말하는데, Comparator 인터페이스에는 compare() 메소드가 정의되어 있다.

비교자는 이 메소드를 재정의해서 비교 결과를 정수 값으로 리턴하면 된다.

리턴 타입메소드설명
intcompare(T o1, T o2)o1, o2 가 동등하면 0, o1이 o2보다 앞에 오게 하려면 음수, o1이 o2보다 뒤에 오게 하려먼 양수를 리턴

LIFO와 FIFO 컬렉션

후입선출은 나중에 넣은 객체가 먼저 빠져나가고, 선입선출은 먼저 넣은 객체가 먼저 빠져나가는 구조를 말한다.
컬렉션 프레임워크는 LIFO 자료구조를 제공하는 스택 클래스와 FIFO 자료구조를 제공하믄 큐 인터페이스를 제공한다.

Stack

Stack 클래스는 LIFO 자료구조를 구현한 클래스이다.

Stack<E> stack = new Stack<E>();
Stack<E> stack = new Stack<>();

다음은 Stack 클래스의 주요 메소드이다.

리턴 타입메소드설명
Epush(E item)주어진 객체를 스택에 넣는다.
Epop()스택의 맨 위 객체를 빼낸다.

Queue

Queue 인터페이스는 FIFO 자료구조에선 사용되는 메소드를 정의하고 있다.
Queue 인터페이스를 구현한 대표적인 클래스는 LinkedList 이다.
때문에 LinkedList 객체를 Queue 인터페이스 변수에 다음과 같이 대입할 수 있다.

Queue<E> queue = new LinkedList<E>();
Queue<E> queue = new LinkedList<>();
리턴 타입메소드설명
booleanoffer(E e)주어진 객체를 큐에 넣는다.
Epoll()큐에서 객체를 빼낸다.

동기화된 컬렉션

컬렉션 프레임워크의 대부분은 싱글 스레드 환경에서 사용할 수 있도록 설계되었다.
그렇게 때문에 여러 스레드가 동시에 컬렉션에 접근한다면 의도하지 않게 요소가 변경될 수 있는 불완전한 상태가 된다.

Vector 와 HashTable 은 동기화된 메소드로 구성되어 있기 때문에 멀티 스레드 환경에서 안전하게 요소를 처리할 수 있지만, 다른 컬렉션은 동기화된 메소드로 구성되어 있지 않아 안전하지 않다.

경우에 따라서는 ArrayList, HashSet, HashMap 을 멀티 스레드 환경에서 사용하고 싶을 때가 있다.
이런 경우를 대비해서 컬렉션 프레임워크는 비동기화된 메소드를 동기화된 메소드로 래핑하는 Collections 의 synchronizedXXX() 메소드를 제공한다.

리턴 타입메소드(매개변수)설명
List<T>synchronizedList(List<T> list)List 를 동기화된 List로 리턴
Map<K, V>synchronizedList(Map<K, V> m)Map 을 동기화된 Map으로 리턴
Set<T>synchronizedList(Set<T> s)Set 을 동기화된 Set 으로 리턴
List<T> list = Collections.synchronizedList(new ArrayList<T>());

Set<E> set = Collections.synchronizedSet(new HashSet<E>());

Map<K, V> map = Collections.synchronizedMap(new HashMap<K, V>());

수정할 수 없는 컬렉션

수정할 수 없는 컬렉션이란 요소를 추가, 삭제할 수 없는 컬렉션을 말한다.
컬렉션 생성 시 저장된 요소를 변경하고 싶지 않을 때 유용하다.

다음과 같은 방법으로 만들 수 있다.

1. List, Set, Map 인터페이스의 정적 메소드인 of() 로 생성

List<E> immutableList = List.of(E... elements);
Set<E> immutableSet = Set.of(E... elements);
Map<K, V> immutableMap = Map.of(K k1, V v1, K k2, V v2 ...);

2. List, Set, Map 인터페이스의 정적 메소드인 copyOf() 을 이용해 기존 컬렉션을 복사하여 수정할 수 없는 컬렉션을 만듬

List<E> immutableList = List.copyOf(Collection<E> coll);
Set<E> immutableSet = Set.copyOf(Collection<E> coll);;
Map<K, V> immutableMap = Map.copyOf(Map<K, V> map);;

3. 배열로부터 수정할 수 없는 List 컬렉션을 만듬

String[] arr = { "A", "B", "C" };
List<String> immutableList = Arrays.asList(arr);

문제

  1. 자바의 컬렉션 프레임워크에 대한 설명으로 틀린 것은 무엇입니까?
    ➊ List 컬렉션은 인덱스로 객체를 관리하며 중복 저장을 허용한다.
    ➋ Set 컬렉션은 순서를 유지하지 않으며 중복 저장을 허용하지 않는다.
    ➌ Map 컬렉션은 키와 값으로 구성된 Map.Entry를 저장한다.
    ➍ Stack은 FIFO(선입선출) 자료구조를 구현한 클래스이다.
  • 답: ➍
  1. List 컬렉션에 대한 설명 중 틀린 것은 무엇입니까?
    ➊ 대표적인 구현 클래스로는 ArrayList, Vector, LinkedList가 있다.
    ➋ 멀티 스레드 환경에서는 ArrayList보다는 Vector가 스레드에 안전하다.
    ➌ ArrayList에서 객체를 삭제하면 삭제된 위치는 비어 있게 된다.
    ➍ 중간 위치에 객체를 빈번히 삽입하거나 제거할 경우 LinkedList를 사용하는 것이 좋다.
  • 답 : ➌
  1. Set 컬렉션에 대한 설명 중 틀린 것은 무엇입니까?
    ➊ 대표적인 구현 클래스로는 HashSet, LinkedHashSet, TreeSet이 있다.
    ➋ Set 컬렉션에서 객체를 하나씩 꺼내오고 싶다면 Iterator를 이용한다.
    ➌ HashSet은 hashCode()와 equals() 메소드를 이용해서 중복된 객체를 판별한다.
    ➍ Set 컬렉션에는 null을 저장할 수 없다.
  • 답 : ➍
  1. Map 컬렉션에 대한 설명 중 틀린 것은 무엇입니까?.
    ➊ 대표적인 구현 클래스로는 HashMap, Hashtable, TreeMap, Properties가 있다.
    ➋ HashMap과 Hashtable은 hashCode()와 equals() 메소드를 이용해서 중복 키를 판별한다.
    ➌ 멀티 스레드 환경에서는 Hashtable보다는 HashMap이 스레드에 안전하다.
    ➍ Properties는 키와 값이 모두 String 타입이다
  • 답 : ➌
  1. 단일(싱글) 스레드 환경에서 Board 객체를 저장 순서에 맞게 읽고 싶습니다. 가장 적합한 컬렉
    션을 생성하도록 밑줄 친 부분에 코드를 작성해보세요.
 __________________ 변수 = new ___________________
  • 답 :
List<Board> 변수 = new ArrayList<Board>();
  1. 단일(싱글) 스레드 환경에서 학번(String)를 키로, 점수(Integer)를 값으로 저장하는 가장 적합
    한 컬렉션을 생성하도록 밑줄 친 부분에 코드를 작성해보세요.
 __________________ 변수 = new ___________________
  • 답 :
Map<String, Integer> 변수 = new HashMap(String, Integer>();
  1. BoardDao 객체의 getBoardList() 메소드를 호출하면 List\<Board> 타입의 컬렉션을 리턴합
    니다. ListExample 클래스의 실행 결과를 보고, BoardDao 클래스와 getBoardList() 메소드를
    작성해보세요.
public class Board {
	private String title;
	private String content;
	public Board(String title, String content) {
 		this.title = title;
 		this.content = content;
	}
	public String getTitle() { return title; }
	public String getContent() { return content; }
}
import java.util.List;
public class ListExample {
	public static void main(String[] args) {
 		BoardDao dao = new BoardDao();
 		List<Board> list = dao.getBoardList();
 		for(Board board : list) {
 			System.out.println(board.getTitle() + "-" + board.getContent());
 		}
	}
}
import java.util.ArrayList;
import java.util.List;

public class BoardDao {
	public List<Board> getBoardList() {
 		List<Board> list = new ArrayList<Board>();
 		list.add(new Board("제목1", "내용1"));
 		list.add(new Board("제목2", "내용2"));
 		list.add(new Board("제목3", "내용3"));
 		return list;
	}
}
  1. HashSet에 Student 객체를 저장하려고 합니다. 학번이 같으면 동일한 Student라고 가정하고
    중복 저장이 되지 않도록 하고 싶습니다. Student 객체의 해시코드는 학번이라고 가정하고 Student
    클래스를 작성해보세요.
public class Student {
	public int studentNum;
	public String name;
	public Student (int studentNum, String name) {
 		this.studentNum = studentNum;
 		this.name = name;
	}
//여기에 코드를 작성하세요.
}
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
	public static void main(String[] args) {
 		Set<Student> set = new HashSet<Student>();
 		set.add(new Student(1, "홍길동"));
 		set.add(new Student(2, "신용권"));
 		set.add(new Student(1, "조민우"));
 		System.out.println("저장된 객체 수: " + set.size());
 		for(Student s : set) {
 			System.out.println(s.studentNum + ":" + s.name);
 		}
	}
}
  • 답 :
	@Override
	public int hashCode() {
		return studentNum;
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Student)) return false;
 		Student std = (Student) obj;
 		if(studentNum != std.studentNum) return false;
 		return true;
	}
  1. HashMap에 아이디(String)와 점수(Integer)가 저장되어 있습니다. 실행 결과와 같이 평균 점
    수, 최고 점수, 최고 점수를 받은 아이디를 출력하도록 코드를 작성해보세요.
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapExample {
	public static void main(String[] args) {
 		Map<String,Integer> map = new HashMap<String,Integer>();
 		map.put("blue", 96);
 		map.put("hong", 86);
 		map.put("white", 92);

 		String name = null; //최고 점수를 받은 아이디를 저장하는 변수
 		int maxScore = 0; //최고 점수를 저장하는 변수
 		int totalScore = 0; //점수 합계를 저장하는 변수

 //여기에 코드를 작성하세요.
	}
}
  • 답 :
		Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
 		for(Map.Entry<String,Integer> entry : entrySet) {
 			if(entry.getValue()>maxScore) {
 			name = entry.getKey();
 			maxScore = entry.getValue();
 			}
 			totalScore += entry.getValue();
 		}

 		int averScore = totalScore / map.size();
 		System.out.println("평균 점수: " + averScore);

 		System.out.println("최고 점수: " + maxScore);
 		System.out.println("아이디: " + name);
  1. TreeSet에 Student 객체를 저장할 때, Student의 score 필드값을 기준으로 자동 정렬되도록
    구현하고 싶습니다. TreeSet의 last() 메소드를 호출했을 때 가장 높은 score의 Student 객체가
    리턴되도록 Student 클래스에서 밑줄 친 곳과 비어있는 곳에 코드를 작성해보세요.
public class Student _____________________ {
	public String id;
	public int score;
	public Student (String id, int score) {
		this.id = id;
 		this.score = score;
	}
    /*
    코드 작성
    */
}
import java.util.TreeSet;

public class TreeSetExample {
	public static void main(String[] args) {
 		TreeSet<Student> treeSet = new TreeSet<Student>();
 		treeSet.add(new Student("blue", 96));
 		treeSet.add(new Student("hong", 86));
 		treeSet.add(new Student("white", 92));

 		Student student = treeSet.last();
 		System.out.println("최고 점수: " + student.score);
 		System.out.println("최고 점수를 받은 아이디: " + student.id);
 	}
}
  • 답 :
 	implements Comparable<Student>
	@Override
	public int compareTo(Student st) {
 		if(score < st.score) return -1;
 		else if(score == st.score) return 0;
 		else return 1;
	}
  1. LIFO와 FIFO 컬렉션에 대한 설명으로 틀린 것은 무엇입니까?
    ➊ Stack은 LIFO이고 Queue는 FIFO 구조를 가지고 있다.
    ➋ Stack에 넣는 행위는 push이고, 빼는 행위는 pop이다.
    ➌ Queue에 넣는 행위는 offer이고, 빼는 행위는 poll이다.
    ➍ Stack과 Queue는 자바에서 클래스 타입이다.
  • 답 : ➍
  1. 동기화된 컬렉션에 대한 설명으로 틀린 것은 무엇입니까?
    ➊ 멀티 스레드 환경에서 안전하게 사용할 수 있는 컬렉션이다.
    ➋ 동기화된 컬렉션의 메소드는 synchronized 처리가 되어 있다.
    ➌ Vector와 HashMap은 동기화된 컬렉션이다.
    ➍ Collections의 synchronizedMap() 메소드는 동기화된 Map을 리턴한다.
  • 답 : ➌
  1. 수정할 수 없는 List 컬렉션에 대한 설명으로 틀린 것은 무엇입니까?
    ➊ 요소를 추가, 삭제할 수 없는 List 컬렉션을 말한다.
    ➋ List의 of() 메소드는 수정할 수 없는 컬렉션을 생성한다.
    ➌ List의 copyOf() 메소드는 기존 컬렉션을 복사한 수정할 수 없는 컬렉션을 생성한다.
    ➍ Array.asList() 메소드는 배열로부터 수정할 수 있는 List 컬렉션을 생성한다
  • 답 : ➍
profile
사는게 쉽지가 않네요

0개의 댓글