Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

스트림의 최종 연산 #44

Open
korjun1993 opened this issue Aug 20, 2023 · 0 comments
Open

스트림의 최종 연산 #44

korjun1993 opened this issue Aug 20, 2023 · 0 comments

Comments

@korjun1993
Copy link
Owner

korjun1993 commented Aug 20, 2023

스트림의 최종 연산

  • forEach
void forEach(Consumer<? super T> action)
  • 조건 검사
boolean allMatch(Predicate<? super T> predicate)
boolean anyMatch(Predicate<? super T> predicate)
boolean noneMatch(Predicate<? super T> predicate)
  • 필터링 결과 가져오기
// 조건에 일치하는 첫 번째 것을 반환한다.
stuStream.filter(s->s.getTotalScore() <= 100).findFirst();

// 병렬 스트림인 경우에는 findFirst 대신 findAny를 사용해야 한다.
stuStream.parallel().filter(s->s.getTotalScore() <= 100).findAny();
  • 통계
    IntStream과 같은 기본형 스트림에는 스트림의 요소들에 대한 통계 정보를 얻을 수 있는 메서드들이 있다. 그러나 기본형 스트림이 아닌 경우에는 통계와 관련된 메서드들이 아래의 3개뿐이다.
long count();
Optional<T> max(Comparator<? super T> comparator)
Optional<T> min(Comparator<? super T> comparator)
  • 리듀싱
    스트림의 요소를 줄여나가면서 연산을 수행하고 최종결과를 반환한다. 처음 두 요소를 가지고 연산한 결과를 가지고 그 다음 요소와 연산한다.
T reduce(T identity, BinaryOperator<T> accumulator) // identity: 초기값
U reduce(U identity, BiFunction<U, T, U> accumulator, BinaryOperator<U> combiner)

// 예시
int count = intStream.reduce(0, (a, b) -> a + 1); // count()
int sum = intStream.reduce(0, (a,b) -> a + b); // sum()
int max = intStream.reduce(Integer.MIN_VALUE, (a,b) -> a>b ? a:b); // max()
int min = intStream.reduce(Integer.MAX_VALUE, (a,b) -> a<b ? a:b); // min()

// for문으로 sum()을 표현하면 다음과 같다.
int a = identity // 초기값을 a에 저장한다.
for (int b : stream) {
   a = a + b; // 모든 요소의 값을 a에 누적한다.
}

// 즉, 일반화하면 다음과 같다.
T reduce(T identity, BinaryOperator<T> accumulator) {
   T a = identity;
   for (T b : stream) {
      a = accumulator.apply(a, b);
   }
   return a;
}
  • collector

    • collect()가 스트림의 요소를 수집한다. 이 때 어떻게 수집할 것인가에 대한 방법을 정의한 것이 컬렉터(collector)이다.
    • 컬렉터는 Collector 인터페이스를 구현한 것으로, 직접 구현할 수도 있고 미리 작성된 것을 사용할 수도 있다.
    • Collectors 클래스는 미리 작성된 다양한 종류의 컬렉터를 반환하는 static 메서드를 가지고 있다.
  • 스트림 → 컬렉션

// Collectors 클래스의 toList()와 같은 메서드를 사용하면된다.
List<String> names = stuStream.map(Student::getName).collect(Collectors.toList());

// Map으로 바꾸려면 어떤 필드를 키, 값으로 사용할지 지정해줘야 한다.
Map<String, Person> map = personStream.collect(Collectors.toMap(p -> p.getRegId(), p->p));
  • 스트림 → 배열
// 스트림에 저장된 요소들을 T[] 타입의 배열로 변환하려면, toArray()를 사용하면 된다.
// 단, 해당 타입의 생성자 참조를 매개변수로 지정해줘야 한다. 그렇지 않으면 Object[] 가 반환된다.
Student[] stuNames = studentStream.toArray(Student[]::new);
Student[] stuNames = studentStream.toArray(); // 에러
Object[] stuNames = studentStream.toArray();
  • 문자열 스트림 → 문자열
String studentNames = stuStream.map(Student::getName).collect(Collectors.joining());
String studentNames = stuStream.map(Student::getName).collect(Collectors.joining(","));

// Student의 toString()으로 결합
String studentInfo = stuStream.collect(Collectors.joining(","));
  • 분할
    • 스트림의 지정된 조건에 일치하는 그룹과 일치하지 않는 그룹으로 분할한다.
Collector partitioningBy(Predicate predicate)
Collector partitioningBy(Predicate predicate, Collector downstream)

// 학생들을 성별로 분할
Map<Boolean, List<Student>> stuBySex = stuStream.collect(Collectors.partitioningBy(Student::isMale));

List<Student> maleStudent = stuBySex.get(true);
List<Student> femaleStudent = stuBySex.get(false);

// 성별 학생들의 수
Map<Boolean, Long>> stuNumBySex = stuStream.collect(Collectors.partitioningBy(Student::isMale, Collectors.counting()));

long maleNum = stuNumBySex.get(true);
long femaleNum = stuNumBySex.get(false);

// 성별로 성적이 150점이 아래인 학생
Map<Boolean, Map<Boolean, List<Student>>> failedStuBySex = Stream.of(stuArr)
			.collect(Collectors.partitioningBy(Student::isMale, Collectors.partitioningBy(s -> s.getScore() <= 100)));
  • 그룹화
    • 스트림의 요소를 특정 기준으로 그룹화한다.
Collector groupingBy(Function classifer)
Collector groupingBy(Function classifer, Collector downstream)
Collector groupingBy(Function classifer, Supplier mapFactory, Collector downstream)

// 예시
// 1. 그룹화(반별)
Map<Integer, List<Student>> stuByBan = Stream.of(stuArr).collect(Collectors.groupingBy(Student2::getBan));

// 2. 그룹화(성적별)
Map<Student2.Level, List<Student2>> stuByLevel = Stream.of(stuArr).collect(Collectors.groupingBy(s -> {
			if (s.getScore() >= 200) {
				return Student2.Level.HIGH;
			} else if (s.getScore() >= 100) {
				return Student2.Level.MID;
			} else {
				return Student2.Level.LOW;
			}
		}));

// 3. 그룹화 + 통계(성적별 학생수)
Map<Student2.Level, Long> stuCntByLevel = Stream.of(stuArr).collect(Collectors.groupingBy(s -> {
			if (s.getScore() >= 200) {
				return Student2.Level.HIGH;
			} else if (s.getScore() >= 100) {
				return Student2.Level.MID;
			} else {
				return Student2.Level.LOW;
			}
		}, Collectors.counting()));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant