[Java] stream API를 예제와 함께 알아보자.

2023. 9. 26. 09:43·Programming Language/Java
반응형

stream API

public class ForIterationExampleMain {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();

        integerList.add(10);
        integerList.add(20);
        integerList.add(30);
        integerList.add(40);
        integerList.add(50);
        integerList.add(60);
        integerList.add(70);

        for (int i = 0; i < integerList.size(); i++) {
            System.out.println(integerList.get(i));
        }
    }
}

-> stream API 를 사용하지 않을 때. for 의 iterator 를 사용할 때

 

 

  • 기존의 for, if 문을 대체할 수 있다.
    • for 와 달리 forEach 를 쓰기때문에, 인덱스를 알 수 없다. (사실 알게할 수는 있는데, 가독성이 매우 떨어지게된다.)
    • for 와 달리 break 가 없다. (filter() 를 사용하면 break 가능)
  • Collection 인터페이스를 상속받은 클래스들에서 stream 을 사용 가능하다. (ArrayList, HashSet, etc)
  • Map 인터페이스를 상속받은 클래스들에서는 우회해서 사용 가능하다.(HashMap, etc)

 

 

 

 

forEach - 반복시키기

public class ForEachIterationExampleMain {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();

        integerList.add(10);
        integerList.add(20);
        integerList.add(30);
        integerList.add(40);
        integerList.add(50);
        integerList.add(60);
        integerList.add(70);

        integerList.stream().forEach(integer -> {
            System.out.println(integer);

            if(integer.equals(40)) {
                throw new RuntimeException();
            }
        });
    }
}

 

 

 

 

 

filter - 조건에 맞는 요소만 뽑기

public class ForAndIfFilterExampleMain {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();

        integerList.add(10);
        integerList.add(20);
        integerList.add(30);
        integerList.add(40);
        integerList.add(50);
        integerList.add(60);
        integerList.add(70);

        Integer findNumber = null;

        for (int i = 0; i < integerList.size(); i++) {
            System.out.println(integerList.get(i));

            if(integerList.get(i).equals(40)) {
                findNumber = integerList.get(i);
                break;
            }
        }

        System.out.println("findNumber=" + findNumber);
    }
}

-> for 에서 조건에 맞는 분기를 if 로 찾고있다.

 

public class FilterExampleMain {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();

        integerList.add(10);
        integerList.add(20);
        integerList.add(30);
        integerList.add(40);
        integerList.add(50);
        integerList.add(60);
        integerList.add(70);

        Integer findNumber = integerList.stream().filter(integer -> {
            System.out.println(integer);

            if(integer.equals(40))
                return true;

            return false;
        }).findAny().get();

        System.out.println("findNumber=" + findNumber);
    }
}

 

-> 조건에 맞지 않는 분기는 return false 한다.

-> filter 에서 조건에 맞는 분기는 return true 하고 있다.

-> .findAny() 해서 하나를 찾자마자 filter 가 종료된다. (for 에서 break 와 같은 효과)

 

 

 

 

 

map - 요소를 매핑시키기

interface 의 map 이 아니다. stream API 의 map 메서드를 말한다.

map 메서드는 원래의 Collection 에서 특정한 연산을 적용하여 새로운 Collection 을 만든다.

 

public class ForMapExampleMain {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();

        integerList.add(10);
        integerList.add(20);
        integerList.add(30);
        integerList.add(40);
        integerList.add(50);
        integerList.add(60);
        integerList.add(70);

        List<Integer> x10IntegerList = new ArrayList<>();

        for (int i = 0; i < integerList.size(); i++) {
            x10IntegerList.add(integerList.get(i) * 10);
        }

        System.out.println(x10IntegerList);
    }
}

 

public class MapExampleMain {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();

        integerList.add(10);
        integerList.add(20);
        integerList.add(30);
        integerList.add(40);
        integerList.add(50);
        integerList.add(60);
        integerList.add(70);

        List<Integer> x10IntegerList = integerList.stream()
                .map(integer -> integer * 10)
                .toList();

        System.out.println(x10IntegerList);
    }
}

 

위 두 코드는 정확하게 같은 동작을 한다.

