Java / Stream 중간연산(1) - 자르기, 요소 걸러내기, 정렬하기, comparing()

김선호·2022년 10월 2일
0

Java 문법

목록 보기
12/15
post-thumbnail

스트림의 연산에는 중간연산과 최종연산이 있다.

  • 중간연산 : 연산결과가 스트림인 연산. 반복적으로 적용 가능
  • 최종연산 : 연산결과가 스트림이 아닌 연산. 단 한 번만 적용가능(스트림의 요소를 소모)

2.3 스트림의 중간 연산 - (1) 자르기, 요소 걸러내기, 정렬하기, comparing


(1/7) 스트림 자르기 - skip(), limit()

Stream<T> skip(long n) // 앞에서 부터 n개 건너뛰기
Stream<T> limit(long maxSize) // maxSize 이후의 요소는 잘라냄

예시

IntStream intStream = IntStream.rangeClosed(1, 10); // 12345678910 (rangeClosed는 endIndex포함)
intStream.skip(3).limit(5).forEach(System.out::print); // 45678

(2/7) 스트림의 요소 걸러내기 - filter(), distinct()

Stream<T> filter(Predicate predicate) // 조건식 predicate에 맞지 않는 요소 제거
Stream<T> distinct()

distinct() 사용 예시

IntStream intStream = IntStream.of(1, 2, 2, 3, 3, 3, 3, 4, 5, 5, 6);
intStream.distinct().forEach(System.out::print);

filter() 사용 예시

IntStream intStream = IntStream.rangeClosed(1, 10);
intStream.filter(i -> i % 2 == 0).forEach(System.out::print); // 246810
IntStream intStream = IntStream.rangeClosed(1, 10);
intStream.filter(i -> i % 2 != 0 && i % 3 != 0).forEach(System.out::print); // 157

// filter()는 중간 연산이므로 여러번 사용 가능하다.
intStream = IntStream.rangeClosed(1, 10);
intStream.filter(i -> i % 2 != 0).filter(i -> i % 3 != 0).forEach(System.out::print); // 157

(3/7) 스트림 정렬하기 - sorted()

Stream<T> sorted() // 스트림 요소의 기본 정렬(Comparable)로 정렬
Stream<T> sorted(Comparator compartor) // 지정된 Compartor로 정렬

문자열 스트림 정렬 방법

문자열 스트림 정렬 방법출력 결과
strStream.sorted() // 기본 정렬
strStream.sorted(Comparator.naturalOrder()) // 기본 정렬
strStream.sorted((s1, s2) → s1.compareTo(s2)) // 람다식도 가능
strStrema.sorted(String::compareTo) // 위의 문장과 동일
CCaaabccdd
strStream.sorted(Comparator.reverseOrder()) // 기본 정렬의 역순
strStream.sorted(Comparator.naturalOrder().reversed())
ddccbaaaCC
strStream.sorted(String.CASE_INSENSITIVE_ORDER) // 대소문자 구분 안함aaabCCccdd
strStream.sorted(String.CASE_INSENSITIVE_ORDER.reversed())ddCCccbaaa
strStream.sorted(Compartor.comparing(String::length) // 길이 순 정렬
strStream.sorted(Comparator.comapringInt(String::length) // no 오토박싱
bddCCccaaa
strStream.sorted(Compartor.comparing(String::length).reversed())aaaddCCccb

(4/7) Comparator의 comparing()으로 정렬 기준을 제공

comparing(Function<T, U> keyExtractor)
comparing(Function<T, U> keyExtractor, Compartor<U> keyComparator)
// comparing()을 사용하여 학생 스트림을 반별로 정렬하는 예시
studentStream
	.sorted(Compartor.comparing(Student::getBan)) // 반별로 정렬. 람다 표기: (Student s) -> s.getBan()
	.forEach(System.out::println);

추가 정렬 기준을 제공할 때는 thenComparing()을 사용

thenComparing(Comparator<T> other)
thenComparing(Function<T, U> keyExtractor)
thenComparing(Function<T, U> keyExtractor, Compartor<U> keyComparator)
// thenComparing 사용 예시 
studentStream
	.sorted(Compartor.comparing(Studentd::getBan)) // 반별로 정렬
	.thenComparing(Student::getTotalScore) // 총점별로 정렬
	.thenComparing(Student::getName) // 이름별로 정렬
	.forEach(System.out::println); 

sorted(), comparing() 사용 예제

package jungsuk_of_java.ch14_stream;

import java.util.Comparator;
import java.util.stream.Stream;

public class SortedComparingEx {
    public static void main(String[] args) {
        Stream<Student> studentStream = Stream.of(
                new Student("이자바", 3, 300),
                new Student("김자바", 1, 200),
                new Student("안자바", 2, 100),
                new Student("박자바", 2, 150),
                new Student("소자바", 1, 200),
                new Student("나자바", 3, 290),
                new Student("감자바", 3, 180)
        );

        studentStream.sorted(Comparator.comparing(Student::getBan)
                .thenComparing(Comparator.naturalOrder()))
                .forEach(System.out::println);

        /* 실행 결과
            [김자바, 1, 200]
            [소자바, 1, 200]
            [박자바, 2, 150]
            [안자바, 2, 100]
            [이자바, 3, 300]
            [나자바, 3, 290]
            [감자바, 3, 180]
         */
    }
}

class Student implements Comparable<Student> {
    String name;
    int ban;
    int totalScore;

    public Student(String name, int ban, int totalScore) {
        this.name = name;
        this.ban = ban;
        this.totalScore = totalScore;
    }

    public String getName() {
        return name;
    }

    public int getBan() {
        return ban;
    }

    public int getTotalScore() {
        return totalScore;
    }

    @Override
    public int compareTo(Student student) { // 총점 내림차순을 기본정렬로 한다.
        return student.totalScore - this.totalScore;
    }

    @Override
    public String toString() {
        return String.format("[%s, %d, %d]", name, ban, totalScore);
    }
}
profile
Every Run, Learn Counts.

0개의 댓글