TIL - 계산기 클래스 예외처리 | Stream 사용하기

su·2023년 5월 26일
0

TIL

목록 보기
10/93
post-thumbnail

문제1 - 어제 했던 계산기 코드 예외처리 하기

1) 문제

어제 했던 계산기 문제에서
이번 주차에 배웠던 내용인 예외처리 코드를 추가해보는 문제였다..
그런데 ,, 생각보다 코드 갈피를 잡기가 어려웠다 ..
그래서 CY 스승님과 함께 코드를 작성해 보기로 했다!

2) 시도

우선 새로 추가된 클래스를 보면,
BadInputException.java

public class BadInputException extends Exception{
    // 예외 처리할 메소드 (매개변수는 String 타입)
    public BadInputException(String type) {
        super("잘못된 입력: "+type+"을 입력해주세요!");
    }
}

이렇게 되어있다.
잘못된 input 값을 받았을 때의 예외처리를 하는 클래스와 그 메소드이다

그리고 새롭게 CalculatorApp과, Parser클래스가 생겼다
CalculatorApp.java

public class CalculatorApp {
    public static boolean start() throws Exception {
        Parser parser = new Parser();
        Scanner scanner = new Scanner(System.in);

        System.out.println("첫 번째 숫자를 입력하세요!");
        String firstInput = scanner.nextLine();
        parser.parserFirstNum(firstInput);

        System.out.println("연산자를 입력해주세요!");
        String operator = scanner.nextLine();
        parser.parserOperator(operator);

        System.out.println("두 번째 숫자를 입력하세요!");
        String secondInput = scanner.nextLine();
        parser.parserSecondNum(secondInput);

        System.out.println("연산 결과: " +parser.executeCalculator());
        return true;
    } // start()

Parser.java

public class Parser {
    private static final String OPERATION_REG = "[+\\-*/]";
    private static final String NUMBER_REG = "^[0-9]*$"; 
    
    private final Calculator calculator = new Calculator();

    public Calculator getCalculator() {
        return calculator;
    }

    public Parser parserFirstNum (String firstInput) {}

    public Parser parserOperator (String operationInput) {}
    
    public Parser parserSecondNum (String secondInput) {}

    public double executeCalculator() {
        return calculator.calculate();
    }
}

Parser 클래스에서 새롭게 생긴 세 메소드 안을 채워야 한다.

그리고 Main클래스도 바뀌었다.

public class Main {
    public static void main(String[] args) throws Exception{
        boolean calculateEnded = false;
    }
}

저 밑에 코드를 작성하면 된다고 한다..!
이제 내용을 채워야 하는데 ,,, 예외 처리를 배웠던 코드랑 다른 부분이 많아서 많이 헤맸었다 ..

그리고 조건에 Pattern.matches()를 사용해야 한다고 했는데, 처음 보는 메소드라 검색해보았다
그 전에! OPERATION_REG와 NUMBER_REG 옆에 써있는 것이 무엇인지 궁금해서 찾아보았다.
검색해보니 정규 표현식이라고 하는데, "^[0-9]*$" 이라는 정규표현식은 숫자를 나타낸다고 한다!

정규표현식^[0-9]*$[+\-*/]
0부터 9사이의 숫자로 이루어진 수대괄호 안의 연산자들 (+ , - , * , /)

여기서 *은 몇자리수인지 상관이 없는 것을 나타내고, ^은 정규표현식의 시작, $은 정규표현식의 끝을 나타내며, -(마이너스)를 나타내기 위해서 앞에 \ \ (역슬래시 두개)를 붙이면 그 기호 자체를 표현한다고 한다.
(즉, \ \ - 이면 -기호 자체를 나타내는 표현이다)

그렇다면 Pattern.matches()는 어떻게 사용하면 될까?
소괄호 안에 매개변수를 두 개 넣어주는데, 앞쪽에 정규표현식, 뒷쪽에 비교할 문자열을 넣어주면 된다. (문자열! 을 넣어주어야 한다)
(ex.Pattern.matches(정규표현식, 비교할문자열))
그리고 결과값은 boolean 타입으로 반환된다.
즉, 조건식에 넣어주면 되는 듯 하다 !

3) 해결

