[4기] 백엔드 개발자 부트캠프 "오르미" ~ing/[4기] 백엔드 개발자 부트캠프 오르미 수업 복습

[4기] 50일차 Java ( 스트림 )

sohee99 2024. 2. 20. 19:21

 

 

매핑 - map, flatMap

 

map

- 스트림의 요소를 하나씩 특정 값으로 변환한다 변환된 값은 새로운 스트림으로 만들어진다!

 

출처 - 이스트소프트 조성연

 

A는 C 변환 B는 D로 변환 되었다.

 

예시) 알파벳 수문자를 문자열 대문자로 변환하는 소스코드

 

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
List.stream()
        .map(String::toUpperCase)
        .forEach(System.out::println);

 

toUpperCase 메소드 = 대문자로 변환해주는 메소드

 

 

flatMap

 

- map과 동일하게 스트림의 요소들을 다른값으로 대체는 동일하지만 데체하는 값이 스트림일경우 flatMap 사용

 

펴주는 느낌!  ( 2차원 배열과 유사한 구조! )

 

 

public static void main(String[] args) {
    List<String> list = Arrays.asList("Hello World", "Java stream", "HiStream");

    // [Hello, World, Java, stream]
    list.stream()
            .flatMap(str -> Arrays.stream(str.split(" ")))
            .forEach(System.out::println);
}

 

" " 공백을 기준으로 싹 펴준것! 

[Hello, World],[Java,stream]을 1차원으로 펴준것!

 

HiStream의 경우 공백이 없기때문에 그대로 출력

 

출력값은?

 

 

 

정렬 - sorted

 

sorted

- 스트림의 요소들을 정렬하기 위해 사용하는 메소드 

 

List<Integer> list = Arrays.asList(15, 6, 7, 8, 2, 1);
list.stream()
        .sorted()
        .forEach(System.out::println);

 

루핑 - peek, forEach

 

peek

-확인해본다는 단어 뜻처럼 특정 결과를 반환하지 않는다.

작업을 처리하는 중간에 결과를 확인해볼때 사용한다

 

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

int sum = list.stream()
			.mapToInt(n -> n)
			.filter(n -> n % 2 == 0)
			.peek(n -> System.out.println(n))   // [2, 4]
			.sum();  // sum을 사용하지 않으면 peek은 동작하지 않음
			
System.out.println(sum);    // 6

 

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

    OptionalInt sum = list.stream()
            .mapToInt(n -> n)
            .filter(n -> n % 2 == 0)

            .max();  

    System.out.println(sum.getAsInt());    // 4

 

forEach

- 결과단계에서 사용하는 메소드

 

forEach가 오면 결과 관련된 메소드가 올수가 없다. 

 

(결과관련된 메소드는 한번 아님 0번만 올수있다!!)

 

2단계 가공은 0 ~ n번 가능하지만 3단계 결과는 0 ~ 1 번가능

 

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

list.stream()
	.mapToInt(n -> n)
	.filter(n -> n % 2 == 0)
	.forEach(n -> System.out.println(n));   // [2, 4]

 

 

수집 - collect()

 

- 스트림의 최종단계에서 사용하는 메소드

 

어떤요소를 어떤 컬렉션에 수집할지 결정할 수 있다.

 

 

리스트의 숫자 중에서 짝수만 골라내어 새로운 리스트를 만드는 예제)

 

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

// 짝수만 골라내어 새로운 리스트로 collect
List<Integer> newList = list.stream()
				.filter(n -> n % 2 == 0)
				.collect(Collectors.toList());
							
newList.stream().forEach(System.out::println);  // [2, 4]

 

 

< Collectors에서 제공하는 메소드>

 
Collectors 정적 메소드 설명
toList
요소를 List에 저장
toSet
요소를 Set에 저장
toCollection
요소를 특정 컬렉션에 저장
toMap
요소를 Map에 저장

 

 

< 그룹핑 수집 >

 

출처 - 이스트 소프트 조성연

 

리스트에 숫자가 있고, 해당 숫자가 몇개 존재하는지 카운트

ex)

 

List<Integer> list = Arrays.asList(1, 1, 2, 2, 2, 3, 4, 5, 5, 5);

Map<Integer, Long> result = list.stream()
			.collect(Collectors.groupingBy(
				n -> n,
				Collectors.counting()  // 그룹핑 후 집계하는 메소드
			)
		);

/*
 * 1: 2개
 * 2: 3개
 * 3: 1개
 * 4: 1개
 * 5: 3개
 */
result.forEach((key, value) -> System.out.println(key + ": " + value + "개"));

 

n -> n 는 요소 값 그자체를 키로 사용한다는 의미!

 

Collectors.counting() 집계함수 그룹핑 후 어떻게 집계할 것인지 정할 수 있다.

 

 

Optional

 

