본문 바로가기
TIL

항해99_TIL220526 (제네릭, 스트림, 람다식)

by Hyeongjun_Ham 2022. 5. 26.

requestparam, repuestbody로 헷갈렸던게 GET,POST 방식을 잘 알지 못해서 더 헷갈렸던거 같다.

GET,POST방식 한번 더 찾아보고 읽었더니 조금 더 이해가 갔다.

오늘 이거저거 찾아보면서 하루에 접했던 내용을 담는거보다 접했던 것 중에 한 가지만 집중해서 글 쓰는게 좋을 것 같다고 생각이 들었다.

 

- 제네릭(Generic)

클래스 내부에서 사용할 데이터 타입을 외부에 지정하는 기법

타입이 안전해지지 않는 상황, 코드의 중복을 제거하는 두마리 토끼를 잡기 위해 사용한다.

장점

  • 컴파일 단계에서 오류가 검출된다.
  • 중복의 제거와 타입 안전성을 동시에 추구할 수 있게 되었다.

제네릭은 참조 데이터 타입에 대해서만 사용할 수 있다. 기본 데이터 타입에서는 사용할 수 없다.

 

- 스트림(Stream)

스트림은 '데이터의 흐름’입니다.

배열 또는 컬렉션 인스턴스에 함수 여러 개를 조합해서 원하는 결과를 필터링하고 가공된 결과를 얻을 수 있습니다.

또한 람다를 이용해서 코드의 양을 줄이고 간결하게 표현할 수 있습니다.

즉, 배열과 컬렉션을 함수형으로 처리할 수 있습니다.

또 하나의 장점은 간단하게 병렬처리(multi-threading)가 가능하다는 점입니다.

하나의 작업을 둘 이상의 작업으로 잘게 나눠서 동시에 진행하는 것을 병렬 처리(parallel processing)라고 합니다.

즉 쓰레드를 이용해 많은 요소들을 빠르게 처리할 수 있습니다.

스트림에 대한 내용은 크게 세 가지로 나눌 수 있습니다.

  1. 생성하기 : 스트림 인스턴스 생성.
  2. 가공하기 : 필터링(filtering) 및 맵핑(mapping) 등 원하는 결과를 만들어가는 중간 작업(intermediate operations).
  3. 결과 만들기 : 최종적으로 결과를 만들어내는 작업(terminal operations).

특징

  1. 데이터를 담고 있는 저장소 (컬렉션)이 아니다.
  2. 스트림은 원본 데이터 소스를 변경하지 않는다.(Read Only)
  3. 스트림은 lterator처럼 일회용이다. (필요하면 다시 스트림을 생성해야 함)
  4. 최종 연산 전까지 중간연산을 수행되지 않는다.(lazy) : 요청할때마다 값을 처리하고 넘겨주는 방법을 게으른 방법
  5. 무제한일 수도 있다. (Short Circuit 메소드를 사용해서 제한할 수 있다.)
  6. 손쉽게 병렬 처리할 수 있다. (멀티 쓰레드 사용) (.parallel)
  7. 기본형 스트림으로 IntStream, LongStream, DoubleStream등 제공
  8. 자료구조가 포함하는 모든 값을 메소드에 포함하는 컬렉션과 다르게, 스트림은 요청할 때만 요소를 계산하는 고정된 자료구조를 가진다.
  9. 스트림은 특정 연산자를 사용할 때여러개의 조건이 중첩된 상황에서 값이 결정나면 불필요한 연산을 진행하지 않고 조건문을 빠져나와 실행 속도를 높인다. 
    • 오토박싱 등의 불필요한 과정이 생략됨.
    • Stream<Integer> 대신에 IntStream을 사용하는게 더 효율적이다.
    • 뿐만 아니라 숫자의 경우 더 유용한 메서드를 Stream<T>보다 더 많이 제공한다.(.sum(), .averge() 등)

 

- Stream API 사용 예시

Filter(Predicate)

  • if문이라고 생각하면 될듯.
  • 람다식의 리턴값은 boolean. true면 다음 단계 진행, false면 버려짐
classes.stream()
	.filter(c->c.getTitle().startWith("spring"))
	.forEach(c->System.out.println(oc.getId));

classes.stream()
	.filter(Predicate.not(OnlineClass::isClosed))
	.forEach(c->System.out.println(oc.getId));
  • 예) 이름이 3글자 이상인 데이터만 새로운 스트림으로 변경하기

 

Map(Function) 또는 FlatMap(Function)

  • stream을 우리가 원하는 모양의 새로운 스트림으로 변환
    • 예) 각각의 File에서 String name만 새로운 스트림으로
    • 예) string 타입 요소를 짤라서 새로운 스트림으로
 map(File::getName)
 map(s->s.subString(3))

 

limit(long) 또는 skip(long)

  • 예) 최대 5개의 요소가 담긴 스트림을 리턴한다.
  • 예) 앞에서 3개를 뺀 나머지 스트림을 리턴한다.
Stream.iterate(10, i->i+1)
		.skip(10)
        .limit(10)
        .forEach(System.out::println)

anyMatch(), allMatch(), nonMatch()

  • 예) k를 포함한 문자열이 있는지 확인한다. (true 또는 false를 리턴한다.)
boolean test=javaClasses.stream()
				.anyMatch(oc->oc.getTitle().contains("k"));
  • 예) 스트림에 있는 모든 값이 10보다 작은지 확인한다.

findFirst() VS findAny()

  • 스트림을 직렬로 처리할 때는 차이가 없다.
  • 하지만 병렬로 처리할 경우에 차이가 생기는데,
    • findFirst()는 stream의 순서를 고려해, 가장 앞쪽에 있는 요소를 반환
    • findAny()는 멀티 쓰레드에서 가장 먼저 찾은 요소를 반환. stream의 뒤쪽에 있는 요소가 반환될 수도 있다.

