Stream API를 사용하기 위해서는 먼저 Stream을 생성해주어야 합니다.
이번 포스팅에서는 Java 8에서 추가된 스트림(Stream) 사용법에 대해 알아보겠습니다.
Stream생성하기 ❕
Stream을 생성하기 위해서는 다음과 같은 방법이 있습니다.
- 배열, 컬렉션, 빈스트림
- Stream.builder() , 람다식(Stream.generate()) , 람다식(Stream.iterate())
- 기본타입형 , String , 파일스트림
- 병렬스트림, 스트림연결하기
배열 Stream 생성
String[] arr = new String[]{"A", "B", "C"};
Stream<String> stream = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3); // 1~2 요소 [b,c]
배열 Stream은 Array 클래스에서 제공하는 Array.stream() 메서드를 활용하여 생성이 가능합니다.
Collection Stream 생성
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
Stream<String> parallelStream = list.parallelStream(); // 병렬 처리 스트림
컬렉션(Collection, List, Set)의 경우 stream() 메서드를 활용하여 생성이 가능합니다.
빈 Stream
Stream<String> stream= Stream.empty();
Stream<Integer> stream2 = Stream.empty();
empty()는 빈 스트림을 생성할 수 있습니다. 빈 Stream은 요소가 없을 때 null 대신 사용할 수 있습니다.
Stream.builder()
Stream<String> builderStream = Stream.<String>builder()
.add("java").add("python").add("JavaScript").add("C#")
.build(); // [java,python, JavaScript, C#]
Builder를 사용하면 스트림에 직접적으로 값을 넣어 생성할 수 있습니다.
builder() 메서드를 통해 Stream을 반환받습니다.
관련 메서드
- void accept(T) :스트림 빌더에 데이터 추가
- Stream.Builder <T> add(T) :스트림 빌더에 데이터 추가 후, 스트림 반환한다.
- Stream <T> build() : 스트림 빌더에 데이터 추가 종료 후 스트림 반환
Stream.iterate()
Stream.iterate(0, n->n+3)
.limit(4)
.forEach(System.out::println); // 0,3,6,9
iterate() 메서드는 파라미터로 초기 값과 값을 다루는 람다식을 받아 Stream을 생성합니다.
사이즈에 제한이 없기 때문에 limit() 메소드를 사용하여 사이즈를 제한해줘야 합니다.
limt()를 빼고 실행을 한다면 "OutOfMemoryError"가 발생합니다.
Stream.generate()
Steam.generate()는 iterate()와 다르게 초기값 없이 람다식의 계산값으로만 Stream을 생성합니다.
geneate()도 사이즈에 제한이 없기 때문에 limit() 메서드를 사용하여 사이즈를 제한해줘야 합니다.
원시 자료형(Primitive)
오토 박싱
List<Integer> list = new ArrayList<>();
list.add(1); // int -> Integer (boxing)
오토 박싱은 원시 타입의 데이터를 해당 Wrapper 클래스의 객체로 변환하는 것을 의미합니다.
언 박싱
Integer number = new Integer(100);
int sum = 10 + number; // Integer -> int (unboxing)
언박싱은 Wrapper 클래스를 원시 타입으로 변환하는 것을 의미합니다.
위와 같이 오토박싱과 언박싱은 자동으로 타입 변환이 필요하므로 명시적 타입변환을 하지 않아도 됩니다.
그러나 코드에서 보이지 않지만 boxing 된 값이 heap 영역에 저장되면서 저장과 가져오는 데 많은 탐색 과정이 필요합니다. 또한 오버헤드가 발생하여 처리 속도가 떨어질 수 도있습니다.
Stream <Integer> 나 Stream <String> 같이 제너릭(Generic)을 사용하면 리스트나 배열을 이용하여 기본 타입 스트림을 생성할 수 있습니다. 그러나 오토 박싱과 언박싱 등 문제점이 있기에 기본 타입에 대한 좋은 기능들을 지원하는 기본 타입형 스트림을 사용합니다.
기본 타입형 Stream
IntStream is = IntStream.range(1, 5); // [1, 2, 3, 4]
LongStream ls = LongStream.rangeClosed(1, 5); // [1, 2, 3, 4, 5]
- range : 끝 범위 포함 X
- rangeClosed : 끝 범위 포함 O
직접적으로 해당 타입의 스트림을 만들고, Generic을 사용하지 않기 때문에 불필요한 오토 박싱이 일어나지 않습니다.
Stream<Integer> boxedIntStream = IntStream.range(1, 5).boxed();
필요한 경우 boxed() 메서드를 사용하여 박싱처리도 할 수 있습니다.
DoubleStream ds = new Random().doubles(3);
IntStream is = new Random().ints(3);
LongStream ls = new Random().longs(3);
random 클래스를 이용하여 난수를 3가지 타입의 스트림(Intstream, LongStream, DoubleStream)으로 만들 수 있습니다.
문자열 스트림
IntStream charStream = "Stream API".chars();
Stream<String> stringStream = Pattern.compile(", ").splitAsStream("A, B, C"); // [A, B, C]
String을 이용하여 Stream을 생성할 수 있습니다.
문자열 스트림
try {
Stream<String> lineStream =
Files.lines(Paths.get("file.txt"),
Charset.forName("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
자바 Files 클래스의 lines 메서드는 각 해당 파일의 라인을 String 타입의 스트림으로 만들어 줍니다.
Stream.of(), ofNullalbe()
of() 메서드는 자바 9부터 제공하는 메서드입니다.
List<Integer> list = Arrays.asList(1, 2, 3);
Set<Integer> set = Set.of(1, 2, 3);
Map<Integer, String> map = Map.of(1, "A", 2, "B", 3, "C");
List, Set, Map을 of 팩토리 메서드를 이용해서 생성할 수 있습니다.
Stream<Integer> stream1 = Stream.of(1, 2, 3);
Stream<Integer> stream2 = Stream.of(1);
Stream<Integer> stream3 = Stream.ofNullable(1);
- Stream.of()를 통해서 여러 개의 인자를 넣을 수 있고 단일 인자도 가능합니다.
- Stream.of()의 경우 null을 넣을 수 없지만, ofNullable은 null을 넣을 수 있습니다.
Stream.of() 그리고 Arrays.stream() 지정된 어레이에서 순차 스트림을 만드는 데 일반적으로 사용되는 두 가지 방법입니다.
'Language > Java' 카테고리의 다른 글
[JAVA] Stream API에 대해 알아보기 _ Stream 최종 연산(집계) (4/5) (0) | 2024.05.18 |
---|---|
[JAVA] Stream API에 대해 알아보기 _ Stream 중간 연산(가공) (3/5) (0) | 2024.05.17 |
[JAVA] Stream API에 대해 알아보기 (1/5) (0) | 2024.05.15 |
[JAVA] 큰 수 다루기 (BigInteger, BigDecimal) (0) | 2024.05.13 |
[JAVA] char에서 String으로 변환하기 (value of() , charAt()) (0) | 2024.05.12 |