이번주를 정의하자면, 컬렉션 프레임워크에 대한 지식을 확장한 한 주였다.
특히 컬렉션을 활용할 수 있는 문법, 사용 시 헷갈릴만한 점들을 알게 되었다.
조각 지식
- 컬렉션 프레임워크를 선언할 때
<T>
를 굳이 적지 않아도 된다. .contains(Object)
: 컬렉션 프레임워크에 해당 Object가 있는지 boolean으로 리턴하는 함수.isEmpty()
: 컬렉션의 사이즈가 0인지 boolean으로 리턴하는 함수.indexOf(Object)
: 해당 Object가 있는 인덱스 중 가장 앞에 있는 인덱스를 리턴한다.
(List 인터페이스를 implement하는 클래스들에서만 사용 가능 e.g. ArrayList, LinkedList, Vector, Stack)- Array to ArrayList :
ArrayList arrayList = new ArrayList(Arrays.asList(array));
- ArrayList to Array :
T[ ] arr1 = arraylist.toArray(new T[arraylist.size()]);
이때 T는 Intger처럼 class 타입이어야 함 - 로또 문제를 Set을 이용하면 훨씬 간단히 구현할 수 있다.
(중복되는 값은 add가 안되므로 & sort하기 위해선 다시 ArrayList로 바꿔야 함 : ArrayList arr = new ArrayList(set); ) - Array to stream :
Arrays.stream(array)
- ArrayList sort :
Collections.sort(arraylist)
- String을 더할때는 +=가 아니라 StringBuilder객체를 사용하는 게 좋다.
String은 길이가 변할 수 없는 객체를 만들므로 +=를 사용하면, 길이가 달라진 String 객체를 새롭게 생성하여 그 값을 리턴한다.
하지만 StringBuilder을 사용하면 가변 길이의 String 객체를 생성하므로 String을 합칠 때 성능이 더 좋다.StringBuilder sb = new StringBuilder();
sb.append("자바").append("최고");
StringBuilder을 String으로 바꾸기 위해선 toString() 메소드를 사용하면 된다.
Deque
- 양방향에서 삽입 삭제가 가능한 구조
- offerFirst / pollFirst / offerLast / pollLast 모두 가능하다.
- 데크 선언 :
Deque<E> deque = new LinkedList<>() || new ArrayDeque<>();
여러 클래스들이 Deque 인터페이스를 구현하므로 다양한 방법으로 생성할 수 있다.
(e.g. ArrayDeque, LinkedBlockingDeque, ConcurrentLinkedDeque, LinkedList)
이중 indexOf를 써야 하는 상황에서는 LinkedList, 다른 경우에서는 ArrayDeque가 더 성능이 좋으므로 ArrayDeque를 사용하면 된다.
참고 : https://tech-monster.tistory.com/159
HashTable
- 키와 값을 대응시켜서 저장하는 데이터 구조
- 키를 통해서 해당 데이터에 빠르게 접근 가능
- 테이블에 값을 저장할 때 아래와 같은 동작이 일어난다.
해싱 함수에 의해 키가 해시 값으로 매핑된다.
해시값은 해시 테이블에서 인덱스의 역할을 한다.
해시 값과 함께 데이터를 저장한다.
하지만 우리가 컬렉션 프레임워크로 HashTable을 사용할 때는 해싱 함수나, 충돌을 피하는 방법 등은 고려하지 않을 때가 더 많다.
HashTable 주요 메서드
containsKey(K key)
containsValue(V value)
entrySet() + entry.getKey(), entry.getValue()
keySet() + entry.get(key)
valueSet()
get(K key)
put(K key, V value)
remove(K key)
getOrDefault(K key, E defaultValue) // key에 해당하는 value가 있으면 그 value를 리턴하고 없으면 defaultValue를 리턴
HashMap과 HashTable 비교
- 공통점 : 둘 다 Map 인터페이스를 구현하고 있으므로 key, value를 저장하고 있다.
- 차이점 ① : key에 null을 사용할 수 있는가
HashMap : O
HashTable : X - 차이점 ② : thread-safe 측면
HashMap : X (싱글 스레드 환경에서 우수)
HashTable : O (멀티 스레드 환경에서 우수 / thread safe)
cf. synchronizedMap, ConcurrentHashMap을 사용하면 HashMap을 thread-safe 하게 사용할 수 있다.
하지만 일반적인 코딩테스트의 상황에서는 멀티 스레드가 일어나지 않으므로 HashMap을 써도 무방하다.
컬렉션 프레임워크 계층 구조
❓왜 Linked List에서 Deque의 메서드인 pollFirst/Last, offerFirst/Last가 사용 가능할까?
❗ 컬렉션 프레임 워크의 의존 관계도를 보면 그 이유를 알 수 있다.
Linked List는 Deque 인터페이스를 implements하고 있다.
복습 ) 어떤 클래스가 인터페이스를 implements 한다면, 그 인터페이스의 메서드를 사용할 수 있다.
따라서 LinkedList deque = new LinkedList<>( );로 생성한 dequeue는 링크드 리스트의 indexOf와 데크의 poll / offer 메소드를 모두 사용할 수 있다.
❓Queue에서 poll, offer 뿐 아니라 add, remove가 사용 가능한 이유?
❗앞의 이유와 마찬가지로, 컬렉션 프레임 워크의 상속 관계 때문에 그렇다.
Queue가 Collection 인터페이스를 implements 하고 있으므로 Collection 인터페이스의 add, remove함수를 사용할 수 있는 것이다.
이 두 연산의 차이점은 아래와 같다.
예외를 방지하기 위해서 AND 지금 큐를 이용한 연산을 한다는 것을 명시하기 위해서 poll과 offer을 쓰도록 하자.
Lambda, Stream, Optional
[JAVA] 람다식, Stream, Optional (tistory.com)
'JAVA' 카테고리의 다른 글
[JAVA] String / StringBuilder / StringBuffer 차이점 (0) | 2023.05.23 |
---|---|
[JAVA] equals로 문자열 비교할 때 NullPointerException 피하는 방법 (0) | 2023.05.22 |
[JAVA] 람다식, Stream, Optional (0) | 2023.05.11 |
스프링 빈과 자동 의존관계 설정 (0) | 2023.04.03 |
[스프링 입문] 회원관리 예제 - 도메인, 레포지토리, 서비스 (0) | 2023.03.14 |