// OPERATION_REG / NUMBER_REG
public Parser parserFirstNum (String firstInput) throws BadInputException{
	// 조건문이 false 라면
	if (Pattern.matches(NUMBER_REG, firstInput)) {
    	// String타입으로 입력받았으므로 Integer타입으로 변환
    	calculator.setFirstNum(Integer.parseInt(firstInput));
        // 이 객체를 반환하라
        return this;
    } else {
    	throw new BadInputException("숫자");
    }
}
    
public Parser parserSecondNum (String secondInput) throws BadInputException{
	// 조건문이 false 라면
	if (Pattern.matches(NUMBER_REG, secondInput)) {
    	// String타입으로 입력받았으므로 Integer타입으로 변환
    	calculator.setSecondNum(Integer.parseInt(secondInput));
        // 이 객체를 반환하라
        return this;
    } else {
    	throw new BadInputException("숫자");
    }
}

public Parser parserOperator (String operationInput) throws BadInputException{
	if (Pattern.matches(OPERATION_REG, operationInput)) {
    	switch (operationInput) {
        	case "+" : // + 연산자일때 AddOperation() 불러오기
            	calculator.setOperation(new AddOperation());
                break;
            case "-" : // - 연산자일때 SubstractOperation() 불러오기
            	calculator.setOperation(new SubstractOperation());
                break;  
            case "*" : // * 연산자일때 MultiplyOperation() 불러오기
            	calculator.setOperation(new MultiplyOperation());
                break;  
            case "/" : // / 연산자일때 DivideOperation() 불러오기
            	calculator.setOperation(new DivideOperation());
                break;    
        } // switch문
    } else {
    	throw new BadInputException("문자열");
    } // else문 종료
    return this;
}

Parser 클래스에서 만들어주어야 하는 메소드들에 throws 우리가 만든 예외 클래스를 해주고, 그 안에서 조건에 따라 throw new 우리가 만든 예외 메소드()를 선언하는 방법으로 코드를 작성했다!

Main 클래스에서는 try ~ catch문을 작성해주면 되는데,
미리 작성되어있던 calculatedEnded를 이용해서 while문을 돌리면 된다.

Main.java

public class Main {
	public static void main(String [] args) {
    	boolean calculatedEnded = false;
        
        while(!calculatedEnded) {
        	try{
            	calculateEnded = CalculatorApp.start();
            } catch (BadInputException e) {
                System.out.println(e.getMessage());
            }
        } // while
    }
}

while문 안에 들어가는 조건이 true라면 (즉 무한반복)
calculateEnded안에 CalculatorApp.start() 메소드를 넣어준다.
(CalculatorApp.start()는 리턴 타입이 boolean 이다!)
만약 예외가 발생하면 메시지를 출력하도록 코드를 작성했다!

4) 배운 점

예외 처리 코드 작성이 생각보다 어려웠다.
그리고 Pattern.matches() 메소드를 사용할 때, 매개변수를 두 개 넣어주는데 순서가 중요하다 ! (순서를 바꿔서 넣었더니 오류가 났었다. 꼭 앞쪽에 정규표현식, 뒤쪽에 비교할 문자열을 넣어주어야 한다.)

작성 완료한 코드를 실행해보니,
첫 번째 숫자 - 연산자 - 두 번째 숫자 순서로 입력을 받게 되어있는데
만약 연산자나 두 번째 숫자를 잘못 입력하면
다시 처음부터 돌아가서 첫 번째 숫자부터 입력하게 되어있었다.
그래서 CY 스승님과 함께 코드를 수정해보았다.
정리해서 올려봐야겠다!

++ 내용 추가 (2023.05.27)

문제2 - 계산기 코드 예외처리 2

1) 문제

위에서 작성했던 코드를 Main.java에서 실행하면
start() 메소드 안에 적힌 순서대로
첫 번째 숫자 - 연산자 - 두 번째 숫자를 입력받고
계산의 결과를 출력해 주게 된다.

