Ch14-17~22. 스트림 만들기
0. 목차
Chapter14. 람다와 스트림
Ch14 - 17. 스트림 만들기 : 컬렉션
Ch14 - 18. 스트림 만들기 : 배열
Ch14 - 19. 스트림 만들기 : 임의의 수
Ch14 - 20. 스트림 만들기 : 특정 범위의 정수
Ch14 - 21. 스트림 만들기 : 람다식 iterate(), generate()
Ch14 - 22. 스트림 만들기 : 파일과 빈 스트림
Ch14 - 17. 스트림 만들기 : 컬렉션
▶ Collection으로 부터 스트림을 만드는 방법
▷ Collection 인터페이스의 stream()으로 컬렉션을 데이터 소스로 하는 스트림 생성
Stream<E> stream() // Collection 인터페이스의 메서드
▷ 예시
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> intStream = list.stream(); // list를 데이터 소스로 하는 새로운 스트림 생성
// 스트림의 모든 요소를 출력
intStream.forEach(System.out::print); // forEach = 최종 연산, 12345를 출력
intStream.forEach(System.out::print); // ERROR, 최종 연산까지 다 한 스트림은 닫힘
// 스트림을 하나 더 생성하여 다시 출력
intStream = list.stream(); // list로부터 stream을 생성
intStream.forEach(System.out::print); // 12345 출력
Ch14 - 18. 스트림 만들기 : 배열
▶ 객체 배열로부터 스트림 생성하는 방법
▷ ()에 가변 인자를 넣어 스트림 생성
Stream<T> Stream.of(T...values)
▷ ()에 T[] 배열을 넣어 스트림 생성
Stream<T> Stream.of(T[]])
▷ ()에 T[] 배열을 넣어 스트림 생성
Stream<T> Arrays.stream(T[])
▷ ()에 범위를 넣어 스트림 생성
Stream<T> Arrays.stream(T[] array, int startInclusive, int endExclusive)
- 배열의 일부로만 stream을 생성
(T[] array, from, to)
from ≤ 범위 < to
- 배열의 일부로만 stream을 생성
▷ 예시
Stream<String> strStream1 = Stream.of("a", "b", "c"); // 가변 인자
Stream<String> strStream2 = Stream.of(new String[]{"a", "b", "c"}); // 배열
Stream<String> strStream3 = Arrays.stream(new String[]{"a", "b", "c"}); // 배열
Stream<String> strStream4 = Arrays.stream(new String[]{"a", "b", "c"}, 0, 3); // 배열의 범위
String[] strArr = {"a", "b", "c"};
Stream<String> strStream3 = Arrays.stream(strArr); // 배열
// 위의 두 줄을 합친 것
Stream<String> strStream3 = Arrays.stream(new String[]{"a", "b", "c"});
▶ 기본형 배열로부터 스트림 생성하는 방법
▷ ()에 가변 인자를 넣어 스트림 생성
IntStream IntStream.of(int...values)
▷ ()에 T[] 배열을 넣어 스트림 생성
IntStream IntStream.of(T[]])
▷ ()에 T[] 배열을 넣어 스트림 생성
IntStream Arrays.stream(T[])
▷ ()에 범위를 넣어 스트림 생성
IntStream Arrays.stream(T[] array, int startInclusive, int endExclusive)
▷ 예시
IntStream IntStream1 = IntStream.of(1, 2, 3); // 가변 인자
IntStream IntStream2 = IntStream.of(new int[]{1, 2, 3}); // 배열
IntStream IntStream3 = Arrays.stream(new int[]{1, 2, 3}); // 배열
IntStream IntStream4 = Arrays.stream(new int[]{1, 2, 3}, 0, 3); // 배열의 범위
▶ 실습
▷ 객체 배열로부터 스트림 생성
String[] strArr = {"a", "b", "c"};
Stream<String> strStream1 = Stream.of(strArr); // 가변 인자
Stream<String> strStream2 = Stream.of(strArr); // 배열
Stream<String> strStream3 = Arrays.stream(strArr); // 배열
Stream<String> strStream4 = Arrays.stream(strArr, 0, 2); // 배열의 범위
System.out.print("\nstrStream1 : ");
strStream1.forEach(System.out::print);
...
// console
strStream1 : abc
strStream2 : abc
strStream3 : abc
strStream4 : ab
▷ 기본형 배열로부터 스트림 생성
IntStream IntStream1 = IntStream.of(1, 2, 3); // 가변 인자
IntStream IntStream2 = IntStream.of(new int[]{1, 2, 3}); // 배열
IntStream IntStream3 = Arrays.stream(new int[]{1, 2, 3}); // 배열
IntStream IntStream4 = Arrays.stream(new int[]{1, 2, 3}, 0, 3); // 배열의 범위
System.out.print("\nIntStream1 : ");
IntStream1.forEach(System.out::print);
...
// console
IntStream1 : 123
IntStream2 : 123
IntStream3 : 123
IntStream4 : 123
▷ 기본형 배열이 아닌 넣어서 스트림 생성하면?
Integer[] intArr = {5, 6, 7}; // int[]는 안 됨 Integer[]!
Stream<Integer> IntegerStream1 = Stream.of(intArr); // 가변 인자
Stream<Integer> IntegerStream2 = Stream.of(intArr); // 배열
Stream<Integer> IntegerStream3 = Arrays.stream(intArr); // 배열
Stream<Integer> IntegerStream4 = Arrays.stream(intArr, 0, 2); // 배열의 범위
System.out.print("\nIntegerStream1 : ");
IntegerStream1.forEach(System.out::print);
...
// console
IntegerStream1 : 567
IntegerStream2 : 567
IntegerStream3 : 567
IntegerStream4 : 56
Integer[] intArr = {5, 6, 7};
- 사실상,
new Integer(5), new Integer(6), new Integer(7)
이게 들어 있는 것
▷ Stream vs IntStream
Stream<Integer>
에서 제공하는 기능 사용
Integer[] intArr = {5, 6, 7}; Stream<Integer> IntegerStream1 = Stream.of(intArr); System.out.println("average : " + IntegerStream1.average()); // average : OptionalDouble[6.0] 출력 System.out.println("sum : " + IntegerStream1.sum()); // sum : 18 출력 System.out.println("count : " + IntegerStream1.count()); // count : 3 출력
Stream<Integer>
은average(), sum(), count()
제공IntStream
에서 제공하는 기능 사용
int[] intStreamArr = {5, 6, 7}; IntStream IntStream1 = IntStream.of(intStreamArr); System.out.println("average : " + IntStream1.average()); // ERROR System.out.println("sum : " + IntStream1.sum()); // ERROR System.out.println("count : " + IntStream1.count()); // count : 3
IntStream
은count()
만 제공
Ch14 - 19. 스트림 만들기 : 임의의 수
▶ 난수를 요소로 갖는 스트림 생성하는 방법
▷ Random() 클래스 안에 정의 된 메서드 : 전범위
// ints()
Integer.MIN_VALUE <= ints() <= Integer.MAX_VALUE // Integer 최소값 ~ Integer 최대값, 사실상 전범위
// longs()
Long.MIN_VALUE <= longs() <= Long.MAX_VALUE
// doubles()
0.0 <= doubles() < 1.0
▷ 예시
IntStreamintStream = new Random().ints(); // 무한 스트림
intStream.limit(5).forEach(System.out::println); // 5개의 요소만 출력
IntStream intStream = new Random().ints(5); // 크기가 5인 난수 스트림을 반환
▷ Random() 클래스 안에 정의 된 메서드 : 지정 된 범위
// 무한 스트림
IntStream ints(int begin, int end)
LongStream longs(long begin, long end)
DoubleStream doubles(doubles begin, doubles end)
// 유한 스트림
IntStream ints(long streamSize, int begin, int end)
LongStream longs(long streamSize, long begin, long end)
DoubleStream doubles(long streamSize, doubles begin, doubles end)
▷ 예시
- 무한 스트림
public static void main(String[] args) { IntStream intStream = new Random().ints(); // 무한 스트림 intStream .limit(10) // 10개로 잘라주지 않으면 무한 스트림이라 계속 나옴 .forEach(System.out::println); } // console -153699236 -1092304517 316377933 2143750017 -2142552547 627585495 894908480 1368624216 -382157223 -1926506540
- 유한 스트림
public static void main(String[] args) { IntStream intStream = new Random().ints(10, 5, 10); // 유한 스트림, (10개만 출력, 5에서, 10-1까지) intStream .forEach(System.out::println); } // console 9 6 9 5 9 9 5 7 8 5
Ch14 - 20. 스트림 만들기 : 특정 범위의 정수
▶ 특정 범위의 정수를 요소로 갖는 스트림 생성하는 방법
▷ IntStream.range()
: from ≤ 범위 < to
(to 값 미포함)
IntStream intStream = IntStream.range(1, 5); // 1, 2, 3, 4
▷ IntStream.rangeClosed()
: from ≤ 범위 ≤ to
(to 값 포함)
IntStream intStream = IntStream.rangeClosed(1, 5); // 1, 2, 3, 4, 5
Ch14 - 20. 스트림 만들기 : 람다식 iterate(), generate()
▶ 람다식을 데이터 소스로 하는 스트림 생성하는 방법
▷ 이전 요소에 종속적 : iterate()
▷ iterate()
: 이전 요소를 seed로 해서 다음 요소를 계산
▷ iterate()
의 매개변수 : iterate(T seed, UnaryOperator f) // 초기값, 단항 연산자(입력1, 출력1)
Stream<Integer> evenStream = Stream.iterate(0, n -> n + 2); // 0, 2, 4, 6...
// 초기값이 0인 n -> n + 2 계산 원리
0 -> 0 + 2
2 -> 2 + 2
4 -> 4 + 2
6 -> 6 + 2
... // 무한 스트림
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f) // 무한 스트림, limit 같은 걸로 자르기 필요
▷ 이전 요소에 독립적 : generate()
▷ generate()
: seed 사용하지 않음
▷ generate()
의 매개변수 : generate(Supplier s) // 입력0, 출력1
Stream<Double> randomStream = Stream.generate(Math::random);
Stream<Integer> oneStream = Stream.generate(0 -> 1); // 1, 1, 1, 1, 1, 1... 무한 스트림
static <T> Stream<T> generate(Supplier<T> s) // 무한 스트림, limit 같은 걸로 자르기 필요
▶ 실습
▷ iterate()
로 홀수 10개 출력
public static void main(String[] args) {
Stream<Integer> intStream = Stream.iterate(1, n -> n + 2); // 짝수는 초기값 '0'으로 주면 됨
intStream.limit(10).forEach(System.out::println); // 무한 스트림이기 때문에 limit으로 10개 자르기 해 줌
}
// console
1
3
5
7
9
11
13
15
17
19
▷ generate()
로 ‘101’을 10개 출력
public static void main(String[] args) {
Stream<Integer> intStream = Stream.generate(() -> 101);
intStream.limit(10).forEach(System.out::println);
}
// console
101
101
101
101
101
101
101
101
101
101
Ch14 - 20. 스트림 만들기 : 파일과 빈 스트림
▶ 파일을 소스로 하는 스트림 생성하는 방법
▷ 파일 또는 디렉토리 경로를 주면 그것으로 스트림을 생성
Stream<Path> Files.list(Path dir) // Path에 파일 또는 디렉토리 작성
▷ lines() : 파일 내용을 라인 단위로 String으로 읽어 스트림을 생성
Stream<String> Files.lines(Path path)
Stream<String> Files.lines(Path path, Charset s)
Stream<String> lines() // BufferedReader 클래스의 메서드
▶ 비어있는 스트림 생성하는 방법
▷ empty() : 빈 스트림을 생성하여 반환
Stream emptyStream = Stream.empty();
long count = emptyStream.count();