서론
4주차 - (4/8 ~ 4/14)
한 달이 지나 조금씩 적응이 되는 시기입니다. 많은 것을 배웠고, 힘든 부분도 많았지만 하나 씩 차근차근 풀어나가야 하는 시간인 것 같습니다.
1. 내용정리
[입출력 (IO)]
- 외부 데이터와 연결된 길 - 스트림(stream)
- 자바 객체를 파일에 저장(직렬화) 할 수 있게 해주는 클래스입니다.
- 그런데 파일에 쓸 때 '헤더(header)'라는 정보를 자동으로 먼저 씁니다.
이 헤더는 ObjectInputStream이 나중에 읽을 때 "이건 자바 직렬화된 파일이야!" 하고 인식하게 도와주는 정보예요.
- InputStream/OutputStream: 1바이트 단위 입출력
- Reader/Writer: 문자(2~3바이트) 단위 입출력
- MS949 → 한글 2바이트
- UTF-8 → 한글 3바이트
직렬화(Serialization)란?
- Library 만들어주고, 직렬화 데이터 주고받기
- +++ 객체를 바이트 형태로 변환하는 작업입니다. 이렇게 변환된 바이트는 파일에 저장하거나 네트워크를 통해 전송할 수 있습니다. 나중에 다시 역직렬화(Deserialization)하면, 객체를 원래의 상태로 복원할 수 있습니다.
예외처리
- 런타임만 왜 던지는가? 무한루프에 빠지니까 catch로 잡아서 쓸 수 있어서
- catch (EOFException e) 작성하고 예외 나오는데 finally
- flush() : 버퍼에 있는 데이터를 강제로 출력 대상에 전송하고, 비워주는 용도
직렬화(Serialization)란?
- Library 만들어주고, 직렬화 데이터 주고받기
- 객체를 바이트 형태로 변환하는 작업, 역직렬화를 통해 복원 가능
[스트림 (Stream)]
- Stream은 크게 생성-가공-결과로 나뉨
- 일반 배열을 순서로 바꾸고 싶으면 Stream을 사용
- 배열 생성 후 stream() 사용
- 기타메소드
range(시작값, 종료값) : 시작값부터 1씩 증가하는 숫자로 종료값 전까지 범위의 스트림생성
OptionalXXX : 값이 있을 수도 있고, 없을 수도 있는 객체 상자 (null일 수도 있는 값)
getAsXXX : Optional에서 값을 꺼낼 때 사용
스트림 :: 참조식 : 스트림에서 자주 쓰이는 map(), forEach(), filter() 등에서 함수 대입처럼 사용
스트림 생성
- stream() : 배열, 컬렉션 스트림생성에 사용 / Stream (문자열 스트림)
- Arrays.stream() : 배열 스트림으로 변환 (스트림 생성)
- Arrays.asList() : 배열을 List로 변환 (컬렉션 생성)
- Stream.of(값1, 값2, 값3, ...) : 값이나 배열 등을 스트림으로 변환
- Stream.builder() : .add().build(); 를 통해 직접 값을 넣을 수 있음
- Stream().iterate() : 수열 형태로 스트림을 생성
- Stream.concat(A, B) : 스트림 합치기
스트림 가공
- range() : 시작값부터 1씩 증가하는 숫자로 종료값 전까지 범위의 스트림생성
- filter: 특정 데이터만 필터링 / boolean으로 리턴
- map() : 데이터를 가공(변환)하여 나타냄
- flatmap() : 한 단계 제거하고 단일 컬렉션으로 만듬
- sorted() : 인자가 없어도 호출이 가능
스트림 결과
- collect() : Collector타입을 받아서 처리 /
- Collectors.toList() : 리스트
- Collectors.joining() : 구분자를 통하여 처리
- sorted() : 데이터 정렬
- reduce() : 스트림에 있는 데이터들의 총합을 계산
- Matching() : anymatch( or형태 ), allMatch ( and ), contains (문자 매치) / 일치시 boolean형태로 반환
제너릭
제네릭은 데이터의 타입을 일반화한다는 의미를 가진다.
제네릭스를 활용하는 제네릭 클래스는 제네릭 타입(T, E, K, V)을 활용하여 하나의 클래스로 해당 제네릭 타입에 변화를 줘서 제네릭 클래스의 인스턴스를 다양한 타입을 지닌 인스턴스로 활용
와일드 카드
- : 모든 타입을 허용하는 와일드 카드
- : T 타입 또는 T의 하위 타입을 허용하는 와일드 카드
- : T 타입 또는 T의 상위 타입을 허용하는 와일드 카드
List
- List 계열의 클래스는 중복 저장을 허용
- Comparator를 활용
- 양수일 때만 반환
- 익명 클래스
ArrayList
- DB에 넣어줄 것
- 단일값 비교, 정렬 기준을 구현하는데 사용
List에서 compareTo()로 단일값 비교할 떄 사용
comparable 에서 String에 있는걸 가져다 사용
- 인덱스로 데이터에 접근 가능하여 조회 기능적으로 뛰어남
LinkedList
- toString()을 오버라이딩해서 전체 리스트 출력하기 좋음
- ArrayList와 달리 부분적인 요소 제거에 성능이 우수
- isEmpty()로 요소들이 비어있으면 true
Stack
- add(), get(), remove()
실상으로 push와 pop을 통해서 사용 해야한다.
구분을 할 때 어떤타입을 자료를 쌓아둘건지 stack과 arrayList로 사용
- peek() : 맨마지막(맨위에)
- pop() : 하나씩 꺼내 사용
- search() : 값이 어디에 있는지 확인
- add는 스택을 List<E(인터페이스>를 상속받고 있어 리스트 계열이라고 할 수 있다.
- 구조의 차이 : 방법이 다를뿐, 쓰임새가 다른 것
Queue
- 먼저 들어온 애가 먼저 나가는 특징을 가지고 있다.
- 이벤트 구조가 선행, 순서가 안맞음, 먼저나가게 해줘야하니까
- Deque : 양방향으로 나가게 할 수 있다. (ex LinkedList)
- 어떤 타입을 참조하는지에 따라 사용하는 범위가 달라짐
Set
- 정렬된 기준을 가지고 출력
- 순서는 정해져 있지 않지만 중복을 정의한다.
- 중복 허용하지 않는다는 것은 중복 저장을 허용하지 않는다는 뜻
- 중복객체를 넣어야 한다면 오버라이딩 해야한다?
- 값만 잘 들어가서 중복이 안되게끔만 하면 됨
- Iterrator를 활용해야 한다.
- HashMap 해시 테이블을 이용하여 데이터를 저장하는 구조
- TreeSet은 이진 검색
Map
- set으로 중복되지 않은 값을 get으로 들고와서
- Iterator(반복자)를 통해 목록화(흩어져있는 값을 줄세움)
- keySet() 키값만 가져오려고 했는데 그타입이 set
- set도 똑같음(산발적인건 똑같음) 근데 get을 쓸 수 없으니
- FileOutputStream / FileWriter / xml / (제이슨)
xml : tag요소들이 늘어면서 구분하기위한 구분자 역할이 있기 떄문에
제이슨 : 더 대용량
람다 (lamda)
- 함수형 인터페이스 람다식을 통해 익명 객체 구현
- 반드시 @FunctionalInterface 어노테이션이 붙은 함수형 인터페이스만 가능
- 함수형 인터페이스는 추상 메서드 1개만 가능
- 매개 변수 없는 경우 : () -> { ... }
- 매개 변수 있는 경우 : (타입 매개변수, ...) -> { ... }
함수형 인터페이스
- Runnable : 반환값 없음
- Consumer : 매개변수 o / 리턴값 x / accept() 메소드 사용
- Supplier : 매개변수 x / 리턴 값 o / getXXX() 메소드 사용
- Function : 매개변수 o / 리턴 값 o / applyXXX() 메소드 사용
(매개변수를 리턴 값으로 매핑하는 역할)
++ Function함수는 받는 타입, 반환 타입을 두 개 설정
- Operator : 매개변수로 연산한 후 통일 타입으로 반환
- Predicate : 매개변수를 활용하여 boolean타입으로 반환 / testXXX() 메소드 사용
리스트(List)
순서가 있는 데이터의 집합으로, 인덱스나 포인터로 접근할 수 있는 자료구조
- 배열 기반 리스트는 접근은 O(1)으로 바로 접근 가능하고 순차 접근이 용이하며
- 삽입은 O(n)으로 중간에 삽입 시 뒤의 요소를 모두 이동해야 함, 삭제도 마찬가지
- O(n) (동적으로 메모리 할당, 크기 제한 없음)
스택(stack)
LIFO(Last In, First Out) 방식으로 데이터 관리 자료구조
- 배열 기반 스택은 O(1)을 빠르게 통해 접근, 삽입, 삭제
- 연결 기반 스택도 접근 O(1) 항상 top 노드에서 접근 가능 / 삽입 O(1) 새로운 노드를 top으로 추가하면 되므로 빠름
- top = -1은 스택이 비어있음을 의미
- search(x) : 데이터 x가 스택의 몇 번째 위치에 있는지 반환
큐(Queue)
FIFO(First In, First Out) 방식으로 데이터를 관리하는 자료구조
- 배열기반 큐는 front와 rear 인덱스를 통해 데이터 접근
- offer(x): 데이터 x를 큐의 맨 뒤에 추가 (성공하면 true 반환, 실패 시 false 반환)
- poll(): 큐의 맨 앞 데이터를 제거하고 반환 (비어있으면 null 반환)
덱(Deque)
양쪽 끝에서 삽입과 삭제를 허용하는 자료구조
- 접근: O(1), 삽입: O(1), 삭제: O(1)
- offerXXXX(x) : 데이터 x를 덱에 추가
- removeXXXX(), pollXXXX() : 덱의 앞쪽(First), 뒤쪽(Last)에 제거하고 반환 (비어있으면 예외, null 반환)
- getXXXX(), peekXXXX() : 덱의 앞쪽(First), 뒤쪽(Last) 제거하지 않고 반환 (비어있으면 예외, null 반환)
[시간복잡도]
배열 (O1)
- 배열은 메모리에서 연속된 공간을 차지하기 떄문에 쉽게 구현 가능
선형 검색 (Linear Search) O(1), O(n)
- 배열의 첫 번째 요소부터 마지막 요소까지 순차적으로 검색
- 구현이 매우 간단하고, 배열이 정렬되어 있지 않아도 사용 가능
- 모든 배열에서 사용가능, 정렬된 배열에서도 가능
이진 검색 (Binary Search) O(1), O(log n)
- 배열이 정렬되어 있는 경우 매우 빠르게 요소를 찾을 수 있음 (반대로 정렬되어 있지 않으면 사용할 수 없음)
- 검색 시간이 배열은 크기에 대해 로그 함수로 증가하므로 예측이 가능 (대신 구현이 복잡)
피보나치 수열 (Fibonacci Sequence) / 재귀 함수 (Recursive Function)
재귀 함수로 피보나치 수열 구현
// 피보나치 수열을 계산하는 재귀 함수
public static int fibonacci(int n) {
// 기본 사례: n이 0 또는 1인 경우
if (n <= 1) {
return n;
}
// 재귀 사례: 피보나치 수열의 정의에 따라 계산
return fibonacci(n - 1) + fibonacci(n - 2);
}
공통 메소드
- isEmpty(): 비어 있는지 확인
- size(): 크기를 반환
- clear(): 비우기
리스트(List)
순서가 있는 데이터의 집합으로, 인덱스나 포인터로 접근할 수 있는 자료구조
- 배열 기반 리스트는 접근은 O(1)으로 바로 접근 가능하고 순차 접근이 용이하며
- 삽입은 O(n)으로 중간에 삽입 시 뒤의 요소를 모두 이동해야 함, 삭제도 마찬가지
- O(n) (동적으로 메모리 할당, 크기 제한 없음)
스택(stack)
LIFO(Last In, First Out) 방식으로 데이터 관리 자료구조
- 배열 기반 스택은 O(1)을 빠르게 통해 접근, 삽입, 삭제
- 연결 기반 스택도 접근 O(1) 항상 top 노드에서 접근 가능 / 삽입 O(1) 새로운 노드를 top으로 추가하면 되므로 빠름
- top = -1은 스택이 비어있음을 의미
- search(x) : 데이터 x가 스택의 몇 번째 위치에 있는지 반환
큐(Queue)
FIFO(First In, First Out) 방식으로 데이터를 관리하는 자료구조
- 배열기반 큐는 front와 rear 인덱스를 통해 데이터 접근
- offer(x): 데이터 x를 큐의 맨 뒤에 추가 (성공하면 true 반환, 실패 시 false 반환)
- poll(): 큐의 맨 앞 데이터를 제거하고 반환 (비어있으면 null 반환)
덱(Deque)
양쪽 끝에서 삽입과 삭제를 허용하는 자료구조
- 접근: O(1), 삽입: O(1), 삭제: O(1)
- offerXXXX(x) : 데이터 x를 덱에 추가
- removeXXXX(), pollXXXX() : 덱의 앞쪽(First), 뒤쪽(Last)에 제거하고 반환 (비어있으면 예외, null 반환)
- getXXXX(), peekXXXX() : 덱의 앞쪽(First), 뒤쪽(Last) 제거하지 않고 반환 (비어있으면 예외, null 반환)
test
- public을 쓸필요 없다
- 메소드명을 한글로 써도 사용할 수 있다.
2. 마무리
> 아쉬웠던 점
Task관리가 부적절했던 것 같습니다.
> 개선할 점
시간을 좀 더 활용하여 정리하는 습관이 필요한 것 같습니다.
> 다음주 계획
코딩테스트 PCCE 일정이 있습니다. 문제풀이에 시간을 좀 더 활용하겠습니다.
task관리에 좀 더 집중하겠습니다.