start() 메소드 자체에 throws Exception이 되어 있어서 그런지
한 번 예외가 발생하면 다시 처음부터 숫자를 입력해 주어야 한다.
이 과정을 거치지 않고, 잘못 입력받은 것만 다시 입력받고 다음 단계로 넘어가게 할 수 없을까? 하는 생각에 코드를 수정해보기로 했다.
(CY 스승님과 !)

2) 시도

현재 CalculatorApp 내부의 start() 메소드의 모습이다.
이를 우리가 원하는 형태로 출력될 수 있게 수정해보자 !

public class CalculatorApp {

	public static boolean start() throws Exception {
    	Parser parser = new Parser();
    	Scanner scanner = new Scanner(System.in);

		System.out.println("첫 번째 숫자를 입력하세요!");
    	String firstInput = scanner.nextLine();
    	parser.parserFirstNum(firstInput);

    	System.out.println("연산자를 입력해주세요!");
    	String operator = scanner.nextLine();
    	parser.parserOperator(operator);

    	System.out.println("두 번째 숫자를 입력하세요!");
    	String secondInput = scanner.nextLine();
    	parser.parserSecondNum(secondInput);

    	System.out.println("연산 결과: " +parser.executeCalculator());
    	return true;
	} // start()
}

우선 각자 입력받을 수 있도록 메소드를 따로 만들어주어야 할 듯 하다.
첫 번째 글자를 입력받는 메소드를 만들어보자 !
start() 메소드 내에서 반복문을 돌리려고 한다.
반복문을 위해 boolean 타입의 firstNumEnded라는 필드를 생성해준다. (기본값 false)

private static boolean firstNumEnded = false;

public static void firstNumInput() throws Exception {
	Scanner sc = new Scanner(System.in);
    Parser parser = new Parser();
    
    // 원래 메소드의 형태와 동일
    System.out.println("첫 번째 숫자를 입력하세요!");
    String firstInput = scanner.nextLine();
    parser.parserFirstNum(firstInput);    
    
    // 입력받은 값이 null인지 아닌지 확인
    // parser 클래스에서 calculator 안의 firstnum 값 갖고오기
    Int i = parser.getCalculator().getFirstNum();
    // i가 null이 아니라면
    if (i != null) {
    	firstNumEnded = true;
    }
}

Parser 클래스에 getter 메소드를 추가한다.

// calculator에 접근하기 위해 !
public Calculator getCalculator() {
	return calculator;
}

Calculator 클래스에도 getter 메소드를 추가해주어야 한다.

public int getFirstNum() {
    return firstNum;
}

public int getSecondNum() {
    return secondNum;
}

public AbstractOperation getOperation() {
    return operation;
}

역시나 private로 선언된 필드에 접근하기 위해 필요하다!

이런 형태로 다른 메소드들 2개를 더 만들어서 실행해보았는데 ,,
이상하게 오류가 났다 ..
입력은 잘 받는데, 연산 결과를 출력하는 과정에서 원하는 값이 나오지 않는 것이었다 ..!
코드를 잘 작성했던 것 같은데 ,, 어떤 것이 문제였을까 ..?

3) 해결

코드를 다시 읽어보면, 각 메소드 안에 Parser 인스턴스를 생성하도록 되어있다.

우리는 하나의 Parser 인스턴스를 갖고 진행을 해야
첫 번째 숫자, 연산자, 두 번째 숫자의 값이
하나의 인스턴스 안에 저장되고 불러와 연산을 할 수 있는데
그렇지 않았기 때문에 발생했던 문제였다.
CalculatorApp을 다시 수정해보자

// CalculatorApp 안에 Parser 객체를 미리 선언해두자
Parser parser1 = new Parser();

// start() 안에서 while문을 돌리기 위한 boolean 필드 선언
private static boolean firstNumEnded = false;
private static boolean operatorEnded = false;
private static boolean secondNumEnded = false;