NPE를 방지할 수 있도록 Optional 클래스가 도입

 

- null을 포함한 모든 데이터를 저장할 수 있는 Wrapper 클래스 

 

출처- 이스트소프트 조성연

 

한꺼풀 랩핑 되어있는 형태!

 

< 사용이유 >

 

1. null을 직접 다루는 것은 위험 - NullPointExcetion

2. null을 체크하기 위해 if문을 사용하면 코드가 지저분

 
메소드 설명
static <T> Optional<T> empty()
아무런 값도 가지지 않는 비어있는 Optional 객체를 반환함.
static <T> Optional<T> of(T value)
null이 아닌 명시된 값을 가지는 Optional 객체를 반환함.
 
 
static <T> Optional<T> ofNullable(T value)
명시된 값이 null이 아니면 명시된 값을 가지는 Optional 객체를 반환하며, 명시된 값이 null이면 비어있는 Optional 객체를 반환함.

 

public static void main(String[] args) {
    // 비어있는 Optional 객체 반환
    Optional<String> empty = Optional.empty();

    // null이 아닌 값을 갖는 Optional 객체 반환
    Optional<String> of = Optional.of("Optional 객체");

    // null을 허용하는 Optional 객체 반환
    Optional<String> nullableOpt = Optional.ofNullable("Nullable Optional 객체");
    
    String ofStr = nullableOpt.get(); // get을 사용하여 꺼낼수도 있음
    String returnSStr = nullableOpt.orElse("default value");
}

 

get() 메서드를 이용하여 저장된 값을 반환할 수 있지만, 

만약 객체가 null일경우 예외가 발생하기때문에 많이 사용은 안한다.

 
메소드 설명
T get()
Optional 객체에 저장된 값을 반환함.
T orElse(T other)
저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 값을 반환함.
T orElseGet(Supplier<? extends T> other)
저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 람다 표현식의 결과값을 반환.
<X extends Throwable> T orElseThrow(Supplier<? extends X>  exceptionSupplier)
저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 예외를 발생시킴.
 
 
boolean isPresent()
저장된 값이 존재하면 true를 반환하고, 값이 존재하지 않으면 false를 반환함.

 

Optional을 이용한 Null 처리 방법 예시

컬렉션에 있는 숫자들의 평균 값을 구하는 코드

 

List<Integer> list = new ArrayList<>();

// NoSuchElementException 예외 발생
double avg = list.stream()
		.mapToInt(Integer::intValue)
		.average()
		.getAsDouble();
				
System.out.println(avg);

 

예외를 피하기 위한 방법 1

 

객체 값이 실제로 존재할때만 평균을 출력하는 방법 ( 존재하는 지 체크해야겠졍?)

 

List<Integer> list = new ArrayList<>();

OptionalDouble optional = list.stream()
			.mapToInt(Integer::intValue)
			.average();

// 값이 실제로 존재하는지 체크
if (optional.isPresent()) {
	System.out.println(optional.getAsDouble());
}

 

예외를 피하기 위한 방법 2

 

값이 없을 경우 디폴트 값을 정하는 orElse 사용

 

List<Integer> list = new ArrayList<>();

double avg = list.stream()
		.mapToInt(Integer::intValue)
		.average()
		.orElse(0.0);  // 평균 값이 존재하지 않을 경우 0을 사용
				
System.out.println(avg);

 

예외를 피하기 위한 방법 3

 

스트림에서 ifPresent 메소드 사용

 

List<Integer> list = new ArrayList<>();

list.stream()
	.mapToInt(Integer::intValue)
	.average()
	.ifPresent(avg -> System.out.println(avg));  // 평균 값이 있을 경우에만 출력

 

이렇게 오늘 스트림을 마무리 했습니당!!!!

 

 

 

음... 이게 머리가 찼는지 뒤로 가면갈수록 머리용량부족인지 머엉----해지네요 ㅋㅋㅋㅋ

 

이해는 가는데 막상 쓰라면 머뭇거리는 매일 같은 상황 반복이랄까요 ㅋㅋㅋ

 

항상 말하지만 연습이 답이다.,... 열심히하자 소희야,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ㅠㅋㅋㅋㅋ

 

 

이제 주말에 전체적인 java 공부를 시작하면 될거같아요 ㅠ

 

이제 sql 한다고 하더라구욥! 

 

sql 혼자 공부하니 모르는게 많았는데 잘됐당 ㅎㅎㅎ 

 

히히히 시험전에 sql 진행해서 다행이지 뭐예요 ㅎㅎ흫ㅎㅎㅋㅋㅋㅋㅋ

 

오늘 배운내용 복습 후 전 sql 자격증 공부하러,,,ㅠ 

 

오늘도 자바 공부 열심히 했구!

 

내일도 파이팅!!!!!!!!!!!