reduce 자세히 보기

  • 스트림의 요소를 하나씩 줄여가며 누적연산 수행
  • reduce(초기값, (누적 변수, 요소)-> 수행문)
Integer sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
					.reduce((total, y) -> total + y);
System.out.println("sum: " + s); //sum: 55

//초기값을 지정해 줄 수 있다.
Integer sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
					.reduce(10, (total, n) -> total + n);
System.out.println("sum: " + sum); //sum: 65

 

출처 : https://futurecreator.github.io/2018/08/26/java-8-streams/

 

Java 스트림 Stream (1) 총정리

이번 포스트에서는 Java 8의 스트림(Stream)을 살펴봅니다. 총 두 개의 포스트로, 기본적인 내용을 총정리하는 이번 포스트와 좀 더 고급 내용을 다루는 다음 포스트로 나뉘어져 있습니다. Java 스트

futurecreator.github.io

출처 : https://velog.io/@gmtmoney2357/%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%8A%B8%EB%A6%BCStream

 

자바 - 스트림(Stream)

본 게시물은 스스로의 공부를 위한 글입니다.틀린 내용이 있을 수 있습니다. 다양한 데이터 소스(컬렉션, 배열 등)를 표준화된 방법으로 다루기 위한 것그 전까지는 List, Set, Map 등의 사용 방법들

velog.io

 

- 람다식

장점

  • 코드의 간결성 - 람다를 사용하면 불필요한 반복문의 삭제가 가능하며 복잡한 식을 단순하게 표현할 수 있습니다.
  • 지연연산 수행 - 람다는 지연연상을 수행 함으로써 불필요한 연산을 최소화 할 수 있습니다.
  • 병렬처리 가능 - 멀티쓰레디를 활용하여 병렬처리를 사용 할 수 있습니다.

단점

  • 람다식의 호출이 까다롭습니다
  • 람다 stream 사용 시 단순 for문 혹은 while문 사용 시 성능이 떨어집니다.
  • 불필요하게 너무 사용하게 되면 오히려 가독성을 떨어 뜨릴 수 있습니다.

 

무조건 람다가 좋다는 보장은 없다. 상황에 따라 필요에 맞는 방법을 사용하는 것이 중요하다.

 

출처 : https://khj93.tistory.com/entry/JAVA-%EB%9E%8C%EB%8B%A4%EC%8B%9DRambda%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0-%EC%82%AC%EC%9A%A9%EB%B2%95

 

[JAVA] 람다식(Lambda)의 개념 및 사용법

람다함수란? 람다 함수는 프로그래밍 언어에서 사용되는 개념으로 익명 함수(Anonymous functions)를 지칭하는 용어입니다. 현재 사용되고 있는 람다의 근간은 수학과 기초 컴퓨터과학 분야에서의 

khj93.tistory.com

 

- GET , POST 차이

- GET

GET은 서버에서 어떤 데이터를 가져와서 보여줄 때 사용한다.

어떤 값이나 내용 상태등을 바꾸지 않는 경우에 사용한다.

GET은 요청을 전송할 때 URL주소 끝에 파라미터로 포함되어 전송되며, 이 부분을 쿼리스트링이라고 부른다.

  • GET은 불필요한 요청을 제한하기 위해 요청이 캐시될 수 있습니다.
  • 파라미터에 내용이 노출되기 때문에 민감한 데이터를 다룰 때 GET 요청을 사용해서는 안 됩니다.
  • GET 요청은 브라우저 기록에 남습니다.
  • GET 요청을 북마크에 추가할 수 있습니다.
  • GET 요청에는 데이터 길이에 대한 제한이 있습니다.
  • Get 요청은 성공시, 200(Ok) HTTP 응답 코드를 XML, JSON뿐만 아니라 여러 데이터(html, txt등..), 여러 형식의 데이터와 함께 반환합니다.
  • GET 요청은 idempotent합니다.

 

- POST

서버상의 데이터 값이나 상태를 바꾸기 위해서 사용한다.

POST는 데이터가 Body로 전송되고, 내용이 눈에 보이지 않아 GET보다 보안적인 면에서 안전하다고 생각할 수 있지만, POST 요청도 크롬의 개발자 도구, Fiddler와 같은 툴로 요청 내용을 확인할 수 있기 때문에 민감한 데이터의 경우에는 반드시 암호화해 전송해야 합니다.

  • POST 요청은 캐시되지 않습니다.
  • POST 요청은 브라우저 기록에 남아 있지 않습니다.
  • POST 요청을 북마크에 추가할 수 없습니다.
  • POST 요청에는 데이터 길이에 대한 제한이 없습니다.
  • Post 요청 중 자원 생성은 201(Created) HTTP 응답 코드를 반환합니다.
  • Post 요청은 idempotent하지 않습니다.

idempotent : 멱등성이란 뜻으로 연산을 여러번 적용하더라도 결과가 달라지지 않는 것

 

 출처 : https://velog.io/@songyouhyun/Get%EA%B3%BC-Post%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%A5%BC-%EC%95%84%EC%8B%9C%EB%82%98%EC%9A%94

 

Get과 Post의 차이를 아시나요?

제 질문에 답을 하지 못하겠다면, 이 글을 읽어보시는 걸 적극적으로 추천합니다.

velog.io

 

- 내일할 일

주특기 숙련주차로 들어가는데 공부를 어떻게 해야할지 계획을 러프하게 짜고 집중 다시해야겠다.