Lambda 표현식
int add(int x, int y) {
return x + y;
}
// 위의 메서드를 람다 표현식을 이용해 아래와 같이 단축 시킬수 있다. (메서드 반환 타입, 메서드 이름 생략)
(int x, int y) -> {
return x + y;
};
// 매개변수 타입도 생략 할 수 있다.
(x, y) -> {
return x + y;
};
// 함수에 리턴문 한줄만 있을 경우 더욱 더 단축 시킬 수 있다. (중괄호, return 생략)
(x, y) -> x + y;
Stack
LIFO(Last In First Out)
java.util.Stack<E> 클래스를 통해 자료형을 제공.
Vector 클래스를 상속받아 구현됨.
Method
삽입 - push(e)
삭제 - pop()
조회 - peek()
사용예제
Stack<Integer> stack = new Stack<>();
Stack 클래스는 Vector 클래스를 상속하여 구현되어 있다.
Vector 클래스는 List를 구현한 클래스로 자바 1.0부터 제공되어왔는데, 성능 상의 문제로 현재는 사용이 권장되지 않고 있다. 결과적으로 Stack 클래스의 사용도 권장되지 않는다.
Vector의 사용이 권장되지 않는 이유
비교 | Vector | ArrayList |
동기화 처리 | O | X |
쓰레드 안전 | O | X |
성능 | 비교적 느림 | 비교적 빠름 |
용량 증가 | 2배 | 1.5배 |
Vector는 동기화된 메서드로 구성되어 있어 멀티 쓰레드 환경에서 안전하나 단일 쓰레드 환경에서도 동기화 처리에 대한 오버헤드가 발생하여 성능 저하가 발생할 수 있다. 따라서 단일 쓰레드 환경에서는 ArrayList를 사용하는 것이 성능상 유리하다.
그리고 되도록 Stack 대신 Deque 사용을 권장한다.
비교 | Stack | ArrayDeque |
동기화 처리 | O | X |
쓰레드 안전 | O | X |
성능 | 비교적 느림 | 비교적 빠름 |
Deque는 별도의 동기화 처리를 위한 메서드가 없다. 하지만 외부 동기화를 통해 멀티쓰레드 환경에서도 안전하게 사용할 수 있다.
외부 동기화 처리 코드↴
class SyncStack<E> {
private final Deque<E> stack = new ArrayDeque<>();
public synchronized void push(E e) {
stack.push(e);
}
}
Deque
Double Ended Queue의 약자 = 양방향 큐
java.util.Deque<E> 클래스를 통해 자료형을 제공.
Queue 인터페이스를 상속받아 구현됨.
Method
예외 발생 시 어떤 값을 반환 할 지에 따라 메서드를 선택해서 씀.
예외 발생 시 에러 발생시킴
삽입 - addFirst(e), addLast(e)
삭제 - removeFirst(), removeLast()
조회 - getFirst(), getLast()
예외 발생 시 Special Value 반환
삽입 - offerFirst(e), offerLast(e) ---> 삽입이 제대로 이루어지지 않으면 false반환
삭제 - pollFirst(), pollLast() ---> 데이터가 존재하지 않을 시 null값 반환
조회 - peekFirst(), peekLast() ---> 데이터가 존재하지 않을 시 null값 반환
사용예제
Queue<Integer> queue = new LinkedList<>();
queue.offer(1);
Stack 메서드에 대응되는 Deque 메서드
Stack | Deque |
push(e) | addFirst(e) |
pop() | removeFirst() |
peek() | peekFirst() |
Deque을 이용한 Stack과 Queue구현
class MyClass {
public static void main(String[] args) throws InterruptedException {
# 스택
System.out.println("Stack!!");
Deque<String> stack = new ArrayDeque<>();
stack.addFirst("Element1");
stack.addFirst("Element2");
stack.addFirst("Element3");
System.out.println(stack.removeFirst());
System.out.println(stack.removeFirst());
System.out.println(stack.removeFirst());
# 큐
System.out.println("Queue!!");
Deque<String> queue = new ArrayDeque<>();
queue.addFirst("Element1");
queue.addFirst("Element2");
queue.addFirst("Element3");
System.out.println(queue.removeLast());
System.out.println(queue.removeLast());
System.out.println(queue.removeLast());
}
}
ALGORITHM CODE KATA
Ⅰ. 배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다. 예를 들면, arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다. arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다. 배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.
제한사항
배열 arr의 크기 : 1,000,000 이하의 자연수
배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수
import java.util.*;
public class Solution {
public int[] solution(int []arr) {
int prev = -1;
int cnt = 0;
for(int i=0; i<arr.length; i++){
if (arr[i]==prev){
continue;
}
else {
cnt++;
prev = arr[i];
};
}
int[] answer = new int[cnt];
prev = -1;
cnt = 0;
for(int i=0; i<arr.length; i++){
if (arr[i]==prev){
continue;
}
else {
answer[cnt] = arr[i];
prev = arr[i];
cnt++;
};
}
return answer;
}
}
Deque를 이용한 풀이↴
import java.util.*;
public class Solution {
public Deque<Integer> solution(int []arr) {
Deque<Integer> deque = new LinkedList<>();
for(int num : arr){
if(deque.isEmpty() || deque.peekLast() != num){
deque.addLast(num);
}
}
return deque;
}
}