[Java] Stream API - 2

노홍기·2023년 4월 23일
0

Stream API

Stream 중간 연산 요약

분류상세 분류설명
Stream 필터filter(), distinct()- filter()는 구성한 스트림 내에서 특정 조건에 맞는 결과값을 필터링 하기 위해 사용됩니다.
- distinct()는 구성한 스트림 내에서 중복을 제거한 결과값을 반환하기 위해 사용됩니다.
Stream 변환map(), flatMap()- map()은 구성한 스트림 내에서 요소들을 원하는 값으로 변환하여서 반환하기 위해 사용됩니다.
- flatMap()는 구성한 스트림 내에서 중복된 스트림을 평면화(flattern)하여 요소를 구성하여 반환하기 위해 사용됩니다.
Stream 제한limit(), skip()- limit()는 구성한 스트림 내에서 요소의 개수를 제한하여 반환해주기 위한 목적으로 사용됩니다.
- skip()는 구성한 스트림 내에서 시작부터 특정 n개의 요소를 제외하여 반환해주는 목적으로 사용합니다.
Stream 정렬sorted()- sorted()는 구성한 스트림 내에서 배열 혹은 리스트 그리고 Object의 요소에 대해서 오름/내림 차순을 수행하여 반환해주는 함수입니다.
Stream 연산 결과 확인peek()- peek()는 구성한 스트림 내에서 각각의 요소를 조회하는 연산자료 요소 자체를 추출하는것이 아닌 스트림의 요소를 조회하는 함수입니다.

Stream 중간 연산 상세

Stream 필터 - filter()

  • Stream 내에서 특정 조건에 맞는 결과값을 필터링 하기 위해 사용됩니다.
/*
 * [CASE1] Array 이용한 방법
 */
// 1. Array Initialize
int[] filterIntArr = {100, 200, 300, 500};

// 2. Array to IntStream : 300 이상의 값 filter
IntStream filterIntStream = Arrays.stream(filterIntArr).filter(item -> item >= 300);

// 3. IntStream to Array
filterIntArr = filterIntStream.toArray();    // 결과값 반환 : [300, 500]

/*
 * [CASE2] ArrayList 이용한 방법
 */
// 1. ArrayList Initialize
List<String> filterStrList = new ArrayList<>(Arrays.asList("kim", "lee", "park", "lee", "jung"));

// 2. ArrayList to Stream<String> : 리스트 내에 "lee"가 존재하는 배열을 찾습니다.
Stream<String> filterStrStream = filterStrList.stream().filter(item -> item.equals("lee"));

// 3. Stream<String> to ArrayList
filterStrList = filterStrStream.collect(Collectors.toList()); // 결과값 반환 : ["lee", "lee"]

/*
 * [CASE3] Object 이용한 방법
 */
// 1. Object ArrayList Initialize
List<UserDto> filterUserDtoList = Arrays.asList(
        UserDto.userBuilder().userId("adjh54").userNm("lee").userPw("1234").userSt("S").build(),
        UserDto.userBuilder().userId("ckask123").userNm("kim").userPw("4321").userSt("A").build()
);
// 2. Object to Stream<Object> : 사용자 상태가 "S"인 Object 를 찾습니다.
Stream<UserDto> filterUserDtoStream = filterUserDtoList.stream().filter(item -> item.getUserSt().equals("S"));

// 3. Stream<Object> to ArrayList
filterUserDtoList = filterUserDtoStream.collect(Collectors.toList()); // 결과값 반환: List<UserDto> 2

Stream 필터 - distinct()

  • Stream 내에서 중복을 제거한 결과값을 반환하기 위해 사용됩니다.
/*
 * [CASE1] Array 이용한 방법
 */
// 1. Array Initialize
int[] distinctIntArr = {1000, 5000, 5000, 7000, 12000, 12000};

// 2. Array to IntStream : Array 내에 중복되는 요소 제거
IntStream distinctIntStream = Arrays.stream(distinctIntArr).distinct();

// 3. InputStream to Array
distinctIntArr = distinctIntStream.toArray();    // 결과값 반환 : [1000, 5000, 7000, 12000]

/*
 * [CASE2] ArrayList 이용한 방법
 */
// 1. ArrayList Initialize
List<String> distinctStrList = new ArrayList<>(Arrays.asList("kim", "lee", "park", "lee", "jung"));

// 2. Array to IntStream : ArrayList 내에 중복되는 요소 제거
Stream<String> distinctStrStream = distinctStrList.stream().distinct();

// 3. InputStream to Array
distinctStrList = distinctStrStream.collect(Collectors.toList());    // 결과값 반환 : ["kim", "lee", "park", "jung"]

/*
 * [CASE3] Object 이용한 방법
 */
