본문 바로가기
Today I Learned 2024. 5. 1.

(24.05.01)[3주차] CODE KATA와 과제에서 스트림과 람다식(메서드참조)정리

여자저차 과제를 마무리단계이고, 스트림과 람다식을 이론으로만 알고 있어서,

함수형 인터페이스와 더불어서 한번더 정리하면서 학습을 마무리하려고 했다.

 

사전 캠프 때 스스로 학습했던 것을 다신 복습하는 것이라선 무리는 없었지만,

개념은 한번더 후에 더 많이 활용하면서 다지도록 해야할 것이다.


CODE KATA 정리

List - > Array 스트림과 람다식(메서드참조)을 활용

더보기
import java.util.ArrayList;
import java.util.Collections;

class Solution {
    public int[] solution(int[] arr, int divisor) {
        
        ArrayList<Integer> arrList = new ArrayList<>();
        
        for(int i =0; i<arr.length; i++){
            if( (arr[i]%divisor) == 0 ) {
                arrList.add(arr[i]);
            } 
        }
        
        if(arrList.isEmpty()){
            arrList.add(-1);
        }
        
        Collections.sort(arrList);
   
   /*람다식을 활용*/
   int[] answer = arrList.stream().mapToInt(Integer::intValue).toArray();
        return answer;
    }
}

 

  • 원래는 아래와 같이 for문으로 작성을 해야했지만, 스트림과 람다식을 활용하여작성하도록 했다. 작성하는 순서를 여기에 정리하면서 나중에는 빠르게 활용할 수 있도록 연습!
  ...
  /*for문 사용*/
  int[] answer = new int[arrList.size()];
        for(int i =0; i<arrList.size(); i++){
            answer[i]=arrList.get(i);
        }
  ...

순서

  • stream 만들기
    • arrList 는 ArrayList이기 때문에 Stream으로 바꿔서 하나씩 꺼내서 int 타입의 Array를 만들어 줘야함
      • arrList는 ArrayList<Integer> 이기 때문에 .stream() 메서드를 사용해서 Stream<Integer>로 바꿈
  • stream 중간연산
    • map() 변환을 활용해서 특정형태, 여기에선 Integer가 아닌  int 타입으로 변해야하기 때문에 mapToInt()를 활용해서 IntStream 반환
    • arrList는 래퍼클래스인 Integer을 값으로 가지고 있기 때문에, 해당값이 i -> i.intValue(i) 람다식을 통해서 int 타입으로 바꿔줘야함
      • 따라서 메서드참조 클래스::메서드 에 따라서 Interger:intValue
  • stream 최종연산
    • Object반환의 toArray() 이지만 mapToInt() mapToDouble() mapToLong() 에 한해서 toArray() 시키면 같은 int double long 배열로 변환
      • 따라서 바로 연속해서 toArray() 써서 int[] answer 로 지정 가능!

과제 정리

스트림과 람다식(메서드참조)을 활용

더보기
...
 /*저장 결과 중 Scanner 입력받은 값보다 큰 결과 값들 출력 메서드*/
    public void biggerResult(double num1, double num2) {
        Scanner sc = new Scanner(System.in);
        System.out.println("입력 값보다 더 큰 값을 출력하겠습니까? (yes 입력 시 조회)");
        String input = sc.next();
        /*yes 입력시*/
        /*num1, num2 중 큰 값 설정*/
        if (input.equals("yes")) {
            Double maxNum;
            if (num1 < num2) {
                maxNum = num2;
            } else {
                maxNum = num1;
            }

            /*calculationResult Deque 컬렉션을 스트림으로 만들기*/
            /*컬렉션에 저장된 값을 변경하지 않아도 가능*/
            Stream<Double> biggerResultStream = calculationResult.stream();
            /*Stream 중간연산 filter 사용*/
            /*Stream 최종연산 forEach 사용*/
            biggerResultStream.filter(d -> d > maxNum).forEach(System.out::println);
        }

    }
...
  • 해당 메서드에서 calculationResult는 <Double>의 컬렉션 필드
  • calculationResult 컬렉션을 스트림으로 바꿔서 특정 조건 : maxNum 보다 큰 값만 출력 되게 만들기

순서

  • Stream 만들기
    • calculationResult을 .stream()을 통해서 Stream<Double>으로 변환
      • 단, 위의 코드는 주석을 추가하기위해 임의로 biggerResultStream으로 선언하면서 한번 끊었음
  • Stream 중간연산
    • filter() 를 통해 조건에 맞는 요소만 골라줄 수 있도록 사용
      • filter() 메서드 자체가 java.util.function 함수형 인터페이스의 Predicate를 매개변수로 받기 때문에(여기서는 Predicate<Double>) public boolean test(Double d) { return d > maxNum; } 인 Predicate가 들어가게됨
      • 위 식을 람다식으로 바꿔서 Double 타입 요소 d가 입력되고 boolean타입을 반환되는 식 d > maxNum을 사용하기 때문에 d ->  d > maxNum 으로 람다식으로 바꿀 수 있음
  • Stream 최종연산
    • forEach() 를 통해 중간연산을 통핸 들어온 요소들을 하나씩 System.out.println()을 통해서 한줄씩 출력
      • forEach() 일경우에는 함수형 인터페이스의 Consumer을 매개변수로 받기 때문에 여기서는 Consumer<Double>) public void accept(Double d) { System.out.println(d); } 인 Consumer가 들어가게됨

코멘트

  • 이론만 알고있었기때문에, 단순한 코드처럼 보이더라도 이번 기회에 KATA와 개인과제에 스트림과 람다 그리고 여기에 쓰이는 함수형 인터페이스를 나만의 말로 여기에 정리하고 후에는 바로 사용할 수 있도록 한다.