// start() 메소드 수정
public static boolean start() throws Exception {
	Scanner scanner = new Scanner(System.in);

	while(!firstNumEnded) {
        firstNumInput();
    }

    while(!operatorEnded) {
        operatorInput();
    }

    while(!secondNumEnded) {
        secondNumInput();
    }
    
    // 첫 번째 숫자와 두 번째 숫자 출력
    System.out.println(parser1.getCalculator().getFirstNum() + ", " + parser1.getCalculator().getSecondNum());
    // 연산 결과 출력
    System.out.println("연산 결과: " + parser1.executeCalculator());
    return true;
} // start() 메소드

public static void firstNumInput() throws Exception {
	Scanner sc = new Scanner(System.in);
    
    // 원래 메소드의 형태와 동일
    System.out.println("첫 번째 숫자를 입력하세요!");
    String firstInput = scanner.nextLine();
    parser1.parserFirstNum(firstInput);    
    
    // 입력받은 값이 null인지 아닌지 확인
    // parser 클래스에서 calculator 안의 firstnum 값 갖고오기
    Int i = parser1.getCalculator().getFirstNum();
    // i가 null이 아니라면
    if (i != null) {
    	firstNumEnded = true;
    }
} // firstNumInput

public static void operatorInput() throws Exception {
	Scanner sc = new Scanner(System.in);
    
    // 원래 메소드의 형태와 동일
    System.out.println("두 번째 숫자를 입력하세요!");
    String operatorInput = scanner.nextLine();
    parser1.parserOperator(operator);
    
    // 입력받은 값이 null인지 아닌지 확인
    // parser 클래스에서 calculator 안의 operator 값 갖고오기
    AbstractOperation aO = parser1.getCalculator().getOperation();   
    // i가 null이 아니라면
    if (!Objects.isNull(a0)) {
    	operatorEnded = true;
    }
} // operatorInput

public static void secondNumInput() throws Exception {
	Scanner sc = new Scanner(System.in);
    
    // 원래 메소드의 형태와 동일
    System.out.println("두 번째 숫자를 입력하세요!");
    String secondInput = scanner.nextLine();
    parser1.parserSecondNum(secondInput);    
    
    // 입력받은 값이 null인지 아닌지 확인
    // parser 클래스에서 calculator 안의 secondNum 값 갖고오기
    Int i = parser1.getCalculator().getSecondNum();
    // i가 null이 아니라면
    if (i != null) {
    	secondNumEnded = true;
    }
} // secondNumInput

4) 배운 점

원래 있던 메소드를 분해해보려는 과정에서
객체를 선언하는 코드의 위치를 다시 생각해보게 되었다

기존에 있는 start() 메소드는,
그 하나의 메소드만으로 코드가 진행되기 때문에 그 안에서 Parser 객체를 선언해서 사용해주면 되지만

우리가 분리하려는 코드에서는
각 메소드마다 Parser 객체를 선언해주면 그 메소드마다 인스턴스가 생기는 것이므로 값이 하나로 묶이지 않는 것이었다.

각 메소드 안에서가 아닌 클래스 내에서 인스턴스를 선언해두고
선언해둔 인스턴스를 각 메소드 안에서 사용하면 된다 !

++ 내용 추가 (2023.05.28)

문제 3 - stream() 이용하기

1) 문제

stream을 처음 배웠다 ..!
처음 들어보는 개념이고, 어떻게 사용해야 할 지 가늠이 잡히지 않아
과제를 수행하는 데에 오랜 시간이 걸렸다 ..

2) 시도

.stream()은 stream을 받아오는 코드이다.
.filter()을 통해서 stream을 가공할 수 있다.
.toList()를 통해 결과를 List 형태로 만들 수 있다.
.forEach()는 각 원소에 넘겨받은 함수를 실행해준다.
.map()은 넘겨받은 값을 변환하는 데에 주로 사용한다.

이렇게 다섯가지를 배우고 사용해보려고 했다.

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)
        ); // bookList
        
		// 여기에 작성할 예정이다!
						
    }
}

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;
    }
}

Main 클래스 안의 main 메소드에서 코드를 실행하되,
Book 클래스 안에서 필요한 필드와 메소드를 정의하여 사용한다.

