Development/JAVA

stream 인터페이스(java 8 람다식)

루루지 2021. 4. 10. 23:37
반응형

Stream

컬렉션, 배열 등의 저장 요소를 하나씩 참조하여 함수형 인터페이스(람다식)를 적용하며 반복적으로 처리할 수 있도록 해주는 기능.

 

java8에서 부터 람다식으로 stream 인터페이스를 사용할 수 있다.

stream API에는 findAny(), findFirst()등의 메소드가 존재한다.

findFirst() 메소드는 말그대로 첫 번째 요소를 반환하는 스트림이다.

 

Stream API 특징

  • 원본의 데이터를 변경하지 않는다.
  • 일회용이다.
  • 내부 반복으로 작업을 처리한다.



출처: https://mangkyu.tistory.com/112 [MangKyu's Diary]

 

사용 예제1)

위와 같이 stream 인터페이스를 이용하여 원하는 값을 찾을 수 있다.

 

사용 예제2) 값을 소문자로 변경 java7, java8 람다식 비교

List<String> engChange = new ArrayList<String>();
        engChange.add("AAA");
        engChange.add("BBB");
        engChange.add("CCC");
        System.out.println(engChange);
        
        //java7 기존식
        for(String s : engChange) {
            System.out.println(s.toLowerCase());
        }
        //java8 람다식
        engChange.stream().map(s -> s.toLowerCase())
                .forEach(s -> System.out.println(s));

 

사용 예제3)

public int getTotalPrice() {
       /*
        int totalPrice = 0;
        for (OrderItem orderItem : orderItems) {
            totalPrice += orderItem.getTotalPrice();
        }
        return totalPrice;
       */
       // 윗 부분을 아래와 같이 변경 가능 
       return orderItems.stream().mapToInt(OrderItem::getTotalPrice).sum();
 }

 

사용 예제4) 두개의 리스트 비교

// 일반 리스트
public void testList1() {
       List<String> list1 = Arrays.asList("김김","님님","딤딤","림림");
       List<String> list2 = Arrays.asList("금금","늠늠","딤딤","림림");
       
       // 중복되지 않은 값 추출
       List<String> notMatchResult = list1.stream()
                                   .filter(origin -> list2.stream().noneMatch(Predicate.isEquals(origin))
                                   .collect(Collectors.toList());
       System.out.println(notMatchResult);  //["김김","님님","림림"]
       
       // 중복되는 값 추출
       List<String> matchResult = list1.stream()
                                   .filter(origin -> list2.stream().anyMatch(Predicate.isEquals(origin))
                                   .collect(Collectors.toList());
       System.out.println(matchResult);  //["딤딤"]
}

// 객체 리스트
public void testList2() {
       List<String> list1 = Arrays.asList(new User(1,"김김"),new User(2,"님님"),new User(3,"딤딤"));
       List<String> list2 = Arrays.asList(new User(10,"금금"),new User(2,"님님"),new User(3,"딤딤"));
       
       // 중복되지 않은 값 추출
       List<String> notMatchResult = list1.stream()
                                   .filter(origin -> list2.stream().noneMatch(target -> origin.getId().equals(target.getId())))
                                   .collect(Collectors.toList());
       System.out.println(notMatchResult);  //User[id=1, name=김김]
       
       // 중복되는 값 추출
       List<String> matchResult = list1.stream()
                                   .filter(origin -> list2.stream().anyMatch(target -> origin.getId().equals(target.getId())))
                                   .collect(Collectors.toList());
       System.out.println(matchResult);  //[User[id=2, name=님님],User[id=3, name=딤딤]]
}

 

단순 반복은 for문이 더 빠르다.

- for문은 단순 인덱스 기반이라 메모리 접근이기 때문에 빠르고 오버헤드가 없다.

- stream의 경우, JVM이 여러가지를 처리해줘야 해서 실행이 느리다.

- for문은 컴파일러가 최적화를 시킨다.

즉, 단순 forEach일 경우, stream이 아닌 for문을 사용하는게 좋다.

 

 

참고 링크

jeong-pro.tistory.com/165

 

자바 스트림(Stream) API 정리, 스트림을 이용한 가독성 좋은 코드 만들기(feat. 자바 람다, 함수형 프

Java Stream 자바 공부를 하면서 Stream이 무엇인지, 어떻게 사용되고 있는지 인지는 하고 있었으나 실제 코드로 타이핑해보지 않았다. 그러던 중 이번에 가볍게 API 훑어보는 식으로 공부를 하면서

jeong-pro.tistory.com