// 1. Object ArrayList Initialize
List<UserDto> distinctUserDtoList = Arrays.asList(
        UserDto.userBuilder().userId("adjh54").userNm("lee").userPw("1234").userSt("S").build(),
        UserDto.userBuilder().userId("ckask123").userNm("kim").userPw("4321").userSt("S").build()
);

// 2. Object to Stream<Object> : 객체간의 중복되는 요소를 확인.
Stream<UserDto> distinctUserDtoStream = distinctUserDtoList.stream().distinct();

// 3. Stream<Object> to ArrayList
distinctUserDtoList = distinctUserDtoStream.collect(Collectors.toList());   // 결과값 반환: 동일한 객체가 아니므로 구성한 모든 객체가 리스트로 반환이 됩니다.

Stream 변환 - Map()

  • Stream 내에서 요소들을 원하는 값으로 변환하여서 반환하기 위해 사용합니다.
  • 요소 내에서 조건부 검색을 위한 목적으로 사용하는 filter와 다르게 요소를 조작하여서 반환을 해줍니다.
/*
 * [CASE1] Array 이용한 방법
 */
// 1. Array Initialize
int[] mapIntArr = {1000, 5000, 7000, 12000};

// 2. Array to IntStream : 배열 요소 값이 7000 이상일 경우에만 3000을 더해서 반환합니다.
IntStream mapIntStream = Arrays.stream(mapIntArr).map(item -> item >= 7000 ? item + 3000 : item);

// 3. InputStream to Array
mapIntArr = mapIntStream.toArray();    // 결과값 반환 : [1000, 5000, 10000, 15000]

/*
 * [CASE2] ArrayList 이용한 방법
 */
// 1. ArrayList Initialize
List<String> mapStrList = new ArrayList<>(Arrays.asList("kim", "lee", "park", "lee", "jung"));

// 2. ArrayList to Stream<String>
Stream<String> strMapStream = mapStrList.stream().map(item -> "name ::" + item);

// 3. Stream<String> to ArrayList
mapStrList = strMapStream.collect(Collectors.toList());      // 결과값 반환 : ["name ::kim", "name ::lee", "name ::park", "name ::lee", "name ::jung"]

/*
 * [CASE3] Object 이용한 방법
 */
// 1. Object ArrayList Initialize
List<UserDto> mapUserDtoList = Arrays.asList(
        UserDto.userBuilder().userId("adjh54").userNm("lee").userPw("1234").userSt("S").build(),
        UserDto.userBuilder().userId("ckask123").userNm("kim").userPw("4321").userSt("S").build()
);
// 2. Object to Stream<Object>
Stream<UserDto> userDtoMapStream = mapUserDtoList.stream().map(item -> {
    return item.toBuilder().userNm("MyName is " + item.getUserNm()).build();
});

// 3. Stream<Object> to ArrayList
mapUserDtoList = userDtoMapStream.collect(Collectors.toList()); // 결과값 반환: List<UserDto> 2

// map을 이용한 소문자를 대문자로 전환 작업
String[] toLowerCaseArr = {"one", "two", "three"};
Stream<String> upperCaseStream = Arrays.stream(toLowerCaseArr).map(String::toUpperCase);

Stream 변환 - flatMap()

  • Stream 내에서 중복된 Stream을 평면화하여 요소를 구성하여 변환하기 위해 사용됩니다. 중복된 구조의 리스트를 하나의 평면화된 리스트로 반환을 받습니다.
/*
 * [CASE1] 2차원 int Array 이용한 방법
 */
// 1. 2차원 intArray Initialize
int[][] int2Dimension = {{1, 2}, {3, 4}, {5, 6}};

// 2. 2차원 intArray to 1차원 intArray
int[] flatMapIntArr = Arrays.stream(int2Dimension).flatMapToInt(Arrays::stream).toArray();    // 결과값 반환: [1, 2, 3, 4, 5, 6]

/*
 * [CASE2] 2차원 string Array 이용한 방법
 */
// 1. 2차원 stringArray Initialize
String[][] str2Dimension = {{"one", "two"}, {"three", "four"}, {"five", "six"}};

// 2. 2차원 stringArray Initialize to 1차원 object Array
Object[] flatMapObjectArr = Arrays.stream(str2Dimension).flatMap(Arrays::stream).toArray(); // 결과값 반환: ["one, "two", "three", "four", "five", "six")

Stream 제한 - limit()

  • Stream 내에서 요소의 개수를 제한하여 반환해 주기 위한 목적으로 사용됩니다.
/*
 * [CASE1] Array 이용한 방법
 */
// 1. Array Initialize
int[] limitIntArr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// 2. Array to IntStream : 4개의 요소만 출력되도록 한다.
IntStream limitIntStream = Arrays.stream(limitIntArr).limit(4);

// 3. InputStream to Array
limitIntArr = limitIntStream.toArray(); // [1, 2, 3, 4]

/*
 * [CASE2] ArrayList 이용한 방법
 */
// 1. ArrayList Initialize
List<String> limitStrList = new ArrayList<>(Arrays.asList("one", "two", "three", "four", "five"));

// 2. ArrayList to Stream<String>
Stream<String> limitStrStream = limitStrList.stream().limit(4);

// 2. InputStream to Array
limitStrList = limitStrStream.collect(Collectors.toList());     // ["one", "two", "three", "four"]

/*
 * [CASE3] Object 이용한 방법
 */
// 1. Object ArrayList Initialize
List<UserDto> limitUserDtoList = Arrays.asList(
        UserDto.userBuilder().userId("adjh54").userNm("lee").userPw("1234").userSt("S").build(),
        UserDto.userBuilder().userId("ckask123").userNm("kim").userPw("4321").userSt("S").build(),
        UserDto.userBuilder().userId("fjdsl3").userNm("park").userPw("5678").userSt("S").build(),
        UserDto.userBuilder().userId("jklasd").userNm("jung").userPw("8765").userSt("S").build()
);
// 2. Object to Stream<Object>
Stream<UserDto> limitUserDtoStream = limitUserDtoList.stream().limit(2);

// 3. Stream<Object> to ArrayList
limitUserDtoList = limitUserDtoStream.collect(Collectors.toList()); // 결과값 반환: List<UserDto> 2

Stream 제한 - skip()

  • Stream 내에서 시작부터 특정 n개의 요소를 제외하여 반환해 주는 목적으로 사용합니다.
/*
 * [CASE1] Array 이용한 방법
 */
// 1. Array Initialize
int[] skipIntArr = {1, 2, 3, 4, 5, 6, 7, 8};

// 2. Array to IntStream : 배열 내에서 인덱스 순서대로 2개의 값을 제외한 결과값을 반환합니다.
IntStream skipIntStream = Arrays.stream(skipIntArr).skip(2);

// 3. InputStream to Array
skipIntArr = skipIntStream.toArray();       // [3, 4, 5, 6, 7, 8]

/*
 * [CASE2] ArrayList 이용한 방법
 */
// 1. ArrayList Initialize
List<String> skipStrList = new ArrayList<>(Arrays.asList("one", "two", "three", "four", "five"));

// 2. InputStream to Array : 리스트 내에서 인덱스 순서대로 4개의 값을 제외한 결과값을 반환합니다.
Stream<String> skipStrStream = skipStrList.stream().skip(4);

// 3. InputStream to Array
skipStrList = skipStrStream.collect(Collectors.toList());   // ["five"]

/*
 * [CASE3] Object 이용한 방법
 */
// 1. Object ArrayList Initialize
List<UserDto> skipUserDtoList = Arrays.asList(
        UserDto.userBuilder().userId("adjh54").userNm("lee").userPw("1234").userSt("S").build(),
        UserDto.userBuilder().userId("ckask123").userNm("kim").userPw("4321").userSt("S").build(),
        UserDto.userBuilder().userId("fjdsl3").userNm("park").userPw("5678").userSt("S").build(),
        UserDto.userBuilder().userId("jklasd").userNm("jung").userPw("8765").userSt("S").build()
);
// 2. Object to Stream<Object> : 리스트 내에서 인덱스 순서대로 2개의 값을 제외한 결과값을 반환합니다.
Stream<UserDto> skipUserDtoStream = skipUserDtoList.stream().skip(2);

// 3. Stream<Object> to ArrayList
skipUserDtoList = skipUserDtoStream.collect(Collectors.toList()); // 결과값 반환: List<UserDto> 2

Stream 제한 - sorted()

  • Stream 내에서 배열 혹은 리스트, Object의 요소에 대해서 오름/내림 차순을 수행하여 반환해 주는 함수입니다.
/*
 * [CASE1] Array 이용한 방법
 */
// 1. Array Initialize
int[] sortNumArr1 = {10, 11, 1, 2, 4};
int[] sortNumArr2 = {0, 1, 2, 3, 4};

// 2.1. Array to IntStream : 배열을 오름차순으로 정렬합니다.
IntStream sortAscIntStreamType1 = Arrays.stream(sortNumArr1).sorted();

// 2.2. Array to Stream<Integer> : 배열을 내림차순으로 정렬합니다.
Stream<Integer> sortDescIntStreamType1 = Arrays.stream(sortNumArr1).boxed().sorted(Comparator.reverseOrder());
Stream<Integer> sortDescIntStreamType2 = Arrays.stream(sortNumArr2).boxed().sorted((a, b) -> b - a);

