Giken Dev
Published 2023. 9. 26. 09:43
[Java] stream API 백엔드 데브코스
반응형

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 사용
        });
    }
}
반응형
profile

Giken Dev

@기켄

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!