0Pricing
Java Academy · 강의

partitioningBy와 counting

partitioningBy로 스트림을 두 그룹으로 나누고 counting으로 요소 수를 셉니다.

partitioningBy와 counting은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

partitioningBy 기본

Collectors.partitioningBy(predicate)는 stream을 정확히 두 그룹인 true와 false로 나누고 Map<Boolean, List<T>>을 반환합니다.

import java.util.*;
import java.util.stream.*;

List<Integer> nums = List.of(1,2,3,4,5,6,7,8,9,10);

Map<Boolean, List<Integer>> evenOdd =
    nums.stream().collect(Collectors.partitioningBy(n -> n % 2 == 0));

System.out.println(evenOdd.get(true));  // [2, 4, 6, 8, 10]
System.out.println(evenOdd.get(false)); // [1, 3, 5, 7, 9]

partitioningBy와 filter 비교

filter와 달리 partitioningBy는 두 그룹을 동시에 유지하므로 분할된 양쪽이 모두 필요할 때 유용합니다.

record Student(String name, int score) {}
List<Student> students = List.of(
    new Student("Alice",90), new Student("Bob",55),
    new Student("Carol",72), new Student("Dave",48)
);

Map<Boolean, List<Student>> result =
    students.stream().collect(
        Collectors.partitioningBy(s -> s.score() >= 60)
    );
System.out.println("Passed: " + result.get(true).size());
System.out.println("Failed: " + result.get(false).size());

partitioningBy와 다운스트림 수집기

groupingBy와 마찬가지로 partitioningBy를 다운스트림 수집기와 결합합니다:

Map<Boolean, Long> passFailCount =
    students.stream().collect(
        Collectors.partitioningBy(
            s -> s.score() >= 60,
            Collectors.counting()
        )
    );
System.out.println("Passed: " + passFailCount.get(true));
System.out.println("Failed: " + passFailCount.get(false));

counting() 수집기

Collectors.counting()은 stream(또는 다운스트림 그룹)의 요소 수를 셉니다. 이는 reducing(0L, e -> 1L, Long::sum)과 같은 기능을 편리하게 제공하는 방식입니다.

long count = Stream.of("a","bb","ccc","dddd")
    .collect(Collectors.counting());
System.out.println(count); // 4

// Same as:
long count2 = Stream.of("a","bb","ccc","dddd").count();
// Use counting() as a downstream; use .count() as a terminal op

다운스트림으로 사용하는 counting()

counting()은 groupingBy/partitioningBy의 다운스트림 수집기로 사용할 때 특히 유용합니다:

List<String> words = List.of("cat","dog","car","door","cup","dune");

Map<Character, Long> byFirstLetter =
    words.stream().collect(
        Collectors.groupingBy(w -> w.charAt(0), Collectors.counting())
    );
byFirstLetter.forEach((c, n) -> System.out.println(c + ": " + n));
// c: 3, d: 3

이름으로 분할하기

mapping 다운스트림 수집기를 사용하여 각 분할에서 이름을 추출합니다:

Map<Boolean, List<String>> namesByPass =
    students.stream().collect(
        Collectors.partitioningBy(
            s -> s.score() >= 60,
            Collectors.mapping(Student::name, Collectors.toList())
        )
    );
System.out.println("Passed: " + namesByPass.get(true));
System.out.println("Failed: " + namesByPass.get(false));

counting과 summarizingInt 결합

Collectors.summarizingInt()는 한 번의 순회로 개수, 합계, 최솟값, 최댓값, 평균을 계산합니다:

IntSummaryStatistics stats =
    students.stream().collect(
        Collectors.summarizingInt(Student::score)
    );
System.out.println("Count: " + stats.getCount());
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());

실제 사용 사례: A/B 테스트 분할

A/B 테스트를 위해 사용자를 대조군과 처리군으로 분할합니다:

record User(String id, boolean isInTreatment) {}
List<User> users = List.of(
    new User("u1",true), new User("u2",false),
    new User("u3",true), new User("u4",false)
);

Map<Boolean, Long> split =
    users.stream().collect(
        Collectors.partitioningBy(User::isInTreatment, Collectors.counting())
    );
System.out.println("Treatment: " + split.get(true)); // 2
System.out.println("Control: " + split.get(false));  // 2

groupingBy + counting을 사용한 빈도 맵

각 요소의 등장 횟수를 셉니다(단어 빈도 맵):

List<String> words2 = List.of("apple","banana","apple","cherry","banana","apple");

Map<String, Long> freq =
    words2.stream().collect(
        Collectors.groupingBy(w -> w, Collectors.counting())
    );
freq.entrySet().stream()
    .sorted(Map.Entry.<String,Long>comparingByValue().reversed())
    .forEach(e -> System.out.println(e.getKey()+": "+e.getValue()));

partitioningBy는 항상 두 키를 반환합니다

groupingBy와 달리 partitioningBy는 두 그룹 중 하나가 비어 있어도 항상 true와 false 키가 모두 있는 맵을 반환합니다. 따라서 map.get(true)에서 NullPointerExceptions가 발생하는 것을 방지할 수 있습니다.

List<Integer> allEven = List.of(2,4,6);
Map<Boolean, List<Integer>> m =
    allEven.stream().collect(Collectors.partitioningBy(n -> n % 2 != 0));
System.out.println(m.get(true));  // [] (empty, not null)
System.out.println(m.get(false)); // [2, 4, 6]

성능: 한 번의 순회

partitioningBy와 counting은 모두 한 번의 stream 순회로 동작하므로 O(n)입니다. 정렬이 필요하지 않습니다. 따라서 filter를 두 번 호출하거나 그룹화 전에 정렬하는 것보다 훨씬 효율적입니다.

빠른 확인

Collectors.partitioningBy(predicate)의 반환 유형은 무엇입니까?

복습: partitioningBy와 counting

핵심 내용:

  • partitioningBy는 정확히 두 그룹(true/false)으로 나눕니다
  • 두 키가 항상 존재하므로 groupingBy와 달리 NPE가 발생할 위험이 없습니다
  • counting()은 요소를 세며 그룹의 다운스트림 수집기로 사용할 수 있습니다
  • summarizingInt/Long/Double은 한 번의 순회로 개수+합계+최솟값+최댓값+평균을 제공합니다
  • 모두 한 번의 O(n) stream 순회로 동작합니다

자주 묻는 질문

“partitioningBy와 counting” 강의는 무료인가요?

네 — “partitioningBy와 counting” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“partitioningBy와 counting”에서 뭘 배우나요?

partitioningBy로 스트림을 두 그룹으로 나누고 counting으로 요소 수를 셉니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Java Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“partitioningBy와 counting” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. groupingBy: 요소 분류
  2. partitioningBy와 counting
  3. toMap, joining, summarizing
  4. 사용자 정의 수집기 만들기
← Java Academy(으)로 돌아가기