스트림의 연산은 중간 연산과 최종 연산으로 나눌 수 있다.
중간 연산은 연산 결과를 스트림으로 반환하기 때문에 중간 연산을 연속해서 연결할 수 있다.
skip()
Stream<T> skip(long n)
처음 n개의 요소를 건너뛴다.
IntStream intStream = IntStream.rangeClosed(1,10); // 1~10의 요소를 가진 스트림 생성
intStream.skip(3).forEach(System.out::println); // 4 5 6 7 8 9 10
limit()
Stream<T> limit(long maxSize)
스트림의 요소를 maxSize개로 제한한다.
Stream<String> strStream = Arrays.stream(new String[]{"a","b","c","d"});
strStream.limit(2).forEach(System.out::print); // ab
filter()
Stream<T> filter(Predicate<? super T> predicate)
주어진 조건 (Predicate) 에 맞지 않는 요소를 걸러낸다.
IntStream intStream = IntStream.rangeClosed(1,10);
intStream.filter(i -> i%2==0).forEach(System.out::print); //246810
filter()은 다른 조건으로 여러 번 사용 가능.IntStream intStream = IntStream.rangeClosed(1,10); intStream.filter(i -> i%2==0).filter(i -> i%3==0).forEach(System.out::print); // 6 // 위의 식은 intStream.filter(i -> i%2==0 && i%3==0).forEach(System.out::print); 와 같다.
distinct()
Stream<T> distinct()
중복된 요소를 제거한다.
Stream<String> strStream = Arrays.stream(new String[]{"a","a","b","c","b","a"});
strStream.distinct().forEach(System.out::print); //abc
sorted()
Stream<T> sorted()
Stream<T> sotred(Comparator<? super T> comparator)
기본 정렬 (사전순 정렬) 혹은 지정된 Comparator로 스트림을 정렬한다.
Stream<String> strStream = Arrays.stream(new String[]{"dd","aaa","CC","cc","b"});
// 기본 정렬
strStream.sorted(); // CCaabccdd
// 역순 정렬
strStream.sorted(Comparator.reverseOrder()); // ddccbaaCC
// 길이순 정렬
strStream.sorted(Comparator.comparing(String::length)) //bddCCccaaa
정렬 예제
import java.util.Comparator;
import java.util.stream.Stream;
public class Main{
public static void main(String[] args) {
Stream<Student> studentStream = Stream.of(
new Student("s1",3,300),
new Student("s2",1,200),
new Student("s3",2,100),
new Student("s4",2,150),
new Student("s5",1,200)
);
studentStream.sorted(Comparator.comparing(Student::getGroup) // 반별 정렬
.thenComparing(Comparator.comparing(Student::getTotalScore))) // 점수별 정렬
.forEach(System.out::println);
}
}
class Student implements Comparable<Student>{
String name;
int group;
int totalScore;
public Student(String name, int group, int totalScore) {
this.name = name;
this.group = group;
this.totalScore = totalScore;
}
@Override
public String toString() {
return String.format("[%s,%d,%d]", name, group, totalScore);
}
public String getName() {
return name;
}
public int getGroup() {
return group;
}
public int getTotalScore() {
return totalScore;
}
public int compareTo(Student s){
return s.totalScore - this.totalScore;
}
}
/*
실행 결과
[s2,1,200]
[s5,1,200]
[s3,2,100]
[s4,2,150]
[s1,3,300]
*/
위의 예제는 먼저 반별로 정렬한 후, 총 점수로 정렬하는 코드이다.
map()
Stream<R> map(Function<? super T, ? extends R> mapper)
스트림 요소에 저장된 값 중에서 원하는 필드만 뽑아내거나 특정 형태로 변환할 때 사용한다.
예를 들어 File의 스트림에서 파일의 이름만 뽑아서 출력하고 싶을 때 사용하는 것이다.
// ** 파일 이름 뽑아서 출력 **
Stream<File> fileStream = Stream.of(new File("Ex1.java"), new File("Ex2.java"), new File("Ex1.txt"));
// map()으로 Stream<File> 을 Stream<String>으로 변환
Stream<String> filenameStream = fileStream.map(File::getName);
filenameStream.forEach(System.out::println);
/*
실행 결과
Ex1.java
Ex2.java
Ex1.txt
*/
// ** 파일 확장자 중복제거후 출력 **
Stream<File> fileStream = Stream.of(new File("Ex1.java"), new File("Ex2.java"), new File("Ex1.txt"));
fileStream.map(File::getName)
.filter(s -> s.indexOf('.')!= -1) // 확장자 없는것 제외
.map(s -> s.substring(s.indexOf('.')+1))
.map(String::toUpperCase) // 대문자로 변환
.distinct() // 중복 제거
.forEach(System.out::println);
/*
실행 결과
JAVA
TXT
*/