// 3.1. IntStream to int[]
int[] resultSortedNumArr1 = sortAscIntStreamType1.toArray();    // 결과값 반환(오름차순) : [1, 2, 4, 10, 11]

// 3.2. Stream<Integer> to int[]
int[] resultSortedNumArr2 = sortDescIntStreamType1.mapToInt(i -> i).toArray();      // 결과값 반환(내림차순) : [11, 10, 4, 2, 1]
int[] resultSortedNumArr3 = sortDescIntStreamType2.mapToInt(i -> i).toArray();      // 결과값 반환(내림차순) : [4, 3, 2, 1, 0]

/*
 * [CASE2] ArrayList 이용한 방법
 */
// 1. ArrayList Initialize
List<String> sortedStrList1 = new ArrayList<>(Arrays.asList("aaa", "bbb", "ccc", "ddd", "AAA"));
List<String> sortedStrList2 = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
List<String> sortedStrList3 = new ArrayList<>(Arrays.asList("f", "b", "z"));

// 2.1. ArrayList to Stream<String> : 리스트를 오름 차순으로 정렬합니다.
Stream<String> sortedStrStream1 = sortedStrList1.stream().sorted(Comparator.naturalOrder());

// 2.2. ArrayList to Stream<String> : 리스트를 오름 차순으로 정렬합니다.
Stream<String> sortedStrStream2 = sortedStrList2.stream().sorted(Comparator.reverseOrder());
Stream<String> sortedStrStream3 = sortedStrList3.stream().sorted((a, b) -> b.compareTo(a));

// 3.1. Stream<String> to List<String>
sortedStrList1 = sortedStrStream1.collect(Collectors.toList());     // 결과값 반환(오름차순) : ["AAA", "aaa", "bbb", "ccc", "ddd"]
sortedStrList2 = sortedStrStream2.collect(Collectors.toList());     // 결과값 반환(오름차순) : ["cherry", "banana", "apple"]
sortedStrList3 = sortedStrStream3.collect(Collectors.toList());     // 결과값 반환(오름차순) : ["z", "f", "d"]

/*
 * [CASE3] Object 이용한 방법
 */
// 1. Object ArrayList Initialize
List<UserDto> sortedUserDtoList = Arrays.asList(
        UserDto.userBuilder().userId("adjh54").userNm("lee").userPw("1234").userSt("S").build(),
        UserDto.userBuilder().userId("ckask123").userNm("kim").userPw("4321").userSt("S").build(),
        UserDto.userBuilder().userId("fjdsl3").userNm("park").userPw("5678").userSt("S").build()
);

// 2.1. Object to Stream<Object> : 리스트 내에서 userNm을 기준으로 오름차순으로 정렬합니다.
Stream<UserDto> sortedAscUserDtoStream = sortedUserDtoList.stream().sorted(Comparator.comparing(UserDto::getUserNm));

// 2.2. Object to Stream<Object> : 리스트 내에서 userNm을 기준으로 내림차순으로 정렬합니다.
Stream<UserDto> sortedDescUserDtoStream = sortedUserDtoList.stream().sorted(Comparator.comparing(UserDto::getUserNm).reversed());

// 3. Stream<Object> to ArrayList
List<UserDto> sortedAscUserDtoList = sortedAscUserDtoStream.collect(Collectors.toList());           // 결과값 반환: List<UserDto>
List<UserDto> sortedDescUserDtoList = sortedDescUserDtoStream.collect(Collectors.toList());         // 결과값 반환: List<UserDto>

Stream 연산 결과 확인 - peek()

  • Stream 내에서 각각의 요소를 조회하는 연산자로 요소 자체를 추출하는 것이 아닌
    Stream의 요소를 조회하는 함수입니다.
  • 해당 값은 스트림 그대로 변환하기에 다시 객체 형태로 변환이 불가능합니다.
  • peek() 함수를 사용하여 디버깅과 디버깅을 위한 중간 연산 결과값을 확인 가능합니다.
/*
 * [CASE1] Array 이용한 방법
 */
// 1. Array Initialize
int[] peekIntArr = {10, 11, 1, 2, 4};

// 2. Array to IntStream
IntStream peekIntStream = Arrays.stream(peekIntArr)
        .peek(System.out::println)
        .map(i -> i + 10)
        .peek(i -> System.out.println("결과값 : " + i))
        .map(i -> i + 10);

/*
 * [CASE2] ArrayList 이용한 방법
 */
// 1. ArrayList Initialize
List<String> peekStrList = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));

// 2. Array to Stream<String>
Stream<String> peekStrStream = peekStrList.stream()
        .peek(System.out::println)
        .map(i -> "My " + i)
        .peek(i -> System.out.println("결과값 : " + i))
        .map(i -> i + " 입니다");
profile
레벨업 하는 중

0개의 댓글