flatMap dla zagnieżdżonych kolekcji
Proszę spłaszczać zagnieżdżone listy, łańcuchy Optional i struktury wierszy plików za pomocą flatMap.
flatMap dla zagnieżdżonych kolekcji to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 1 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.
Problem z zagnieżdżonymi kolekcjami
Gdy każdy element strumienia jest mapowany na inną kolekcję, map daje w wyniku Stream<List<T>>. flatMap scala wewnętrzne strumienie w jeden płaski Stream<T>.
List<List<Integer>> nested = List.of(List.of(1,2), List.of(3,4), List.of(5));
// With map:
Stream<List<Integer>> s = nested.stream().map(l -> l); // Stream<List<Integer>>
// With flatMap:
Stream<Integer> flat = nested.stream().flatMap(List::stream); // Stream<Integer>
flat.forEach(System.out::println); // 1 2 3 4 5flatMap a map
map(f) stosuje f do każdego elementu i opakowuje wynik. flatMap(f) stosuje f, które zwraca strumień, a następnie łączy wszystkie te strumienie w jeden.
// map: List<String> -> Stream<Stream<Character>>
Stream<Stream<Character>> nested = List.of("hi","bye").stream()
.map(s -> s.chars().mapToObj(c -> (char)c));
// flatMap: List<String> -> Stream<Character>
Stream<Character> flat = List.of("hi","bye").stream()
.flatMap(s -> s.chars().mapToObj(c -> (char)c));Spłaszczanie zamówień i elementów
Typowy przypadek użycia: każde zamówienie ma listę elementów. Należy uzyskać płaski strumień wszystkich elementów ze wszystkich zamówień.
List<String> allItems = orders.stream()
.flatMap(order -> order.getItems().stream())
.collect(Collectors.toList());
System.out.println(allItems);flatMap z Optional
Użyj stream() na obiekcie Optional (Java 9+), aby przekształcić go w strumień zawierający 0 lub 1 element. Następnie flatMap przekształca Stream<Optional<T>> w Stream<T>.
List<Optional<String>> maybes = List.of(Optional.of("a"), Optional.empty(), Optional.of("c"));
List<String> values = maybes.stream()
.flatMap(Optional::stream) // Java 9+
.collect(Collectors.toList());
System.out.println(values); // [a, c]Odczytywanie wszystkich wierszy z wielu plików
flatMap ułatwia połączenie wszystkich wierszy z listy plików w jeden strumień bez zagnieżdżonych pętli.
List<Path> files = List.of(Path.of("a.txt"), Path.of("b.txt"));
List<String> allLines = files.stream()
.flatMap(p -> {
try { return Files.lines(p); }
catch (IOException e) { return Stream.empty(); }
})
.collect(Collectors.toList());Dzielenie ciągów znaków na słowa
Podziel każde zdanie na słowa i spłaszcz wszystkie słowa do jednego strumienia, aby zliczyć częstotliwość ich występowania.
List<String> sentences = List.of("hello world", "java streams rock");
Map<String, Long> freq = sentences.stream()
.flatMap(s -> Arrays.stream(s.split("\\s+")))
.collect(Collectors.groupingBy(w -> w, Collectors.counting()));
System.out.println(freq);flatMap z Map.entrySet
Spłaszcz mapę, w której kategoriom odpowiadają listy elementów, do strumienia zawierającego wszystkie elementy.
Map<String, List<String>> catalog = Map.of(
"fruit", List.of("apple","banana"),
"veg", List.of("carrot","pea"));
List<String> all = catalog.values().stream()
.flatMap(List::stream)
.sorted()
.collect(Collectors.toList());
System.out.println(all); // [apple, banana, carrot, pea]Unikanie NullPointerException w flatMap
Jeśli funkcja może zwrócić null zamiast strumienia, zastosuj sprawdzenie wartości null lub zwróć Stream.empty(), aby uniknąć NullPointerException.
departments.stream()
.flatMap(dept -> dept.getEmployees() == null
? Stream.empty()
: dept.getEmployees().stream())
.forEach(System.out::println);Zliczanie unikalnych słów za pomocą flatMap
Połącz flatMap, distinct i count w celu zwięzłego przetwarzania danych.
long distinctWords = sentences.stream()
.flatMap(s -> Arrays.stream(s.toLowerCase().split("[^a-z]+")))
.filter(w -> !w.isEmpty())
.distinct()
.count();
System.out.println("Distinct: " + distinctWords);flatMapToInt dla strumieni typów prymitywnych
Użyj flatMapToInt, flatMapToLong i flatMapToDouble, aby uniknąć autoboxingu podczas spłaszczania do strumieni typów prymitywnych.
int totalQuantity = orders.stream()
.flatMapToInt(order -> order.getItems().stream().mapToInt(Item::getQuantity))
.sum();
System.out.println("Total qty: " + totalQuantity);Uwaga dotycząca wydajności
Każde wywołanie flatMap dodaje warstwę strumienia. W przypadku bardzo dużych zbiorów danych z wieloma małymi kolekcjami wewnętrznymi należy rozważyć podejście iteracyjne lub Spliterator, aby ograniczyć narzut tworzenia obiektów.
Szybkie sprawdzenie
Co flatMap robi inaczej niż map?
Podsumowanie
flatMap konwertuje każdy element na strumień i scala wszystkie strumienie w jeden. Używaj go do spłaszczania zagnieżdżonych kolekcji, łączenia obiektów Optional, dzielenia ciągów znaków i odczytywania wielu plików. Użyj flatMapToInt, aby uniknąć autoboxingu.
Często zadawane pytania
Czy lekcja „flatMap dla zagnieżdżonych kolekcji” jest bezpłatna?
Tak — pełny tekst „flatMap dla zagnieżdżonych kolekcji” 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 „flatMap dla zagnieżdżonych kolekcji”?
Proszę spłaszczać zagnieżdżone listy, łańcuchy Optional i struktury wierszy plików za pomocą flatMap. Ć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 1 z 4.
Ile czasu zajmuje lekcja „flatMap dla zagnieżdżonych kolekcji”?
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
- flatMap dla zagnieżdżonych kolekcji
- Strumienie równoległe: wydajność i pułapki
- Spliterator: dzielenie na potrzeby równoległości
- Nieskończone strumienie za pomocą iterate i generate