map() 에서는 람다식을 파라미터로 전달받는데, 1 line 짜리 람다식은 중괄호가 {} 생략 가능하다.

 

 

 

 

filter와 map의 결합

public class FilterAndMapExampleMain {
    public static void main(String[] args) {
        int[] integerArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        List<Integer> integerList = Arrays.stream(integerArray)
                .boxed()
                .toList();

        System.out.println(integerList);

        List<Integer> evenNumberList = integerList.stream()
                .filter(integer -> integer % 2 == 0)
                .toList();

        System.out.println(evenNumberList);

        List<Integer> evenX10NumberList = evenNumberList.stream()
                .map(integer -> integer * 10)
                .toList();

        System.out.println(evenX10NumberList);
    }
}

-> list 에서 짝수만 뽑아와서 데이터를 모두 10배씩 해서 새로운 list 를 만드는 과정

List<Integer> evenX10NumberList = integerList.stream()
                .filter(integer -> integer % 2 == 0)
                .map(integer -> integer * 10)
                .toList();

-> 이렇게 filter() 와 map() 을 합칠 수 있다.

 

for + if 의 조합에 비해서 가독성이 얼마나 좋은가! 

stream 을 잘 다루는 것은 자바 개발자에게 엄청난 무기가 되겠다.

 

 

 

 

map 에 stream API 사용하기

앞에서 말했던 것처럼 map 은 Collection 인터페이스를 상속받지 않고,

독자적인 인터페이스를 상속받기 때문에 stream API 를 사용할 수 없다.

하지만 map 을 set 으로 변환시켜서 stream API 를 사용할 수 있다.
public class MapStreamExample {
    public static void main(String[] args) {
        Map<String, Integer> someMap = new HashMap<>();
        Set<Map.Entry<String, Integer>> entries = someMap.entrySet();
        Set<String> keySet = someMap.keySet();
        List<Integer> valueList = someMap.values().stream().toList();

        entries.stream().forEach(stringIntegerEntry -> {
            String key = stringIntegerEntry.getKey();
            Integer value = stringIntegerEntry.getValue();

            // key, value 사용
        });
    }
}
반응형
저작자표시 비영리 변경금지 (새창열림)

'Programming Language > Java' 카테고리의 다른 글

[Java] 의존 관계에 대해 예제와 함께 알아보자.  (0) 2023.09.26
[Java] stream API 와 Optional  (0) 2023.09.26
[Java] if문이 너무 많다면, 리팩토링을 해보자.  (0) 2023.09.25
[Java] Optional - nullPointException을 잘 다뤄보자.  (0) 2023.09.25
[Java] Object 클래스와 주요 메서드 - equals(), hashCode(), toString()  (0) 2023.09.22
'Programming Language/Java' 카테고리의 다른 글
  • [Java] 의존 관계에 대해 예제와 함께 알아보자.
  • [Java] stream API 와 Optional
  • [Java] if문이 너무 많다면, 리팩토링을 해보자.
  • [Java] Optional - nullPointException을 잘 다뤄보자.
Giken
Giken
𝐒𝐲𝐬𝐭𝐞𝐦.𝐨𝐮𝐭.𝐩𝐫𝐢𝐧𝐭𝐥𝐧("𝐇𝐞𝐥𝐥𝐨 𝐖𝐨𝐫𝐥𝐝!");
  • Giken
    개발자 기켄
    Giken
  • 전체
    오늘
    어제
    • 분류 전체보기 (149)
      • Spring (10)
      • Infra & Messaging (5)
      • Database (6)
        • SQL (5)
      • Vibe Coding(with AI) (1)
      • FrontEnd (3)
      • Algorithm (74)
        • 백준 (71)
        • 프로그래머스 (0)
      • Programming Language (33)
        • C (3)
        • C++ (2)
        • Java (19)
        • PHP (7)
      • 프로젝트 (2)
      • EtcTech (9)
      • 낙서 (5)
  • 블로그 메뉴

    • GitHub
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    2753
    2588
    9498
    평년
    SQL
    백준
    SQL고득점키트
    DB
    C
    1330
    프로그래머스
    윤년
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Giken
[Java] stream API를 예제와 함께 알아보자.
상단으로

티스토리툴바