CS/Java
[Java] 스트림(Stream)
싱브이
2024. 2. 19. 13:34
728x90
반응형
자바 프로젝트를 하면서 아주아주 유용하게 사용하고 있는 람다식과 스트림(둘 다 Java 8부터 추가됨)을 확실하게 정리해버리게 나을 것 같아서 글을 적기로 한다 !
1. 람다식 (lambda expression)
2. 스트림 (stream)
스트림
연속되는 요소들의 흐름으로 배열, 콜렉션, 파일 등에서 만들어질 수 있다.
- Java 8부터 추가됨
- 컬렉션(배열 등)의 저장 요소를 하나씩 참조하여 람다식으로 처리할 수 있도록 해주는 반복자 (Iterator와 비슷한 역할로 코드 간결하게 할 수 있음)
* Iterator와의 차이점
스트림은 내부 반복자를 사용하므로 병렬처리가 쉽다.
스트림 사용법
1. 배열
//배열 : 정적 메서드 이용 (Arrays.stream)
String[] array = new String[]{"a", "b", "c"};
Stream<String> stream1 = Arrays.stream(array);
Stream<String> stream2 = Arrays.stream(array, 1, 3); // 인덱스 1포함, 3제외 ("b", "c")
stream1.forEach(a -> System.out.print(a + ","));
2. 컬렉션 (클래스)
class Student {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() { return name; }
public int getScore() { return score; }
}
public class FromCollectionExample {
public static void main(String[] args) {
List<Student> studentList = Arrays.asList(
new Student("사람1", 10),
new Student("사람2", 20),
new Student("사람3", 30)
);
// 스트림 객체 생성
Stream<Student> stream = studentList.stream();
stream.forEach(s -> System.out.println("이름 : "+ s.getName()));
}
}
3. 빌더
String<String> stream = Stream<String>builder()
.add("Apple")
.add("Banana")
.build();
4. Generator
Stream<String> stream = Stream.generate(() -> "Hi").limit(5);
5. Iterator
// (100, 110, 120, 130, 140)
Stream<String> stream = Stream.iterate(100, n -> n + 10).limit(5);
예제)
홀수만 골라내어 정렬하여 문자열로 만들기 (1, 3, 5..)
List<Integer> int0To9 = new ArrayList<>(
Arrays.asList(5, 2, 0, 8, 4, 1, 7, 9, 3, 6)
);
// 기존의 방식
List<Integer> odds = new ArrayList<>();
for (var i : int0To9) {
if (i % 2 == 1) odds.add(i);
}
odds.sort(Integer::compare);
List<String> oddsStrs = new ArrayList<>();
for (var i : odds) {
oddsStrs.add(String.valueOf(i));
}
var oddsStr = String.join(", ", oddsStrs);
// 스트림을 이용한 방식
var oddsStrStreamed = int0To9
.stream()
.filter(i -> i % 2 == 1)
.sorted(Integer::compare)
.map(String::valueOf)
.collect(Collectors.joining(", "));
스트림 연산
peek | 연산 과정 중에 스트림에 영향을 주지 않으면서 주어진 Consumer 작업을 실행한다. (쉽게 말해서 그냥 한번 해본다 ->중간에 로깅같은거에 사용) |
filter | 주어진 Predicate에 충족하는 요소만 남긴다. |
distinct | 중복되지 않는 요소들의 스트림을 반환 |
map | 주어진 Function에 따라 각 요소들을 변경 |
sorted | 요소들을 정렬 |
limit | 주어진 수 만큼의 요소들은 스트림으로 반환 |
skip | 주어진 개수만큼의 요소를 제거 |
takewhile / dropwhile | 주어진 Predicate을 충족하는 동안 갖거나 / 건너뛰거나 |
forEach | 각 요소들에 주어진 Consumer를 실행 (return 안함) |
count | 요소들의 개수를 반환 |
min / max | 주어진 Comparator에 따라 최소 / 최대값을 반환 |
reduce | 주어진 초기값과 BinaryOperator로 값들을 하나의 값으로 줄여나감 |
예제)
1. Peek
int sum = IntStream.range(1, 10)
.peek(System.out::println)
.sum();
2. Filter
Stream<Integer> stream = IntStream.range(1, 10).boxed();
stream.filter(v -> ((v % 2) == 0))
.forEach(System.out::println);
// 2, 4, 6, 8
3. Map
Stream<Integer> stream = IntStream.range(1, 10).boxed();
stream.filter(v -> ((v % 2) == 0))
.map(v -> v * 10)
.forEach(System.out::println);
// 20, 40, 60, 80
4. forEach
Set<Integer> evenNumber = IntStream.range(1, 1000).boxed()
.filter(n -> (n%2 == 0))
.forEach(System.out::println);
// 1~999까지 짝수 출력
728x90
반응형