Everyday Dev System

0601_TIL : Stream forEach() 활용 본문

내배캠 주요 학습/TIL : Today I Learned

0601_TIL : Stream forEach() 활용

chaeyoung- 2023. 6. 1. 18:45
public class Main {
    public static void main(String[] args) {
        List<Book> bookList = Arrays.asList(
                new Book(1L, "모두의 딥러닝", "조태호", "IT", 21600),
                new Book(2L, "이득우의 게임 수학", "이득우", "IT", 40500),
                new Book(3L, "자바 웹 개발 워크북", "구멍가게 코딩단", "IT", 31500),
                new Book(4L, "실전 시계열 분석", "에일린 닐슨", "IT", 34200),
                new Book(5L, "데이터 분석가의 숫자유감", "권정민", "IT", 14400),
                new Book(6L, "스프링 부트 실전 활용 마스터", "그렉 턴키스트", "IT", 25200),
                new Book(7L, "오늘부터 IT를 시작합니다", "고코더", "IT", 16200),
                new Book(8L, "그림으로 이해하는 인지과학", "기타하라 요시노리", "IT", 16200),
                new Book(9L, "괜찮아, 그 길 끝에 행복이 기다릴 거야", "손미나", "여행", 17100),
                new Book(10L, "여행의 이유", "김영하", "여행", 12150),
                new Book(11L, "여행의 시간", "김진애", "여행", 16200),
                new Book(12L, "로봇 시대 살아남기", "염규현", "역사", 14850),
                new Book(13L, "경제 전쟁의 흑역사", "이완배", "역사", 15750),
                new Book(14L, "100가지 동물로 읽는 세계사", "사이먼 반즈", "역사", 29700),
                new Book(15L, "k 배터리 레볼루션", "박순혁", "경제", 17100),
                new Book(16L, "정하준의 경제학 레시피", "장하준", "경제", 16200),
                new Book(17L, "레버리지", "롭 무어", "경제", 16200)
        );
        
        // 카테고리가 여행인 책 제목 조회하기
        // 가격이 16200원 이하인 책 제목 조회하기
        // 책 제목에 경제라는 용어가 들어간 책 제목 조회하기
        // 가격이 가장 비싼 책 가격 조회하기
        // 카테고리가 IT인 책들의 가격을 40% 할인하여 새로운 책 리스트 만들기
        // 카테고리가 IT인 책들의 가격 합 조회하기

						
    }
}

class Book {
    // 분류번호
    private Long id;
    // 책 이름
    private String bookName;
    // 작가 이름
    private String author;
    // 카테고리
    private String category;
    // 가격
    private double price;

    public Book(Long id, String bookName, String author, String category, double price) {
        this.id = id;
        this.bookName = bookName;
        this.author = author;
        this.category = category;
        this.price = price;
    }

    public String getBookName() {
        return bookName;
    }

    public String getCategory() {
        return category;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

 

# 문제점 :

"카테고리가 여행인 책의 제목을 출력하기" 기능을 구현하는 과정에서

stream을 활용해서 하고 있으나 주소값만 출력되고 있다.. 

        System.out.println("카테고리가 여행인 책 : ");
        bookList.stream()
                .filter((Book book)-> book.getCategory().equals("여행"))
                .forEach(book -> System.out.println(book));

Result : 

카테고리가 여행인 책 : 
org.example.week5.Book@6d311334
org.example.week5.Book@682a0b20
org.example.week5.Book@3d075dc0

 

 

# 시도 

 

1. filter를 통해 새로운 배열에 넣은 후, for문을 통해 출력.

        List<Book> bookAboutTravel = bookList.stream()
                .filter((Book book)-> book.getCategory().equals("여행"))
                .toList();
        System.out.println("카테고리가 여행인 책 : ");
        for(Book b : bookAboutTravel){
            System.out.printf("%-20s\n",b.getBookName());
        }

Result : 

카테고리가 여행인 책 : 
괜찮아, 그 길 끝에 행복이 기다릴 거야
여행의 이유              
여행의 시간   

 

-> 요구한 결과값이 잘 나온다.

그렇지만, 과제에서 주어진 코드 템플릿에서는 새로운 배열을 생성하지 않고 출력하는 방법을 사용하라고 했다.

아래와 같은 템플릿을 통해 구현하라고 명시되어 있다.

// 카테고리가 여행인 책 제목 조회
bookList.stream().

 

stream()을 활용해 .toList()가 아닌 .forEach()를 통해 출력하여야 한다는 것을 구글링을 통해 알게 되었다.

forEach()를 어떻게 활용해야 하는지도 찾아보았다.

또한, filter와 map의 차이점도 검색해았다.

 

filter - 조건에 맞는 것들에 대해서만 로직을 적용.
예) [1,2,3,4]에서 2 이상인 요소 추출할 때 filter를 통해 [2,3,4]를 반환할 수 있다.


map - 모든 요소에 대해 로직을 적용.
예) [1,2,3,4]를 [2,4,6,8]로 가공할 때 map을 쓴다.

 

2. forEach() 활용하기 -1

        System.out.println("카테고리가 여행인 책 : ");
        bookList.stream()
                .filter((Book book)-> book.getCategory().equals("여행"))
                .forEach(book -> System.out.println(book.getBookName()));

 

        System.out.println("카테고리가 여행인 책 : ");
        bookList.stream()
                .filter((Book book)-> book.getCategory().equals("여행"))
                .forEach(travelB -> System.out.println(travelB.getBookName()));

차이를 두기 위해 book에서 travelB으로 변경하였다. 

filter를 거쳐 filter에서 true가 나온 book을 forEach 안에 들어가 실행하기 때문에,

forEach를 거치는 book은 카테고리가 여행인 책이고, 이를 travelB으로 따로 명명하였다.

 

Result : 

카테고리가 여행인 책 : 
괜찮아, 그 길 끝에 행복이 기다릴 거야
여행의 이유
여행의 시간

 

 

# 문제 해결 : 

bookList.stream().filter((Book book) -> book.getCategory().equals("여행"))
        .map(Book::getBookName)
        .toList()
        .forEach(System.out::println);

stream() 함수의 forEach를 활용하여 해결하였다.

자세한 stream 함수의 문법은 위에 설명하였다.