1) 카테고리가 여행인 책 제목 조회
위에서 배웠던 filter 기능을 사용하면 될 것 같아 코드를 작성해보았다.

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

1-1) filter를 이용하여 카테고리가 여행인 책들을 분류한다
1-2) map을 이용하여 책 제목을 불러온다
1-3) toList로 리스트 형태로 만들어준 다음
1-4) forEach로 각 책의 제목을 조회한다

2) 가격이 16200원 이하인 책 제목 조회
위의 코드와 거의 유사해보였다. 바로 작성해보자.

bookList.stream().filter((Book book) -> book.getPrice() <= 16200)
.map(Book::getBookName).toList().forEach(System.out::println);

2-1) filter를 이용하여 가격이 16200원 이하인 책을 분류한다
2-2) map을 이용하여 책 제목을 불러온다
2-3) toList를 이용하여 리스트 형태로 만들어준다
2-4) forEach로 각 책의 제목을 출력한다

3) 책 제목에 "경제" 라는 용어가 들어간 책 제목 조회
마찬가지로 책 제목을 조회하는 문제이지만, 조건이 조금 달라졌다.
작성해보자 !

bookList.stream().filter((Book book) -> book.getBookName().contains("경제"))
.map(Book::getBookName).toList().forEach(System.out::println);

4) 가격이 가장 비싼 책 가격 조회

double maxPrice = bookList.stream().
System.out.println("책 목록 중 가장 비싼 금액: " + maxPrice);

저 뒤의 코드를 완성하면 되는데 ..
어떻게 최대값을 구할 수 있을지 계속 검색해보았다.
그리고 두 가지 방법을 알게 되었다!

4-1) max() 안의 Comparator.comparing 사용하기

double maxPrice = bookList.stream().max(Comparator.comparing(Book::getPrice))
.get().getPrice();

stream()의 max()를 사용하되 max 안에 Comparator.comparing을 이용한다.
max는 Comparator를 인자로 받아 사용할 수 있는데,
comparing을 이용하면 리스트 내의 값 비교가 더 용이하다고 한다.
comparing()안에 Book 클래스 내의 getPrice 메소드를 이용하여 값을 가져오고 이를 이용해 max() 내에서 최대값을 찾도록 한다.
그 후 get()을 통해 Book을 불러오고 getPrice()를 통해서 가격을 불러온다.

4-2) mapToDouble() 사용하기

double maxPrice = bookList.stream().mapToDoulbe(Book::getPrice)
.max().getAsDouble();

위의 코드보다 더 간결해졌다!
mapToDouble은 반환 결과를 double의 형태로 알려준다. 즉 doubleStream으로 반환한다. (그냥 map과의 차이점이다)
우리는 가격만 가져오면 되기 때문에 doubleStream으로 반환된 형태에서 max()값을 구하고 그 값을 getAsDouble을 통하여 double 타입으로 가져오면 된다.

5) 카테고리가 IT인 책들의 가격 합 조회
조건 + 계산이 합쳐진 문제다 ..! 코드를 작성해보자

double sum = bookList.stream()
System.out.println("카테고리 IT 책들의 가격 합: " + sum);

마찬가지로 stream() 뒤를 채워주면 된다.
우선 카테고리가 IT인 책들을 분류하면

.filter((Book book) -> book.getCategory().equals("IT"))

이 코드를 뒤에 붙일 수 있고,
가격을 가져와야 하니 위에서 사용했던 mapToDouble을 적용해보자!

.mapToDouble(Book::getPrice)

여기까지는 잘 왔는데 ,, mapToDouble 형태로 반환했으니 더하기만 하면 되지 않을까 ? 해서 sum 함수를 붙여보았다..!
성공적이었다 ,,

코드를 완성하면,

double sum = bookList.stream()
.filter((Book book) -> book.getCategory().equals("IT"))
.mapToDoulbe(Book::getPrice).sum();

이렇게 사용할 수 있다 !

stream에 reduce라는 것이 있어 이를 이용해보고자 코드를 하나 더 작성해보았다

double sum = bookList.stream()
.filter((Book book) -> book.getCategory().equals("IT"))
.mapToDouble(Book::getPrice).reduce(0, Double::sum);

어째서 인지 코드가 더 길어졌다 ..
애초에 bookList라는 리스트는 안에 들어간 원소의 type이 Book이라
단순하게 reduce를 통해서 사용할 순 없고,
Book 안의 getPrice를 통해서 가격만을 doubleStream 형태로 반환하는 mapToDouble이 없으면 reduce를 사용할 수 없는 것 같았다.
그래서 코드가 더 길어진 듯 하다. 하지만 결과는 같다 !

6) IT 책 할인 이벤트 - 카테고리가 IT 인 책들의 가격을 40% 할인하여 새로운 책 리스트 만들기

List<Book> discountedBookList = bookList.stream().
			
for (Book book : discountedBookList) {
    System.out.println("할인된 책 제목: " + book.getBookName());
    System.out.println("할인된 책 가격: " + book.getPrice() + "\n");
}

이 6번 문제를 해결하는 것에 시간이 오래 걸렸다 ..
처음에는 map을 이용하면 되지 않을까 ? 해서 map을 이용해서 계속 코드를 작성했었다.

List<Book> discountedBookList =
bookList.stream().filter((Book book) -> book.getCategory().equals("IT"))
.map((Book book) -> book.setPrice(book.getPrice()*0.6)).toList();

그랬더니 오류가 발생했다

java: method map in interface java.util.stream.Stream<T> cannot be applied to given types;

stream 내부의 map 메소드는 지금 내가 작성한 type을 적용할 수 없다는 이야기 인 듯 하였다.

그래서 코드를 계속 수정해보았다

List<Book> discountedBookList = 
bookList.stream().map((Book book) -> book.getCategory().equals("IT") ? 
book.getPrice()*0.6 : book.getPrice()).collect(Collectors.toList());

그래도 오류가 발생했다

incompatible types: inference variable T has incompatible bounds

이 역시 호환되지 않는 유형이라고 한다.
값을 수정하여 새로운 리스트를 만들어야 하는 문제인데,
map이 아니라 다른 무언가가 있는건가 ? 싶어 검색을 해보았다.

3) 해결

stream에 peek라는 메소드를 사용하는 코드들을 발견했다.
peek는 연산과 연산 사이에서 결과를 확인할 때 사용한다고 한다.
무엇보다 원본 List의 요소를 소모하지 않는다고 한다.
peek는 중개 연산자이기 때문에 마지막에 peek를 사용하는 것이 아니라, 중간에 peek를 넣어주어야 동작한다.

peek를 사용해서 코드를 다시 작성해보자

List<Book> discountedBookList = 
bookList.stream().filter((Book book) -> book.getCategory().equals("IT"))
.peek((Book book) -> book.setPrice(book.getPrice() * 0.6))
.collect(Collectors.toList());  // 말고 .toList() 도 가능

filter로 카테고리가 IT인 책들을 분류하고
peek를 통해서 Book 안의 setPrice 메소드를 통해 가격을 수정한다. (40% 할인)
그런 다음 결과를 list 형태로 반환해주는 collect(Collectors.toList())를 사용했다.

4) 배운 점

stream을 처음 배우고 처음 써보는 터라
아직 모르는 부분이 너무 많고, 원하는 대로 결과가 출력되기는 했지만 올바르게 코드를 작성했는지 감이 잘 잡히지 않는다.
하지만 코드가 훨씬 간결해진 것을 느낌으로써 잘 배워서 사용하면 코드를 작성하기도, 읽기도 편해질 것 같다는 생각이 들었다!

혹시 ,, 제 코드에서 틀린 부분을 발견하신다면 ,, 알려주시면 감사하겠습니다 ,,

출처 & 참고자료

https://tourspace.tistory.com/9
https://dev-kani.tistory.com/32
https://tychejin.tistory.com/377

profile
(❁´◡`❁)

0개의 댓글