0%

java8 스트림(stream)

stream은 함수와 람다 문법으로 쉽고 직관적인 결과를 도출할수 있도록 도와줍니다.
스트림은 데이터의 흐름 속에서 데이터를 가공 하고, 결과를 도출 해내는것이 전부입니다.

스트림 사용 방법

데이터 → 스트림 생성 → 가공 [ → 가공] → 결과

스트림 생성

스트림을 활용하려면 우선 데이터로부터 스트림을 만들어야합니다.

빈 스트림

1
Stream<String> stream = Stream.empty();

기본타입

Int, Long, Double 과 같은 기본타입의 스트림을 만들 수 있습니다.
제네릭을 사용하지 않으므로 오토박싱(auto-boxing)을 피할 수 있습니다.

1
2
IntStream intStream = IntStream.range(0, 5);
LongStream longStream = LongStream.of(0, 1, 2, 3, 4, 5);

오토박싱이 필요한경우는 아래와 같이 할 수 있습니다.

1
Stream<Integer> stream = IntStream.range(0, 5).boxed();

배열

1
2
String data = "Hi~ my name is wook";
Stream<String> stream = Stream.of(data.split(" "));

값을 직접 입력

1
Stream<String> stream = Stream.of("Hi~", "my", "name", "is", "wook");

Collection

컬렉션은 모두 stream 이 될 수 있습니다.

1
2
3
4
ArrayList<String> data = new ArrayList<String>(
Arrays.asList("Hi~", "my", "name", "is", "wook")
);
Stream<String> stream = data.stream();

Stream.builder()

빌더패턴을 제공합니다.

1
2
3
4
5
6
7
Stream<String> stream = Stream.<String>builder()
.add("Hi~")
.add("my")
.add("name")
.add("is")
.add("wook")
.build();

Stream.generate()

Supplier<T> 를 이용하여 스트림을 생성합니다.

1
2
Stream<String> stream = Stream.generate(() -> "Stream");
Stream<Double> stream = Stream.generate(Math::random);

! 이 방법은 무한개의 데이터가 스트림이 되므로 있으므로 항상 제한을 두는것이 좋습니다.

1
2
// 10개의 데이터
Stream<Double> stream = Stream.generate(Math::random).limit(10);

Stream.iterate()

Seed 값 (Integer) 과 lambda 표현식으로 스트림을 생성합니다.

1
Stream<Integer> stream = Stream.iterate(10, n -> n + 1);

! 이 방법은 무한개의 데이터가 스트림이 되므로 항상 제한을 두는것이 좋습니다.

1
2
// 10개의 데이터
Stream<Integer> stream = Stream.iterate(10, n -> n + 1).limit(10);

파일

파일로부터 읽는 라인 모두 스트림이 될 수 있습니다.

1
2
3
4
Stream<String> stream = Files.lines(
Paths.get("file.txt"),
Charset.forName("UTF-8")
);

스트림 연결

Stream.concat 을 이용해 두개의 스트림을 연결할 수 있습니다.

1
2
3
4
Stream<Integer> stream = Stream.concat(
Stream.of(1, 2, 3, 4),
Stream.of(5, 6, 7, 8)
);

스트림 가공

스트림으로 구성된 데이터를 조작합니다.

filter

스트림 내 요소들을 걸러냅니다.

1
2
3
4
5
6
7
public class Main {
public static void main(String... args) {
Stream.of(1, 2, 3, 4, 5, 6, 7)
.filter(n -> n % 2 > 0)
.forEach(System.out::println);
}
}

결과

1
2
3
4
1
3
5
7

map

스트림 내 요소를 가공하여 새로운 요소를 만들어냅니다.

1
2
3
4
5
6
7
public class Main {
public static void main(String... args) {
Stream.of(1, 2, 3, 4, 5, 6, 7)
.map(n -> n * 100)
.forEach(System.out::println);
}
}

결과

1
2
3
4
5
6
7
100
200
300
400
500
600
700

sorted

스트림 내 요소를 정렬합니다.

1
2
3
4
5
6
7
public class Main {
public static void main(String... args) {
Stream.of(4, 6, 8, 2, 1, 9, 5, 3, 7, 0)
.sorted((a, b) -> a - b)
.forEach(System.out::println);
}
}

결과

1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9

스트림 결과

가공한 스트림을 이용해 결과를 도출하는 최종 작업 입니다.

연산

1
2
long count = IntStream.of(1, 2, 3, 4).count();
long sum = IntStream.of(1, 2, 3, 4).sum();

스트림이 비어있는경우의 연산은 Optional 을 이용하여 처리 합니다.

1
2
OptionalInt min = IntStream.of(1, 2, 3, 4).min();
OptionalInt max = IntStream.of(1, 2, 3, 4).max();

또는 ifPresent 를 이용하여 Optional 을 바로 처리할 수 있습니다.

1
2
3
4
5
6
7
public class Main {
public static void main(String... args) {
IntStream.of(1, 2, 3)
.average()
.ifPresent(System.out::println);
}
}

누산

reduce 를 활용해 스트림의 데이터를 계산하여 그 결과를 반환 합니다.

컬렉션

collection 으로 데이터를 반환합니다.

비교

데이터의 결과값을 boolean 으로 도출합니다.

순회

forEach 함수를 통해 컬렉션을 순회합니다.