Collection 인터페이스
Collections 인터페이스 구현체는 stream() 메서드 호출하여 Stream 객체로 변환한다
Stream<E> stream()
public interface Collection<E> extends Iterable<E> {
//..
default Stream<E> stream() {
return StreamSupport.stream(this.spliterator(), false);
}
//..
}
1) List
List<Person> people = List.of(new Person("고길동", 30), new Person("마이콜", 20), new Person("고희동", 5));
Stream<Person> personStream = people.stream();
2) Set
Set<Integer> integerSet = IntStream.range(1, 11).boxed().collect(Collectors.toSet()); // 1 ~ 10
Stream<Integer> integerStream = integerSet.stream();
3) Map
Map 구현체는 Collection 인터페이스 상속받지 않았기 때문에 keySet(), values(), entrySet() 통해 stream() 호출해야 한다
Map<String, Integer> testMap = new HashMap<>();
testMap.put("A", 1);
testMap.put("B", 2);
testMap.put("C", 3);
Stream<String> keyStream = testMap.keySet().stream();
Stream<Integer> valueStream = testMap.values().stream();
Stream<Map.Entry<String, Integer>> entryStream = testMap.entrySet().stream();
배열(Array)
1) Stream.class
- 가변 인자 전달하여 생성
- 내부적으로 Arrays.stream(T[] array) 호출
static <T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
of(..)
Stream<Integer> ints = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> integers = Stream.of(new Integer[] {6, 7, 8, 9, 10});
Person[] people = {
new Person("고길동", 30),
new Person("마이콜", 20),
new Person("고희동", 5)
};
Stream<Person> personStream = Stream.of(people);
2) Arrays.class
Stream<T> Arrays.stream(T[])
public static <T> Stream<T> stream(T[] array) {
return stream((Object[])array, 0, array.length);
}
// 사용 예시
Stream<String> stringStream = Arrays.stream(new String[] {"가", "나", "다"});
Stream<Integer> integerStream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5});
Stream Arrays.stream(T[] array, int startInclusive, int endExclusive)
public static <T> Stream<T> stream(T[] array, int startInclusive, int endExclusive) {
return StreamSupport.stream(spliterator(array, startInclusive, endExclusive), false);
}
// 사용 예시
Stream<Integer> interStream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5}, 1, 3); // [2, 3]
- end 는 exclusive(제외)이다
기본형(Primitive type) 스트림 생성
생성 메서드
IntStream IntStream of(int... values)
IntStream Arrays.stream(int[])
IntStream Arrays.stream(int[] array, int startInclusive, int endExclusive)
IntStream range(int startInclusive, int endExclusive)
IntStream rangeClosed(int startInclusive, int endInclusive)
- LongStream 의 경우 파라미터 타입이 long, DoubleStream 의 경우 파라미터 타입이 double 정도의 차이를 보인다
1) of(..)
IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
LongStream longStream = LongStream.of(11L, 22L, 33L);
DoubleStream doubleStream= DoubleStream.of(1.1, 2.2, 3.3);
2) Arrays.stream(..)
Stream<String> stringStream = Arrays.stream(new String[] {"가", "나", "다"});
Stream<Integer> integerStream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5});
Stream<Integer> integerStream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5}, 1, 3); // [2, 3]
- 범위를 지정하는 경우 to는 exclusive(제외) 하고 생성한다
3) range(..)
- from ~ to - 1 까지 범위 내의 요소를 가진 스트림 생성
- to 가 exclusive(제외) 된다
- IntStream, LongStream 지원 (DoubleStream은 x)
static IntStream range(int startInclusive, int endExclusive) {
return startInclusive >= endExclusive ? empty() : StreamSupport.intStream(new Streams.RangeIntSpliterator(startInclusive, endExclusive, false), false);
}
// 사용 예시
int[] numbers = IntStream.range(1, 5).toArray(); // [1, 2, 3, 4]
assertThat(numbers).hasSize(4);
assertThat(numbers).containsExactly(1, 2, 3, 4);
4) rangeClosed(..)
- from ~ to - 1 까지 범위 내의 요소를 가진 스트림 생성
- range와 차이점은 to가 inclusive(포함) 된다
- IntStream, LongStream 지원 (DoubleStream은 x)
static IntStream rangeClosed(int startInclusive, int endInclusive) {
return startInclusive > endInclusive ? empty() : StreamSupport.intStream(new Streams.RangeIntSpliterator(startInclusive, endInclusive, true), false);
}
// 사용 예시
long[] longs = LongStream.rangeClosed(10L, 15L).toArray(); // [10L, 11L, 12L, 13L, 14L, 15L]
assertThat(longs).hasSize(6);
assertThat(longs).containsExactly(10L, 11L, 12L, 13L, 14L, 15L);
난수 스트림 생성 (Random 클래스 활용)
1) 무한 스트림 생성 메서드
IntStream ints();
LongStream longs();
DoubleStream doubles();
예시
- int 범위 내의 난수 출력
- 무한 스트림을 생성하기 때문에 limit()로 elements 수 제한
List<Integer> integerValues = new Random().ints().limit(5).boxed().collect(Collectors.toList());
assertThat(integerValues).hasSize(5);
System.out.println(integerValues); // [1795705658, -1846049641, -435549310, -1243732334, -1718129831]
2) 유한 스트림 생성 메서드
IntStream ints(long streamSize); // 사이즈 개수만큼 요소 생성
LongStream longs(long streamSize);
DoubleStream doubles(long streamSize);
IntStream ints(long streamSize, int begin, int end); // 범위 지정시 end는 exclusive(제외)
LongStream longs(long streamSize, int begin, int end);
DoubleStream doubles(long streamSize, int begin, int end);
예시
마찬가지로 long과 double 범위 내 난수를 지정한 elements 수 만큼 생성
long[] longValues = new Random().longs(5).toArray();
List<Double> doubleValues = new Random().doubles(10).boxed().collect(Collectors.toList());
assertThat(longValues).hasSize(5);
assertThat(doubleValues).hasSize(10);
System.out.println(Arrays.toString(longValues));
System.out.println(doubleValues);
// 출력 결과
[-988333197112617847, -6426412998368006415, 3004887402415624804, -119315104063414599, -5575395704719870242]
[0.4093800146077434, 0.4265407624426173, 0.8426462399400118, 0.40285476473105064, 0.26415518341622524, 0.7699068907586042, 0.0319713300902309, 0.7240449685674681, 0.3745949044913478, 0.8857594640391309]
Stream.iterate(..) 와 Stream.generate(..)
둘 다 무한 스트림 생성하기 때문에 limit() 와 같은 elements 수를 지정하여 사용해야 한다
1) Stream.iterate(..)
- 이전 요소에 종속적인 형태
- seed에 초기값 설정, 람다식 인자로 전달하면 elements 수 만큼 결과값을 구함
- 이때 iterate의 반환 타입은 Stream<T> 이다
// Stream.class
static <T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) { .. }
// 서용 예시
int[] numbers = Stream.iterate(0, x -> x + 2).limit(5).mapToInt(v -> v).toArray();
assertThat(numbers).hasSize(5);
assertThat(numbers).isInstanceOf(int[].class);
assertThat(numbers).containsExactly(0, 2, 4, 6, 8);
2) Stream.generate(..)
- 이전 요소에 독립적
- Supplier 인자에 전달 함수 값을 가져와 리턴 (T get())
- 마찬가지로 반환 타입은 Stream<T>
// Stream.class
static <T> Stream<T> generate(Supplier<? extends T> s) {
Objects.requireNonNull(s);
return StreamSupport.stream(new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef(Long.MAX_VALUE, s), false);
}
// 사용 예시
// nextInt(int n) : 0 ~ n 사이의 수 중 하나
// generate 또한 infinite stream 이므로 수량 제한 필요
Random random = new Random();
int[] randomNumber = Stream.generate(() -> random.nextInt(100)).limit(5).mapToInt(v -> v).toArray();
assertThat(randomNumber).hasSize(5); // Ok
파일 소스로 Stream 생성하는 방법은 추후 포스팅
https://mkyong.com/java8/java-8-stream-read-a-file-line-by-line/
https://mkyong.com/java/how-to-read-and-parse-csv-file-in-java
참고
https://www.youtube.com/watch?v=AOw4cCVUJC4&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=164
https://howtodoinjava.com/java/stream/primitive-type-streams/
'공부 > Java' 카테고리의 다른 글
[Java] Stream 최종 연산(Terminal Operation) (0) | 2023.08.05 |
---|---|
[Java] Stream 중간 연산 (Stream Intermediate Operation) (0) | 2023.08.03 |
[Java] Stream API (0) | 2023.08.03 |
[Java] 람다식을 더 짧게 - 메서드 참조 Method Reference (0) | 2023.08.02 |
[Java] Optional 클래스 메서드 (자바의 정석) (0) | 2023.08.01 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!