상세 컨텐츠

본문 제목

[JAVA] 스트림(Stream) 중간연산, 최종연산 메소드 - (2)

Spring/JAVA

by Chan.94 2024. 2. 12. 23:02

본문

반응형

Stream 개념 : [Spring/JAVA] - [JAVA] 스트림(Stream)이란 - (1)


중간연산 메소드

요소의 범위를 줄이는 작업을 먼저 실행하는 것이 불필요한 연산을 막을 수 있어 성능을 향상할 수 있다.

이런 메소드로는 skip, filter, distinct 등이 있다.

스트림 자르기

Skip (long n) 

처음 n개의 요소 건너뛰기

 

Limit (long maxSize)

스트림의 요소를 maxSize개로 제한

IntStream exampleStream1 = IntStream.rangeClosed(1, 10);     // 1~10의 요소를 가진 스트림
exampleStream1.skip(3).limit(5).forEach(System.out::print);  // 45678

 

스트림 요소 걸러내기

distinct()

스트림에서 중복된 요소들 제거

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

 

filter()

주어진 조건에 맞지 않는 요소를 걸러낸다.

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

 

스트림 정렬

sorted(Comparator<? super T> comparator)

class Student{
    private String name;
    private int age;
    private String getName() {
        return name;
    }
    private int getAge() {
        return age;
    }
    private Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void print() {
        System.out.print(String.format("[name : %s, age : %d]", this.name, this.age));
    }
}

private Stream<Student> genrateStudentStream() {
    Stream<Student> stream = Stream.<Student>builder()
            .add(new Student("Kim", 15))
            .add(new Student("Park", 18))
            .add(new Student("Lee", 17))
            .build();
    
    return stream;
}

 

오름차순 정렬

defualt

Stream<Student> studentStream1 = genrateStudentStream();
//[name : Kim, age : 21][name : Park, age : 18][name : Lee, age : 17][name : Kim, age : 15]
studentStream1.sorted(Comparator.comparing(Student::getName))//이름 오름차순
              .forEach(Student::print);     
//[name : Kim, age : 21][name : Kim, age : 15][name : Lee, age : 17][name : Park, age : 18]

 

내림차순 정렬

reversed()

Stream<Student> studentStream2 = genrateStudentStream();
//[name : Kim, age : 21][name : Park, age : 18][name : Lee, age : 17][name : Kim, age : 15]
studentStream2.sorted(Comparator.comparing(Student::getName).reversed())//이름 내림차순
              .forEach(Student::print);     
//[name : Park, age : 18][name : Lee, age : 17][name : Kim, age : 21][name : Kim, age : 15]

 

정렬조건 추가

thenComparing()

Stream<Student> studentStream3 = genrateStudentStream();
//[name : Kim, age : 21][name : Park, age : 18][name : Lee, age : 17][name : Kim, age : 15]
studentStream3.sorted(Comparator.comparing(Student::getName)        //이름 오름차순
                                .thenComparing(Student::getAge))    //나이 오름차순
              .forEach(Student::print);     
//[name : Kim, age : 15][name : Kim, age : 21][name : Lee, age : 17][name : Park, age : 18]

 

스트림 변환

map()

스트림의 요소에 저장된 값 중에서 원하는 필드만 뽑아내거나, 특정 형태로 변환해야 할 때 사용한다.

map()은 여러 번 사용 가능하다.

Stream<Student> studentStream4 = genrateStudentStream();
//[name : Kim, age : 21][name : Park, age : 18][name : Lee, age : 17][name : Kim, age : 15]
Stream<String> stringStream = studentStream4.map(Student::getName)
                                            .map(String::toUpperCase)   // 모두 대문자로 변환
                                            ; 
stringStream.forEach(System.out::print);	//KIMPARKLEEKIM

최종연산 메소드

최종 연산은 스트림의 요소를 소모해서 결과를 만든다. 그래서 최종 연산 후에는 스트림이 닫혀서 더이 상 사용할 수 없다.

 

출력

forEach()

반환 타입이 void이므로 스트림의 요소를 출력하는 용도로 많이 사용

 

검사

allMatch(), anyMatch(), noneMatch()

System.out.println(genrateStudentStream().anyMatch(data -> data.getAge() > 20));    //true
System.out.println(genrateStudentStream().anyMatch(data -> data.getAge() > 25));    //false

 

검색

findFirst(), findAny()

findFirst(), findAny() 둘 다 스트림 요소 중 조건에 일치하는 첫 번째 것을 반환한다.

병렬스트림의 경우 findFirst() 대신 findAny() 사용한다.

//[name : Kim, age : 21][name : Park, age : 18][name : Lee, age : 17][name : Kim, age : 15]
Optional<Student> student1 = genrateStudentStream().filter(data -> data.getAge() > 20)
                                                   .findFirst();
student1.get().print();	//[name : Kim, age : 21]


통계

count(), min(), max()

System.out.println("count : " + genrateStudentStream().count());	//count : 4
genrateStudentStream().max(Comparator.comparing(Student::getAge))
                      .get()
                      .print();	//[name : Kim, age : 21]
System.out.println();
genrateStudentStream().min(Comparator.comparing(Student::getAge))
                      .get()
                      .print();	//[name : Kim, age : 15]

연산

sum(), average()

double average = genrateStudentStream().mapToDouble(Student::getAge)
                                       .average()
                                       .getAsDouble();
System.out.println("average : " + average);	//average : 17.75
double sum = genrateStudentStream().mapToDouble(Student::getAge)
                                   .sum();
System.out.println("sum : " + sum);			//sum : 71.0

 

수집

collect()

collector는 Collector인터페이스를 구현한 것.

 

joining(delimiter)

String nameJoin1 = genrateStudentStream().map(Student::getName)
                                         .collect(Collectors.joining("\n"));   
System.out.println(nameJoin1);	//Kim\nPark\nLee\nKim

 

joining(delimiter, prefix, suffix)

String nameJoin2 = genrateStudentStream().map(Student::getName)
                                         .collect(Collectors.joining(", ", "{", "}"));   
System.out.println(nameJoin2);//{Kim, Park, Lee, Kim}

 

toList(), toArray()

List<Student> studentList = genrateStudentStream().collect(Collectors.toList());
for(Student student : studentList) {
    student.print();
}
System.out.println();
Student[] studentArr1 = genrateStudentStream().toArray(Student[]::new);  //OK
for(Student student : studentArr1) {
    student.print();
}
//Student[] studentArr = genrateStudentStream().toArray();              //ERROR

 

 

반응형

관련글 더보기

댓글 영역

>