partitioningBy i counting
Dziel strumień na dwie grupy za pomocą partitioningBy i zliczaj elementy za pomocą counting.
partitioningBy i counting to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Podstawy partitioningBy
Collectors.partitioningBy(predicate) dzieli strumień dokładnie na dwie grupy — true i false — oraz zwraca 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 a filter
W przeciwieństwie do filter partitioningBy zachowuje jednocześnie obie grupy — jest to przydatne, gdy potrzebują Państwo obu części podziału.
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());Kolektor podrzędny z partitioningBy
Połącz partitioningBy z kolektorem podrzędnym tak samo jak groupingBy:
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));Kolektor counting()
Collectors.counting() zlicza liczbę elementów w strumieniu lub grupie podrzędnej. Jest wygodnym odpowiednikiem 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 opcounting() jako kolektor podrzędny
counting() szczególnie dobrze sprawdza się jako kolektor podrzędny dla 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: 3Podział na grupy nazw
Wyodrębnij nazwy z każdej części podziału, używając kolektora podrzędnego 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));Łączenie counting z summarizingInt
Collectors.summarizingInt() oblicza podczas jednego przejścia liczbę elementów, sumę, minimum, maksimum i średnią:
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());Praktyczny przypadek: podział testu A/B
Podziel użytkowników na grupę kontrolną i badaną na potrzeby testu 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)); // 2Mapa częstości z groupingBy + counting
Zlicz wystąpienia każdego elementu, tworząc mapę częstości słów:
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 zawsze zwraca oba klucze
W przeciwieństwie do groupingBy partitioningBy zawsze zwraca mapę zawierającą oba klucze true i false — nawet jeśli jedna grupa jest pusta. Zapobiega to wystąpieniu NullPointerException przy wywołaniu map.get(true).
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]Wydajność: jedno przejście
Zarówno partitioningBy, jak i counting działają podczas jednego przejścia strumienia — O(n). Nie wymagają sortowania. Dzięki temu są znacznie wydajniejsze niż dwukrotne wywołanie filter albo sortowanie przed grupowaniem.
Szybkie sprawdzenie
Jaki jest typ zwracany przez Collectors.partitioningBy(predicate)?
Podsumowanie: partitioningBy i counting
Najważniejsze informacje:
- partitioningBy dzieli elementy dokładnie na dwie grupy (true/false)
- Oba klucze są zawsze obecne — w przeciwieństwie do groupingBy nie ma ryzyka NPE
- counting() zlicza elementy; używaj go jako kolektora podrzędnego dla grup
- summarizingInt/Long/Double zwraca podczas jednego przejścia liczbę elementów, sumę, minimum, maksimum i średnią
- Wszystkie te operacje wykonują jedno przejście strumienia o złożoności O(n)
Ucz się Java dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 104
- Lekcje
- 374
Często zadawane pytania
Czy lekcja „partitioningBy i counting” jest bezpłatna?
Tak — pełny tekst „partitioningBy i counting” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „partitioningBy i counting”?
Dziel strumień na dwie grupy za pomocą partitioningBy i zliczaj elementy za pomocą counting. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „partitioningBy i counting”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- groupingBy: klasyfikowanie elementów
- partitioningBy i counting
- toMap, joining i summarizing
- Tworzenie własnego kolektora