[JAVA] Stream

2020. 10. 28. 22:14기본 문법/[JAVA]

개요


Java 문법에 대해서 조금 더 공부하려고자 한다..

이유는 간단하다. 코딩 테스트를 준비하는데 Programmers에 들어가봤더니 코드양이 압도적으로 차

이가 났었다. 물론 내 직관력이 조금 떨어지는 부분은 보완 할 수 있었겠지만 자바의 내장 객체들을

제대로 알고 쓰기 위해 먼저 Stream이라는 객체를 공부하고자 한다.

// 프로그래머스의 대단한 분의 코드... ( Programmers/Level2/해쉬/위장 1등 코드) 
import java.util.*;
import static java.util.stream.Collectors.*;

class Solution {
    public int solution(String[][] clothes) {
        return Arrays.stream(clothes)
                .collect(groupingBy(p -> p[1], mapping(p -> p[0], counting())))
                .values()
                .stream()
                .collect(reducing(1L, (x, y) -> x * (y + 1))).intValue() - 1;
    }
}
// 내 코드..
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

class Solution {
    static int types = 0;
    static int answer = 1;
    static int[] perTypes = new int[30];

    public int solution(String[][] clothes) {
        ArrayList<Integer> cList = new ArrayList<>();
        HashMap<String, Integer> typesSet = new HashMap<>();
        types = 0;
        for(int i=0; i<clothes.length; i++){
            String tTypes = clothes[i][1];
            if(typesSet.get(tTypes) == null){
                perTypes[types]++;
                typesSet.put(tTypes, types);
                types++;
            }else{
                perTypes[typesSet.get(tTypes)]++;
            }
        }
        for(int i=0; i<types; i++){
            int perTypeValue = perTypes[i];
            answer *= (perTypeValue+1);
        }
        return answer-1;
    }
}

Stream 이란?


우리는 배열 또는 컬렉션들을 다루는 방법으로 for 또는 foreach 문을 돌면서 요소 하나씩을 꺼내서 다루는 방법을 사용했을 것이다.

간단한 경우라면 상관없지만 로직이 복잡해질수록 코드의 양이 많아져 여러 로직이 섞이게 되고, 메소드를 나눌 경우 루프를 여러 번 도는 경우가 발생하게 된다.. ( 유지보수 + 직관성 떨어짐)

스트림은 '데이터의 흐름’이다. 배열 또는 컬렉션 인스턴스에 함수 여러 개를 조합해서 원하는 결과를 필터링하고 가공된 결과를 얻을 수 있게 된다.

또한, 람다를 이용해서 코드의 양을 줄이고 간결하게 표현할 수 있다.

즉, 배열과 컬렉션을 함수형으로 처리할 수 있다.

Why Stream?


  1. 직관성이 좋아진다.
  2. 코드의 양이 줄어든다.
  3. 간단한 병렬처리가 가능하다.
  4. Index Size 실수를 예방 할 수 있다. ( 사실 foreach를 사용하면 상관이 없긴 하다.)

How ?


  1. 생성하기 : 스트림 인스턴스 생성.
  2. 가공하기 : 필터링(filtering) 및 맵핑(mapping) 등 원하는 결과를 만들어가는 중간 작업(intermediate operations).
  3. 결과 만들기 : 최종적으로 결과를 만들어내는 작업(terminal operations).

Use


필자는 코테에 지금 집중을 하고 있기 때문에 병렬처리와 같은 실제 서비스를 위한 부분은 일단 제외 하도록 하겠다. 더 많은 예제들을 보고 싶으면 맨 밑에 내가 참고하고 쓴 사이트를 클릭하면 된다.

1. Filter

List<String> names = Arrays.asList("Eunchae", "Kyeong", "Java", "Wow");
Stream<String> filtered = names.stream().filter(name -> name.contains("a"));
// [Eunchae, Java]

2. Mapping

        Stream<String> mapped = names.stream()
                .map(String::toUpperCase);
                // [EUNCAHE, KYEONG, JAVA, WOW]
        Stream<Integer> stream = productList.stream()
                .map(Product::getAmount);
                // [10000, 100, 53, 22, 43 ...]

3.Collecting

List<String> collectorCollection = productList.stream()
	.map(Product::getName)
	.collect(Collectors.toList());

4. Collectors.groupingBy()

Map<Integer, List<Product>> collectorMapOfLists = productList
    .stream()
    .collect(Collectors.groupingBy(Product::getAmount));
// Product 의 수량으로 묶기

5. Matching

boolean anyMatch = names.stream()
	.anyMatch(name -> name.contains("a")); // 만족하는게 하나라도 있니?
boolean allMatch = names.stream()
	.allMatch(name -> name.length() > 3); // 모두 조건 만족하니?
boolean noneMatch = names.stream()
	.noneMatch(name -> name.endsWith("s")); // 모두 만족하는게 없니?

'기본 문법 > [JAVA]' 카테고리의 다른 글

[JAVA] 정규식 표현  (0) 2021.09.25
[JAVA] 지네릭스  (0) 2020.07.07
[JAVA] Set - TreeSet  (0) 2020.06.16
[JAVA] Set - HashSet  (0) 2020.06.14
[JAVA] Iterator  (0) 2020.06.14