Java

[Java] 람다식과 스트림

블로그 주인장 2023. 8. 10.

 

 

 

목차

     

     


    📢 람다식

    • 메소드 대신에 하나의 식으로 표현하는 것이다.
    • '익명 함수' 라고도 불린다.

     람다식의 장점

    • 일반적으로 코드가 간결해진다.
    • 코드의 가독성과 생산성이 높아진다.

    람다식의 단점

    • 재사용이 불가능하다.(익명함수이기 때문에)
    • 디버깅이 어렵고 재귀함수로는 맞지 않다.

    익명클래스(추상메소드) 와 익명함수(람다식)의 차이

    interface ComputeTool {
        public abstract int compute(int x, int y);
    }
    
    public class Main {
    
        public static void main(String[] args) {
    
            //익명 클래스
            ComputeTool cTool = new ComputeTool() {
                @Override
                public int compute(int x, int y) {
                    return x+y;
                }
            };
            System.out.println(cTool.compute(1,2));
    
            // 람다식
            ComputeTool cTool2 = (x , y) -> {return x + y;};
            System.out.println(cTool2.compute(1,2));
        }
    }
    • 람다식은 일회용함수이기 때문에 추상 메소드가 하나여야, 람다식에서 정보를 추론할 수 있다.
    • 만약 추상메소드가 2개인 경우 람다식은 사용 불가하다!!

    📢 스트림

    • 배열이나 컬렉션 등의 데이터를 하나씩 참조하여 처리 가능한 기능이다.
    • for문의 사용을 줄여 간결하게 한다.

     스트림 생성

     🏁 배열 스트림

    • Arrays.stream 메소드를 사용
    • stream.foreach() : 요소를 돌면서 실행되는 최종 작업
    public class Main {
    
        public static void main(String[] args) {
    
            String[] arr = new String[]{"a", "b", "c"};
    
            Stream stream1 = Arrays.stream(arr);
            stream1.forEach(System.out::println);
        }
    }

     🏁 컬렉션 스트림

    • 컬렉션 개체(List, Map, Set..) stream() 메소드를 지원한다.
    • 컬랙션 개체에서 stream() 메소드를 호출하면 스트림 객체를 만들 수 있다.
    public class Main {
    
        public static void main(String[] args) {
    
            System.out.println("== 컬렉션 스트림 ==");
            ArrayList list1 = new ArrayList(Arrays.asList(1, 2, 3));
            System.out.println("list1 = " + list1);
    
            Stream stream2 = list1.stream();
            stream2.forEach(System.out::println);
        }
    }

     🏁 스트림 빌더

    • 빌더(Builder)를 사용하면 스트림에 직접적으로 원하는 값을 넣을 수 있다.
    • 마지막에 .build() 메소드로 스트림을 리턴한다.
    public class Main {
    
        public static void main(String[] args) {
    
            Stream streamBuilder = Stream.builder().add(1).add(2).add(3).build();
            streamBuilder.forEach(System.out::println);
        }
    }

     🏁 스트림 generate

    • 람다식으로 값을 넣을 수 있다.
    • () -> "abc" 인자가 없고 리턴만 있는 함수형 인터페이스이기에 람다에서 리턴하는 값이 들어간다.
    public class Main {
    
        public static void main(String[] args) {
    
            //"abc"를 3번 반복한다는 의미이다.
            Stream streamGenerate = Stream.generate(() -> "abc").limit(3);
        }
    }

     🏁 스트림 iterate

    •  초기값과 해당 값을 다루는 람다를 이용해서 스트림에 들어갈 요소를 만든다.
    public class Main {
    
        public static void main(String[] args) {
    
            //3번 출력을 해야한다.(limit 3)
            //출력할 때 10에 x2를 하면서 출력한다.
            Stream streamIterate = Stream.iterate(10, n-> n* 2).limit(3);
            streamIterate.forEach(System.out::println);
      	}
    }

     🏁 기본 스트림

    •  기본 타입(int, long, double) 스트림을 생성할 수 있다.
    •  range 와 rangeClosed 는 범위의 차이는 두 번째 인자인 종료지점이 포함되느냐 안되느냐의 차이이다.
    IntStream intStream = IntStream.range(1, 5); // [1, 2, 3, 4]
    LongStream longStream = LongStream.rangeClosed(1, 5); // [1, 2, 3, 4, 5]

    스트림 중개 연산

    🏁 Filtering : Filter 내부 조건에 참인 요소들을 추출

    //조건(1). 1 ~ 9까지의 반복해라
    //조건(2). filtering을 해라 (n % 2 == 0)인 경우만
    IntStream intStream2 = IntStream.range(1,10).filter(n -> n % 2 == 0);
    intStream2.forEach(System.out::println);

    🏁 Mapping : Map 안의 연산을 요소 별로 수행

    //조건(1). 1 ~ 9까지의 반복해라
    //조건(2). n + 1을 해서 스트림에 담아라
    IntStream intStream3 = IntStream.range(1, 10).map(n -> n + 1);
    intStream3.forEach(n-> System.out.print(n + " "));

     

    🏁 Sorting : Map 안의 연산을 오름차순으로 수행

    IntStream intStream4 = IntStream.builder().add(1).add(5).add(3).add(4).add(2).build();
    IntStream intStreamSort = intStream4.sorted();		//intStream4을 오름차순으로 정렬

    ✨ 스트림 최종 연산

    🏁 Sum

    int sum = IntStream.range(1,5).sum();
    System.out.println("sum = " + sum);

    🏁 Average

    double average = IntStream.range(1,5).average().getAsDouble();	//Double형 치환
    System.out.println("average = " + average);

    🏁 min

    int min = IntStream.range(1,5).min().getAsInt();	//Int형 치환
    System.out.println("min = " + min);

    🏁 max

     

    int max = IntStream.range(1,5).max().getAsInt();	//Int형 치환
    System.out.println("max = " + max);

    🏁 reduce

    Stream<Integer> stream7 = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5)).stream();
    System.out.println(stream7.reduce((x , y) -> x + y).get()); //[1+2 -> 3+3 -> 6+4 -> 10+5 -> result = 15]

    🏁 forEach

    IntStream.range(1,10).filter(n -> n == 5).forEach(System.out::println);	//5의 배수인 경우만 반복문 진행

    반응형

    'Java' 카테고리의 다른 글

    [Java] Scanner vs BufferedReader, StringTokenizer  (0) 2023.08.16
    [Java] 내부 클래스  (0) 2023.08.09
    [Java] 인터페이스  (0) 2023.08.09

    댓글