본 게시물은 4개 중 마지막 게시물
Finish
1️⃣날짜와 시간
1) Java에서의 날짜와 시간
- 날짜/시간을 사용할 때 자주 쓰는 java.time 패키지
패키지(package)?
: 클래스의 묶음. 패키지에는 클래스 혹은 인터페이스를 포함가능하며, 관련 클래스끼리 묶어두어 클래스를 효율적으로 관리 가능하다.
public class Main {
public static void main(String[] args) {
System.out.println("now()를 활용하여 생성");
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(date);
System.out.println(time);
System.out.println(dateTime);
System.out.println("of()를 활용하여 생성");
LocalDate newDate = LocalDate.of(2021, 03, 29);
LocalTime newTime = LocalTime.of(22, 50, 55);
System.out.println(newDate);
System.out.println(newTime);
}
}
👉now() vs of()
두 가지 방법 모두 객체를 생성할 때 사용되며,
now()는 현재의 날짜 시간, of()는 지정하는 값이 필드에 담겨진다.
- LocalDate와 LocalTime은 java.time 패키지의 가장 기본이 되는 클래스
2) 날짜와 시간의 형식 수정
날짜와 시간을 출력하는 방법
출력문의 결과가 원하는 형식이 아닐 경우, 날짜/시간을 원하는 형식으로 출력할 수 있다.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
String shortFormat = formatter.format(LocalTime.now());
System.out.println(shortFormat);
→ LocalDate.now() 를 했을 때와는 다르게 오전/오후가 추가되었으며 보다 직관적인 형태가 된다
→ 형식을 변환하는데 사용한 DateTimeFormatter 클래스는 SHORT이외에도 다양한 FormatStyle 종류가 있다
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String myDate = newFormatter.format(LocalDate.now());
System.out.println(myDate);
→ ofPattern에 작성한 형식대로 날짜가 출력된다.
3) 날짜와 시간의 차이 계산
날짜와 시간 차이 계산 예제
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(2021, 8, 9);
Period period = Period.between(today, birthday);
System.out.println(period.getMonths());
System.out.println(period.getDays());
→ 오늘 일자와 생일 일자간의 날짜 차이를 계산하기 위해서는 between()을 사용하면 구할 수 있다.
(between() 이외에도 until()로 구할 수도 있다.)
퀴즈
오늘의 날짜와 시간을 [연도/월/일 시간/일자]의 형식으로 값으로 출력
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd h/mm");
String now = dateTimeFormatter.format(LocalDateTime.now());
System.out.println("현재시간: " + now);
}
}
2️⃣컬렉션
: 자료구조를 표현하는 인터페이스
1) 컬렉션 프레임워크란?
- 다수의 데이터를 다루기 위한 자료구조를 표현하고 사용하는 클래스의 집합
- 데이터를 다루는데 필요한 풍부하고 다양한 클래스와 기본함수를 제공하기 때문에 많이 유용하다.
- 컬렉션 프레임워크의 모든 클래스는 Collection interface를 구현(implement)하는 클래스 또는 인터페이스
2) 컬렉션 인터페이스와 자료구조
Collection은 모든 자료구조가 구현(implement)하는 인터페이스
모든 자료구조에 해당하는 클래스, 인터페이스 언제나 Collection 인터페이스 구현
1. List : 순서가 있는 데이터의 집합이며 데이터의 중복을 허용한다
→ ArrayList, LinkedList, Stack 등
2. Set : 순서를 유지하지 않는 데이터의 집합이며 데이터의 중복을 허용하지 않는다
→ HashSet, TreeSet 등
3. Map : 키(key)와 값(value)의 쌍으로 이루어진 데이터의 집합이다.
순서는 유지되지 않으며 키는 중복을 허용되지 않고 값은 중복을 허용한다.
→ HashMap, TreeMap 등
4. Stack : 마지막에 넣은 데이터를 먼저 꺼내는 자료구조 => LIFO(Last In First Out)
→ Stack, ArrayDeque 등
5. Queue : 먼저 넣은 데이터를 먼저 꺼내는 자료구조 => FIFO(First In First Out)
→ Queue, ArrayDeque 등
컬렉션 인터페이스
=> 컬렉션 클래스에 저장된 데이터를 읽고, 추가하고 삭제하는 등 데이터를 다루는데 기본적인 메소드들을 정의
3️⃣컬렉션 - 리스트, 셋, 맵
1)List
순서가 있는 나열된 데이터를 표현
- ArrayList는 배열을 이용하여 데이터를 저장하는 List 인터페이스
public class Main {
public static void main(String[] args) {
List list = new ArrayList(10);
list.add(1);
list.add(5);
list.add(4);
list.add(11);
list.add(10); // ArrayList에 값 한개씩 입력
System.out.println(list); // [1,5,4,11,10]
Collections.sort(list); // list 정렬
System.out.println(list); // [1,4,5,10,11]
System.out.println(list.size()); // arrayList의 크기 출력
arrayList.remove(4); // 인덱스를 활용하여 해당하는 값 제거
System.out.println(list);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i)); // get을 이용하여 값 1개씩 출력
}
for (int current : list) {
System.out.println(current);
}
}
}
2) Set
순서를 유지하지 않는 데이터의 집합이며 데이터의 중복을 허용
- HashSet은 Set 인터페이스를 구현한 대표적인 컬렉션
해당 예제는 스파르타 코딩클럽의 예시임
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> integerSet = new HashSet<>(); // Collection의 자료형에는 primitive 타입은 올 수 없습니다. primitive 타입에 해당하는 class 가 있으니 사용할 것
integerSet.add(1);
integerSet.add(3);
integerSet.add(2);
integerSet.add(9);// 하나씩 값을 삽입
System.out.println(integerSet); // 출력을 해보면 순서가 지켜지지 않는 것을 알 수 있다.
Set<String> stringSet = new HashSet<>();
stringSet.add("LA");
stringSet.add("New York");
stringSet.add("LasVegas");
stringSet.add("San Francisco");
stringSet.add("Seoul");
System.out.println(stringSet);
stringSet.remove("Seoul"); //Seoul을 HashSet에서 제거
System.out.println(stringSet);
ArrayList<String> target = new ArrayList<String>();
target.add("New York");
target.add("LasVegas");//제거할 항목을 ArrayList에 삽입
stringSet.removeAll(target);//제거항목에 삽입된 도시들을 삭제
System.out.println(stringSet);
System.out.println("LA가 포함돼 있는가? " + stringSet.contains("LA"));
System.out.println("LA가 포함돼 있는가? " + stringSet.contains("LasVegas"));
//LA가 HashSet에 포함되어있으면 true를, 그렇지 않으면 false를 반환
System.out.println("현재 HashSet의 크기는 : " + stringSet.size() + "입니다.");
//HashSet의 크기를 반환
stringSet.clear();//HashSet의 모든 아이템들을 삭제
System.out.println(stringSet);
}
}
3) Map
- HashMap은 키(key)와 값(value)을 하나의 데이터로 저장하는 특징
해싱(hashing)을 가능하게 하여 데이터를 검색하는데 뛰어난 성능을 보인다
선언부분에 <> 표시는 Generics표시이다
HashMap 예제
public class Main {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "apple");
map.put(2, "berry");
map.put(3, "cherry");
System.out.println(map);
System.out.println("1st in map: " + map.get(1));
map.remove(2);
System.out.println(map);
System.out.println(map.containsKey(2));
System.out.println(map.containsValue("cherry"));
map.clear();
System.out.println(map);
}
}
4️⃣ 컬렉션 - 스택, 큐, ArrayDeque
1)스택
- 스택이란(stack)
- 스택은 마지막에 저장한 데이터를 먼저 꺼내는 자료구조
- LIFO(Last In First Out)
- 스택의 예
- 웹브라우저의 앞페이지 이동 뒤페이지 이동/그릇 쌓기
Stack 예제
해당 예제는 스파르타 코딩클럽의 예시임을 알림
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> integerSet = new HashSet<>(); // Collection의 자료형에는 primitive 타입은 올 수 없습니다. primitive 타입에 해당하는 class 가 있으니 사용할 것
integerSet.add(1);
integerSet.add(3);
integerSet.add(2);
integerSet.add(9);// 하나씩 값을 삽입
System.out.println(integerSet); // 출력을 해보면 순서가 지켜지지 않는 것을 알 수 있다.
Set<String> stringSet = new HashSet<>();
stringSet.add("LA");
stringSet.add("New York");
stringSet.add("LasVegas");
stringSet.add("San Francisco");
stringSet.add("Seoul");
System.out.println(stringSet);
stringSet.remove("Seoul"); //Seoul을 HashSet에서 제거
System.out.println(stringSet);
ArrayList<String> target = new ArrayList<String>();
target.add("New York");
target.add("LasVegas");//제거할 항목을 ArrayList에 삽입
stringSet.removeAll(target);//제거항목에 삽입된 도시들을 삭제
System.out.println(stringSet);
System.out.println("LA가 포함돼 있는가? " + stringSet.contains("LA"));
System.out.println("LA가 포함돼 있는가? " + stringSet.contains("LasVegas"));
//LA가 HashSet에 포함되어있으면 true를, 그렇지 않으면 false를 반환
System.out.println("현재 HashSet의 크기는 : " + stringSet.size() + "입니다.");
//HashSet의 크기를 반환
stringSet.clear();//HashSet의 모든 아이템들을 삭제
System.out.println(stringSet);
}
}
2) 큐
- 큐(queue)
- 큐는 처음에 저장한 데이터를 가장 먼저 꺼내게 되는 FIFO(First In First Out)
- ex) 은행 창구 줄서기 / 인쇄작업 대기목록
- 양 쪽 끝의 통로가 뚫려있다고 생각하게 된다. 가장 먼저 들어온 Data가 반환이 될때도 가장 먼저 반환된다.
- 우선순위 큐, 원형 우선순위 큐, 원형 큐 등 다양하게 존재한다.
해당 예제는 스파르타 코딩클럽의 예시임을 알림
public class Main {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
queue.add(1);
queue.add(3);
queue.add(5);//Queue에 값 삽입합니다.
System.out.println(queue);//Queue 출력합니다.
System.out.println(queue.poll()); // Queue에서 객체를 꺼내서 반환합니다.
queue.add(7);
queue.add(11);
queue.add(9);
System.out.println(queue);
System.out.println(queue.peek()); //Queue에서 삭제 없이 요소를 반환합니다.
System.out.println(queue);
}
}
3) ArrayDeque
- deque
- 큐는 한쪽에서만 값이 삽입되고 다른 한쪽에서만 값을 반환하는 자료구조다
deque의 경우 양 끝에서 삽입과 반환이 가능하다
- 양 끝에서 삽입과 삭제가 이뤄진다.
public class Main {
public static void main(String[] args) {
ArrayDeque<Integer> arrayDeque = new ArrayDeque<>(); // ArrayDeque를 이용한 선언(제네릭스 이용)
arrayDeque.addFirst(1);
arrayDeque.addFirst(2);
arrayDeque.addFirst(3);
arrayDeque.addFirst(4); // arrayDeque의 앞에 값을 삽입
System.out.println(arrayDeque);
arrayDeque.addLast(0); // arrayDeque의 끝에 값을 삽입
System.out.println(arrayDeque);
arrayDeque.offerFirst(10); // addFirst와 비슷하지만 큐의 크기 문제가 생길 때, offerFirst는 false를,
// addFrist는 exception을 반환합니다.
System.out.println(arrayDeque);
arrayDeque.offerLast(-1); // arrayDeque의 끝에 값을 삽입
System.out.println(arrayDeque);
System.out.println(arrayDeque.size()); // 7
System.out.println(arrayDeque.removeFirst()); // 첫번째 값을 제거하면서 그 값을 리턴
System.out.println(arrayDeque.removeLast()); // 마지막 값을 제거하면서 그 값을 리턴
System.out.println(arrayDeque);
System.out.println(arrayDeque.size()); // 5
System.out.println(arrayDeque.pollFirst()); // 첫번째 값을 반환 및 제거하면서 그 값을 리턴
System.out.println(arrayDeque);
System.out.println(arrayDeque.size()); // 4
System.out.println(arrayDeque.pollLast()); // 마지막 값을 반환 및 제거하면서 그 값을 리턴
System.out.println(arrayDeque);
System.out.println(arrayDeque.size()); // 3
System.out.println(arrayDeque.peekFirst()); // 첫번째 값을 반환, 제거하지 않음
System.out.println(arrayDeque.peekLast()); // 마지막 값을 반환, 제거하지 않음
System.out.println(arrayDeque.size()); // 3
}
}
5️⃣ 제네릭스
1) 제네릭스(Generics)란?
- 다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능
근데 왜 쓰는데?
→ 객체의 타입을 컴파일 시에 체크하기 때문에 안정성이 높아진다.
(의도하지 않은 타입의 객체가 저장되는 것을 막고 잘못된 형변환을 막을 수 있다.)
2) 제네릭스의 형식과 약어
- 제네릭스의 형식
public class 클래스명<T> {...}
public interface 인터페이스명<T> {...}
- 자주 사용되는 타입인자 약어
- <T> == Type
- <E> == Element
- <K> == Key
- <V> == Value
- <N> == Number
- <R> == Result
3) 제네릭스를 활용한 예제
- 제네릭스를 사용한 예제는 Collection(또는 Collection을 구현한 다른 자료구조들)이다
Collection.java 일부
public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
Iterator<E> iterator();
boolean add(E e);
<T> T[] toArray(T[] a);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
}
List.java 일부
public interface List<E> extends Collection<E> {
// Collection 에 있는 메소드들 모두 포함
// + List 에만 있는 메소드들
boolean add(E e);
}
ArrayList.java 일부
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
}
제네릭스를 활용하면 동작은 같으나 클래스 타입이 바뀌어야 다룰 수 있다.
제네릭스를 통해 컴파일 언어어의 특징인 타입 안정성을 보장하면서도 유연한 프로그램을 작성가능하다.
6️⃣ 람다
단순하게 표현하는데 유용한 개념
1) 람다식(Lambda expression)이란?
→ "식별자 없이 실행 가능한 함수"라고 말할 수 있습니다.
즉, 함수의 이름을 따로 정의하지 않아도 곧바로 함수처럼 사용할 수 있는 것입니다.
문법이 간결하여 보다 편리한 방식입니다. (익명 함수라고도 부릅니다.)
→ 람다식이 코드를 보다 간결하게 만들어주는 역할을 하나 장점만 있지는 않다.
그럼 뭐가 단점일까?
→ 람다를 사용해서 만든 익명함수는 재사용이 불가능하다
→ 람다만을 사용할 경우 비슷한 메소드를 중복되게 생성할 가능성이 있어 지저분해질 수 있다
2) 람다식의 형식
: '→'의 의미는 매개변수를 활용하여 {}안에 있는 코드를 실행
위의 형식을 바탕으로 만든 예제이다
public class Main {
public static void main(String[] args) {
ArrayList<String> strList = new ArrayList<>(Arrays.asList("korea", "japan", "china", "france", "england"));
Stream<String> stream = strList.stream();
stream.map(str -> str.toUpperCase()).forEach(System.out::println);
}
}
3) 이중 콜론 연산자
public class Main {
public static void main(String[] args) {
List<String> cities = Arrays.asList("서울", "부산", "속초", "수원", "대구");
cities.forEach(System.out::println);
}
}
위의 예제에서 ::가 사용되었다. 자주 사용되는 람다 표현식으로 ::(이중 콜론 연산자)
-이중 콜론 연산자는 매개변수를 중복해 사용하고 싶지 않을 때 사용된다.
출력결과처럼 cities가 하나씩 출력된다
즉, cities.forEach(x -> System.out.println(x)); 와 같은 의미.
7️⃣ 스트림
: 컬렉션의 저장 요소를 하나씩 참조해 람다식으로 처리 가능하도록 해주는 반복자
(데이터의 흐름)
스트림을 활용해 필터링, 데이터 변경, 다른 타입이나 자료구조로 변환가능
스트림의 특징
- 데이터 소스를 변경하지 않는다
- 작업을 내부적으로 반복 처리한다
- 컬렉션의 요소를 모두 읽고 나면 닫혀 재사용이 불가하다.그래서 필요할 경우 재생성을 해야한다.
스트림의 구조
1. 스트림 생성
-스트림을 이용하기 위해 먼저 스트림을 생성해야한다
-Stream<T> Collection.stream()를 이용하여 해당하는 컬렉션을 기반으로하는 스트림을 생성가능하다
2. 중간 연산
- 중간 단계로써 데이터의 형변환 혹은 필터링, 정렬 등 스트림에 대한 가공을 해준다
- map(변환)/ sorted(정렬)/ skip(스트림 자르기)/ limit(스트림 자르기) 등이 있다.
3. 최종 연산
- 스트림의 요소를 소모해 결과를 반환하는 단계.최종 연산 후 스트림이 닫히고 더 이상 사용 불가
- 최종 연산의 결과값은 단일 값이거나 배열 혹은 컬렉션일 수 있다
- collect()를 이용해 다른 콜렉션으로 바꾸는 것, reduce를 이용해 incremental calculation하는 것도 많이 쓰이는 패턴
스트림의 연산은 다양하여 공부를 하며 필요할 때 적절한 연산에 익혀야한다.
일부 이해 안되는 부분은 코드 추가 구현 예정
8️⃣ 네트워킹 - Retrofit, OpenAPI
1) 네트워킹(Networking)
- 두 대이상의 컴퓨터를 케이블 또는 인터넷으로 연결해 네트워크를 구성하는 것
2) 네트워크의 기본 개념
- 클라이언트(Client) / 서버(Server) (컴퓨터간의 관계를 역할로 구분)
- 서버: 서비스를 제공하는 컴퓨터, 요청에 응답하는 컴퓨터
- 클라이언트 : 서비스를 사용하게 되는 컴퓨터, 요청을 하는 컴퓨터
🔔IP 주소가 뭐야?
- 컴퓨터를 구별하는데 사용되는 고유한 값으로 인터넷이 연결된 모든 컴퓨터는 IP주소를 갖는다
확인하는 방법은 윈도우는 cmd창을, 맥은 terminal을 통해 "ipconfig"를 입력하자.
직접해보는 것이 좋다
🔔URL(Uniform Resource Locator)이 뭐야?
- URL은 인터넷에 존재하는 여러 서버들이 제공하는 자원에 접근할 수 있는 주소를 표현하기 위함
(네이버, 구글을 검색할 때도 URL을 이용해 접근을 하는 것)
- URL의 형식
'프로토콜://호스트명:포트번호/경로명/파일명?쿼리스트링#참조' 의 형식
->프로토콜은 복수의 컴퓨터 사이에 데이터 통신을 원활하게 하기 위해 필요한 통신 규약을 의미
-포트번호
: 통신에 사용되는 서버의 포트번호
포트(port)가 그럼 뭘까?
이름 그대로 항구처럼 포트도 외부의 다른 장비와 접촉하기 위한 플러그의 역할을 한다.
포트번호는 어떤 프로그램에 접속 할 것인지를 식별하는 역할이다.
입력을 아무것도 하지 않으면 http는 80번, https는 443번이 default이다.
🔔API(Application Programming Interface)
응용 프로그램에서 사용가능하게 운영체제나 프로그래밍 언어가 제공하는 기능을 제어가능하게 해주는 인터페이스
client-server관점에서 API는 요청과 응답의 형식에 대한 약속
3) Retrofit 라이브러리를 활용하여 API 호출하기
TCP와 UDP
TCP/IP 프로토콜은 시스템간의 통신을 위한 표준 프로토콜, 프로토콜의 집합
TCP와 UDP 역시 이 TCP/IP 프로토콜에 포함되며 OSI 7계층의 전송계층에 해당
TCP
: 데이터를 전송전 상대방의 연결을 확인 후 데이터를 전송, 결과를 확인하며 수신이 제대로 되지 않을 경우 재전송을 실시
UDP
: 상대편과 연결하지 않고 데이터를 전송, 데이터가 제대로 수신되었는지를 확인하지 않아 신뢰성이 형성되지 않는다
추가적인 내용은 OSI 7 LAYER에 대해 공부 후 추가 작성하도록 하겠다.
'Language & Framework & GIT > JAVA' 카테고리의 다른 글
[JAVA] List ? ArrayList? #2 (0) | 2022.12.20 |
---|---|
[JAVA] List ? ArrayList? #1 (0) | 2022.12.14 |
[언어공부] 코테를 위한 JAVA 뽀개기 #3 (0) | 2022.10.28 |
[JAVA] this / super (0) | 2022.10.22 |
[JAVA] 오버로딩과 오버라이딩 (0) | 2022.10.22 |
댓글