⦁ 스택과 큐(Stack & Queue)
▶ 스택(Stack) : LIFO(Last In First Out)구조. 마지막에 저장된 것을 제일 먼저 꺼내게 된다.
밑이 막힌 상자안에 물건을 쌓는 구조. 위로만 넣고 빼는 것이 가능하기 때문에 마지막에 저장(push)한 것이 가장 먼저 추출(pop) 된다.

▶ 큐(Queue) : FIFO(First In First Out) 구조. 제일 먼저 저장(offer)한 것을 제일 먼저 추출(poll)하게 된다.

⦁ 스택과 큐(Stack & Queue)의 메소드
- Stack (Stack은 클래스다. 평범하게 객체 생성 가능)

* search 메소드 사용시, Stack의 맨 위가 index 1이고, 쭉 아래로 오름차순임
- Queue (Queue는 인터페이스다. Queue를 구현한 클래스를 이용해 객체를 생성해야함)

* add, remove는 비어있으면 예외가 발생하지만 poll, peek은 null을 반환함
⦁ Queue 인터페이스를 구현한 클래스 찾기
Java API에 들어가서 Queue 인터페이스를 찾는다 -> Queue 인터페이스를 구현한 클래스를 찾는다 -> 다형성을 이용해서 Queue객체를 생성한다.
ex) Queue q = new LinkedList();
ex)
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class Ex11_2 {
public static void main(String[] args) {
Stack st = new Stack();
Queue q = new LinkedList(); // Queue인터페이스의 구현체인 LinkedList를 사용
st.push("0");
st.push("1");
st.push("2");
q.offer("0");
q.offer("1");
q.offer("2");
System.out.println("= Stack =");
while(!st.empty()) { // 비었는지 확인
System.out.println(st.pop()); // 스택에서 요소 하나를 꺼내서 출력
}
System.out.println("= Queue =");
while(!q.isEmpty()) { // 비었는지 확인
System.out.println(q.poll()); // 큐에서 요소 하나를 꺼내서 출력
}
}
}
⦁ 스택과 큐(Stack & Queue)의 활용
스택의 활용 예 – 수식계산, 수식괄호검사, 워드프로세서의 undo/redo, 웹브라우저의 뒤로/앞으로
큐의 활용 예 – 최근사용문서, 인쇄작업 대기목록, 버퍼(buffer)
ex)
import java.util.EmptyStackException;
import java.util.Stack;
public class Ex11_3 {
public static void main(String[] args) {
if (args.length!=1) {
System.out.println("Usage:java Ex11_3 \"EXPRESSION\"");
System.out.println("Example:java Ex11_3 \"((2+3)*1)+3\"");
System.exit(0);
}
Stack st = new Stack();
String expression = args[0];
System.out.println("expression: " + expression);
try {
for (int i=0; i<expression.length(); i++) {
char ch = expression.charAt(i);
if (ch == '(') {
st.push(ch + "");
} else if (ch==')') {
st.pop();
}
}
if (st.isEmpty()) {
System.out.println("괄호가 일치합니다.");
} else {
System.out.println("괄호가 일치하지 않습니다.");
}
} catch (EmptyStackException e) {
System.out.println("괄호가 일치하지 않습니다.");
} // try-catch의 끝
}
}
ex)
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Queue;
import java.util.Scanner;
public class Ex11_4 {
static Queue q = new LinkedList();
static final int MAX_SIZE = 5; // Queue에 최대 5개까지만 저장되도록 한다.
public static void save(String input) {
// queue에 저장한다.
if(!"".equals(input)) // if(input!=null && !input.equals("")
q.offer(input);
// queue의 최대크기를 넘으면 제일 처음 입력된 것을 삭제한다.
if(q.size() > MAX_SIZE) // size()는 Collection인터페이스에 정의
q.remove(); // q.poll()도 쓸 수 있음.
}
public static void main(String[] args) {
System.out.println("help를 입력하면 도움말을 볼 수 있습니다.");
while(true) {
System.out.println(">>");
try {
// 화면으로부터 라인단위로 입력받는다.
Scanner sc = new Scanner(System.in);
String input = sc.nextLine().trim(); // trim은 앞뒤에 있는 공백 삭제
if ("".equals(input)) continue;
if(input.equalsIgnoreCase("q")) {
System.exit(0);
} else if (input.equalsIgnoreCase("help")) {
System.out.println(" help - 도움말을 보여줍니다.");
System.out.println(" q 또는 Q - 프로그램을 종료합니다.");
System.out.println(" history - 최근에 입력한 명령어를 "+MAX_SIZE+"개 보여줍니다.");
} else if (input.equalsIgnoreCase("history")) {
save(input); // 입력받은 명령어를 저장하고,
// LinkedList의 내용을 보여준다.
LinkedList list = (LinkedList)q;
final int SIZE = list.size();
for(int i=0; i<SIZE; i++)
System.out.println((i+1)+"."+list.get(i));
} else {
save(input);
System.out.println(input);
} // if(input.equalsIgnoreCase("q")) {
} catch(Exception e) {
System.out.println("입력오류입니다.");
}
} // while(true) 끝
} // main()
}
⦁ Iterator, ListIterator, Enumeration
- 컬렉션에 저장된 데이터를 접근하는데 사용되는 인터페이스 (읽어오기)
핵심 메소드)
hasNext() : 읽어올 요소가 남아있는지 확인한다. 있으면 true, 없으면 false를 반환한다.
next() : 다음 요소를 읽어온다. next()를 호출하기 전에 hasNext()를 호출해서 읽어올 요소가 있는지 확인하는 것이 안전하다.
- Enumeration은 Iterator의 구버전
Enumeration의 핵심메소드)
hasMoreElements() (Iterator의 hasNext()와 같음)
nextElement() (Iterator의 next()와 같음)
- ListIterator는 Iterator의 접근성을 향상시킨 것(단방향 -> 양방향)
- Iterator
컬렉션에 저장된 요소들을 읽어오는 방법을 표준화 한 것
- Iterator 사용방법
List list = new ArrayList(); // 다른 컬렉션으로 변경할 때는 이 부분만 고치면 된다.
Iterator it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
ex)
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Ex11_5 {
public static void main(String[] args) {
// Collection의 메소드만 사용하고 있다면, 객체가 바뀌어도 뒤에 있는 코드들을 수정하지 않을 수 있어서 좋음.
Collection c = new ArrayList();
// ArrayList list = new ArrayList(); 참조변수를 ArrayList로 고정해놓으면 객체가 바뀌는 경우
// 코드들을 무조건 수정해줘야 해서 번거로울 수 있음.
c.add("1");
c.add("2");
c.add("3");
c.add("4");
c.add("5");
Iterator it = c.iterator(); // iterator는 Collection을 구현한 클래스에서 모두 사용 가능
while(it.hasNext()) {
Object obj = it.next();
System.out.println(obj);
}
// for (int i=0; i<list.size(); i++) {
// System.out.println(list.get(i));
// }
}
}
⦁ Map과 Iterator
- Map에는 iterator()가 없다.
Map map = new HashMap();
Iterator it = map.entrySet().iterator();
⦁ Arrays – 배열을 다루기 편리한 메소드(static) 제공
1. 배열의 출력 – toString()
static String toString(boolean[] a)
static String toString(byte[] a)
static String toString(char[] a)
static String toString(short[] a)
static String toString(int[] a)
static String toString(long[] a)
static String toString(float[] a)
static String toString(double[] a)
static String toString(Object[] a)
2. 배열의 복사 – copyOf(), copyOfRange()
int[] arr = {0,1,2,3,4};
int[] arr2 = Arrays.copyOf(arr, arr.length); // arr2 = [0,1,2,3,4]
int[] arr3 = Arrays.copyOf(arr, 3); // arr3 = [0,1,2]
int[] arr4 = Arrays.copyOf(arr, 7); // arr4 = [0,1,2,3,4,0,0]
int[] arr5 = Arrays.copyOfRange(arr, 2, 4); // arr5 = [2,3]
int[] arr6 = Arrays.copyOfRange(arr, 0, 7); // arr6 = [0,1,2,3,4,0,0]
3. 배열 채우기 – fill(), setAll()
int[] arr = new int[5];
Arrays.fill(arr, 9); // arr=[9,9,9,9,9]
Arrays.setAll(arr, (i) -> (int)(Math.random()*5)+1); // arr=[1,5,2,1,1]
4. 배열의 정렬과 검색 – sort(), binarySearch() (이진탐색)
int[] arr = [3,2,0,1,4];
int idx = Arrays.binarySearch(arr, 2); // idx=-5 <- 잘못된 결과, 정렬이 되어있어야 함.
Arrays.sort(arr); // 배열 arr을 정렬한다.
System.out.println(Arrays.toString(arr)); // [0,1,2,3,4]
int idx = Arrays.binarySearch(arr, 2); // idx=2 <- 올바른 결과.
5. 다차원 배열의 출력 – deepToString()
int[] arr = {0,1,2,3,4};
int[][] arr2D = {{11,12}, {21,22}};
System.out.println(Arrays.toString(arr)); // [0, 1, 2, 3, 4]
System.out.println(Arrays.deepToString(arr2D)); // [[11,12], [21, 22]]
6. 다차원 배열의 비교 – deepEquals()
String[][] str2D = new String[][]{{“aaa”,“bbb”},{“AAA”,“BBB”}};
String[][] str2D2 = new String[][]{{“aaa”,“bbb”},{“AAA”,“BBB”}};
System.out.println(Arrays.equals(str2D, str2D2)); // false
System.out.println(Arrays.deepEquals(str2D, str2D2)); // true
7. 배열을 List로 변환 – asList(Object... a) 가변 매개변수 – 개수가 정해져있지 않음
List list = Arrays.asList(new Integer[]{1,2,3,4,5}); // list = [1, 2, 3, 4, 5]
List list = Arrays.asList(1,2,3,4,5);
list.add(6); // UnsupportedOperationException 예외 발생, 지원하지 않는 기능
// (이 list는 읽기전용이라 변경이 안 됨)
List list = new ArrayList(Arrays.asList(1,2,3,4,5)); // 새로운 ArrayList 생성
// (이 list는 변경이 가능)
8. 람다와 스트림(14장)관련 – parallelXXX(), spliterator(), stream()
ex)
import java.util.Arrays;
public class Ex11_6 {
public static void main(String[] args) {
int[] arr = {0,1,2,3,4};
int[][] arr2D = {{11,12,13}, {21,22,23}};
System.out.println("arr="+Arrays.toString(arr));
System.out.println("arr2D="+Arrays.deepToString(arr2D));
int[] arr2 = Arrays.copyOf(arr, arr.length);
int[] arr3 = Arrays.copyOf(arr, 3);
int[] arr4 = Arrays.copyOf(arr, 7);
int[] arr5 = Arrays.copyOfRange(arr, 2, 4);
int[] arr6 = Arrays.copyOfRange(arr, 0, 7);
System.out.println("arr2="+Arrays.toString(arr2));
System.out.println("arr3="+Arrays.toString(arr3));
System.out.println("arr4="+Arrays.toString(arr4));
System.out.println("arr5="+Arrays.toString(arr5));
System.out.println("arr6="+Arrays.toString(arr6));
int[] arr7 = new int[5];
Arrays.fill(arr7, 9); // arr=[9,9,9,9,9]
System.out.println("arr7="+Arrays.toString(arr7));
Arrays.setAll(arr7, i -> (int)(Math.random()*6)+1);
System.out.println("arr7="+Arrays.toString(arr7));
for(int i : arr7) { // 향상된 for문
// for(int x=0; x<arr7.length; x++) {
// int i = arr7[x];
char[] graph = new char[i];
Arrays.fill(graph, '*');
System.out.println(new String(graph)+i); // String->char[] 는 tocharArray() 이용
} // char[]->String 는 new String(char[]) 이용(생성자 이용)
String[][] str2D = new String[][] {{"aaa","bbb"},{"AAA","BBB"}};
String[][] str2D2 = new String[][] {{"aaa","bbb"},{"AAA","BBB"}};
System.out.println(Arrays.equals(str2D, str2D2)); // false
System.out.println(Arrays.deepEquals(str2D, str2D2)); // true
char[] chArr = {'A', 'D', 'C', 'B', 'E'};
System.out.println("chArr="+Arrays.toString(chArr));
System.out.println("index of B ="+Arrays.binarySearch(chArr, 'B'));
System.out.println("= After sorting =");
Arrays.sort(chArr); // binarySearch를 하기 전에는 반드시 정렬 먼저 해야 함.
System.out.println("chArr="+Arrays.toString(chArr));
System.out.println("index of B ="+Arrays.binarySearch(chArr, 'B'));
}
}
출처 - 유튜브 남궁성의 정석코딩 [자바의 정석 - 기초편]
'Java > Java의 정석' 카테고리의 다른 글
220323 Java - Chapter.12 지네릭스, 열거형, 애너테이션 Part.1 (0) | 2022.03.23 |
---|---|
220322 Java - Chapter.11 Collections Framework Part.3 (0) | 2022.03.23 |
220319 Java - Chapter 11. Collections Framework Part.1 (0) | 2022.03.19 |
220316 Java - Chapter 10. 날짜와 시간 & 형식화 (0) | 2022.03.17 |
220315 Java - Chapter 9. java.lang패키지와 유용한 클래스 (0) | 2022.03.15 |