Mengubah Optional: map dan flatMap
Rangkai transformasi dengan map dan flatMap untuk memproses nilai tanpa pemeriksaan null.
Mengubah Optional: map dan flatMap adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.
Mentransformasi Optional: map dan flatMap
map() mentransformasi nilai di dalam Optional jika tersedia. flatMap() menghindari Optional bertingkat ketika transformasinya sendiri mengembalikan Optional.
map: Mentransformasi Nilai
map(Function) menerapkan fungsi pada nilai jika tersedia, lalu membungkus hasilnya dalam Optional baru. Metode ini mengembalikan nilai kosong jika sejak awal Optional juga kosong.
import java.util.Optional;
Optional<String> name = Optional.of("alice");
Optional<String> upper = name.map(String::toUpperCase);
System.out.println(upper.get()); // ALICE
Optional<Integer> length = name.map(String::length);
System.out.println(length.get()); // 5
// Empty in → empty out
Optional<String> empty = Optional.<String>empty().map(String::toUpperCase);
System.out.println(empty.isPresent()); // falseMerangkai Pemanggilan map
Beberapa pemanggilan map dapat merangkai transformasi dengan rapi tanpa pemeriksaan nilai kosong yang bertingkat.
import java.util.Optional;
record Address(String city, String country) {}
record User(String name, Address address) {}
User user = new User("Alice", new Address("New York", "US"));
// Chain of maps — safe even if any step returns null
Optional<String> city = Optional.ofNullable(user)
.map(User::address)
.map(Address::city)
.map(String::toUpperCase);
System.out.println(city.orElse("Unknown")); // NEW YORKflatMap: Menghindari Optional<Optional>
Jika fungsi pemetaan Anda mengembalikan Optional, gunakan flatMap agar tetap mendapatkan Optional datar, bukan Optional<Optional> bertingkat.
import java.util.Optional;
record User(String name, Optional<String> email) {}
User u = new User("Bob", Optional.of("bob@example.com"));
// map returns Optional<Optional<String>> — ugly!
Optional<Optional<String>> nested = Optional.of(u).map(User::email);
// flatMap flattens: Optional<String>
Optional<String> flat = Optional.of(u).flatMap(User::email);
System.out.println(flat.get()); // bob@example.comflatMap Nyata: Rangkaian Repositori
Pola umum: merangkai pencarian repositori ketika masing-masing mengembalikan Optional.
import java.util.Optional;
record Order(long id, long userId, double total) {}
record User(long id, String name, String email) {}
static Optional<Order> findOrder(long orderId) {
return orderId == 1 ? Optional.of(new Order(1, 42, 99.99)) : Optional.empty();
}
static Optional<User> findUser(long userId) {
return userId == 42 ? Optional.of(new User(42, "Alice", "a@co.com")) : Optional.empty();
}
Optional<String> email = findOrder(1)
.flatMap(o -> findUser(o.userId()))
.map(User::email);
System.out.println(email.orElse("Not found")); // a@co.comRingkasan map vs flatMap
Memilih antara map dan flatMap:
- Gunakan
mapketika fungsi mengembalikan nilai biasa (String, bilangan bulat) - Gunakan
flatMapketika fungsi mengembalikan Optional
import java.util.Optional;
// map: T → R
Optional.of("hello").map(String::toUpperCase); // Optional<String>
Optional.of("42").map(Integer::parseInt); // Optional<Integer>
// flatMap: T → Optional<R>
Optional.of("42").flatMap(s -> {
try { return Optional.of(Integer.parseInt(s)); }
catch (NumberFormatException e) { return Optional.empty(); }
}); // Optional<Integer> (not Optional<Optional<Integer>>)Parsing Aman dengan flatMap
Pola yang rapi: bungkus operasi berisiko yang mungkin gagal dalam Optional menggunakan flatMap.
import java.util.Optional;
static Optional<Integer> tryParseInt(String s) {
try { return Optional.of(Integer.parseInt(s)); }
catch (NumberFormatException e) { return Optional.empty(); }
}
Optional<String> input = Optional.of("123");
Optional<Integer> parsed = input.flatMap(JavaOptional::tryParseInt);
System.out.println(parsed.map(n -> n * 2).orElse(-1)); // 246
Optional<String> bad = Optional.of("abc");
Optional<Integer> failed = bad.flatMap(JavaOptional::tryParseInt);
System.out.println(failed.orElse(-1)); // -1Mengumpulkan Optional
Saring dan petakan aliran Optional untuk mengumpulkan hanya nilai yang tersedia.
import java.util.*;
import java.util.stream.*;
List<String> inputs = List.of("10", "abc", "25", "nope", "7");
List<Integer> numbers = inputs.stream()
.flatMap(s -> {
try { return Stream.of(Integer.parseInt(s)); }
catch (NumberFormatException e) { return Stream.empty(); }
})
.collect(Collectors.toList());
System.out.println(numbers); // [10, 25, 7]Penelusuran Objek Bertingkat
map dan flatMap membuat penelusuran graf objek yang dalam menjadi aman tanpa pemeriksaan nilai kosong yang merepotkan.
import java.util.Optional;
record Company(String name, Optional<Address> address) {}
record Address(String city, Optional<String> zipCode) {}
Company company = new Company(
"Acme Corp",
Optional.of(new Address("Austin", Optional.of("78701")))
);
String zip = Optional.of(company)
.flatMap(Company::address)
.flatMap(Address::zipCode)
.orElse("N/A");
System.out.println(zip); // 78701map untuk Konversi Tipe
map sangat berguna untuk mengonversi tipe nilai Optional—misalnya mengurai, memformat, atau mengekstrak subatribut.
import java.util.Optional;
import java.time.LocalDate;
// Parse a date from String safely
static Optional<LocalDate> parseDate(String s) {
try { return Optional.of(LocalDate.parse(s)); }
catch (Exception e) { return Optional.empty(); }
}
Optional<String> dateStr = Optional.of("2024-06-15");
Optional<Integer> year = dateStr
.flatMap(JavaOptional::parseDate)
.map(LocalDate::getYear);
System.out.println(year.orElse(-1)); // 2024Membangun Alur Data
Menggabungkan filter, map, dan flatMap membangun alur data yang ekspresif serta menangani ketiadaan pada setiap langkah tanpa pemeriksaan nilai kosong secara eksplisit.
import java.util.Optional;
record Product(String sku, String category, boolean inStock, double price) {}
static Optional<Product> findProduct(String sku) {
if ("LAPTOP-1".equals(sku))
return Optional.of(new Product("LAPTOP-1", "Electronics", true, 999.99));
return Optional.empty();
}
Optional<String> priceTag = findProduct("LAPTOP-1")
.filter(Product::inStock)
.filter(p -> p.price() < 2000)
.map(p -> String.format("%s: $%.2f", p.sku(), p.price()));
System.out.println(priceTag.orElse("Not available")); // LAPTOP-1: $999.99Pemeriksaan Singkat
Kapan Anda sebaiknya menggunakan flatMap daripada map pada Optional?
Rangkuman: Mentransformasi Optional: map dan flatMap
Hal-hal penting:
- map() mentransformasi nilai jika tersedia, lalu membungkus hasilnya dalam Optional
- flatMap() digunakan untuk fungsi yang mengembalikan Optional sehingga menghindari Optional bertingkat
- Rangkai beberapa map untuk transformasi multi-langkah tanpa pemeriksaan nilai kosong
- Gunakan flatMap untuk merangkai pemanggilan repositori/layanan yang mengembalikan Optional
- Gabungkan filter + map + flatMap untuk membangun alur data yang aman dari nilai kosong
- Gunakan flatMap Optional::stream untuk memasukkan Optional ke dalam alur stream
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Mengubah Optional: map dan flatMap” gratis?
Ya — teks lengkap “Mengubah Optional: map dan flatMap” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Mengubah Optional: map dan flatMap”?
Rangkai transformasi dengan map dan flatMap untuk memproses nilai tanpa pemeriksaan null. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Java Academy?
Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Mengubah Optional: map dan flatMap” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?
Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Alasan Optional Ada
- Membuat dan Memeriksa Optional
- Mengubah Optional: map dan flatMap
- Praktik Terbaik Optional