Java 8 Optional
Bài đăng này đã không được cập nhật trong 7 năm
Java 8 đã giới thiệu một lớp mới là Optional trong package java.util. Nó được sử dụng để đại diện cho một giá trị có mặt hoặc vắng mặt. Lợi ích chính của cấu trúc mới này là Không có quá nhiều kiểm tra null và tránh bất kỳ NullPointerExceptions xảy ra trong runtime. Do dó Optional hỗ trợ phát triển các API hoặc ứng dụng Java gọn gàng. Giống Collections và arrays, nó cũng là một Container để chứa tối đa một giá trị. Chúng ta hãy cùng khám phá cấu trúc mới này bằng một số ví dụ hữu ích sau đây.
Ưu điểm của Java 8 Optional:
- Không bắt buộc kiểm tra Null.
- Tránh NullPointerException ở runtime.
- Hỗ trợ phát triển các API một cách gọn gàng.
1. Ví dụ cơ bản về Java 8 Optional
Phương thức Optional.ofNullable() trả về một Non-empty Optional nếu giá trị hiện hữu, ngược lại sẽ trả về một empty Optional. Phương thức Optional.empty() tạo một đối tượng empty Optional.
package vuta.test;
import java.util.Optional;
public class OptionalBasicExample {
public static void main(String[] args) {
Optional<String> gender = Optional.of("MALE");
String answer1 = "Yes";
String answer2 = null;
System.out.println("Non-Empty Optional:" + gender);
System.out.println("Non-Empty Optional: Gender value : " + gender.get());
System.out.println("Empty Optional: " + Optional.empty());
System.out.println("ofNullable on Non-Empty Optional: " + Optional.ofNullable(answer1));
System.out.println("ofNullable on Empty Optional: " + Optional.ofNullable(answer2));
}
}
Output
Non-Empty Optional:Optional[MALE] Non-Empty Optional: Gender value : MALE Empty Optional: Optional.empty
ofNullable on Non-Empty Optional: Optional[Yes] ofNullable on Empty Optional: Optional.empty
2. Optional.map and flatMap
package vuta.test;
import java.util.Optional;
public class OptionalMapFlapMapExample {
public static void main(String[] args) {
Optional<String> nonEmptyGender = Optional.of("male");
Optional<String> emptyGender = Optional.empty();
System.out.println("Non-Empty Optional:: " + nonEmptyGender.map(String::toUpperCase));
System.out.println("Empty Optional :: " + emptyGender.map(String::toUpperCase));
Optional<Optional<String>> nonEmptyOtionalGender = Optional.of(Optional.of("male"));
System.out.println("Optional value :: " + nonEmptyOtionalGender);
System.out.println("Optional.map :: " + nonEmptyOtionalGender.map(gender -> gender.map(String::toUpperCase)));
System.out.println("Optional.flatMap :: " + nonEmptyOtionalGender.flatMap(gender -> gender.map(String::toUpperCase)));
}
}
Output
Non-Empty Optional:: Optional[MALE] Empty Optional :: Optional.empty Optional value :: Optional[Optional[male]] Optional.map :: Optional[Optional[MALE]] Optional.flatMap :: Optional[MALE]
3. Optional.filter
package vuta.test;
import java.util.Optional;
public class OptionalFilterExample {
public static void main(String[] args) {
Optional<String> gender = Optional.of("MALE");
Optional<String> emptyGender = Optional.empty();
//Filter on Optional
System.out.println(gender.filter(g -> g.equals("male"))); //Optional.empty
System.out.println(gender.filter(g -> g.equalsIgnoreCase("MALE"))); //Optional[MALE]
System.out.println(emptyGender.filter(g -> g.equalsIgnoreCase("MALE"))); //Optional.empty
}
}
Output
Optional.empty Optional[MALE] Optional.empty
4. Optional isPresent và ifPresent
Optional.isPresent() trả về true nếu đối tượng Optional khác rỗng, ngược lại trả về false. Optional.ifPresent() thực thi action nếu đối tượng Optional khác rỗng, ngược lại trả về false.
package vuta.test;
import java.util.Optional;
public class OptionalIfPresentExample {
public static void main(String[] args) {
Optional<String> gender = Optional.of("MALE");
Optional<String> emptyGender = Optional.empty();
if (gender.isPresent()) {
System.out.println("Value available.");
} else {
System.out.println("Value not available.");
}
gender.ifPresent(g -> System.out.println("In gender Option, value available."));
//condition failed, no output print
emptyGender.ifPresent(g -> System.out.println("In emptyGender Option, value available."));
}
}
Output
Value available. In gender Option, value available.
5. Optional orElse
package vuta.test;
import java.util.Optional;
public class OptionalOrElseExample {
public static void main(String[] args) {
Optional<String> gender = Optional.of("MALE");
Optional<String> emptyGender = Optional.empty();
System.out.println(gender.orElse("<N/A>")); //MALE
System.out.println(emptyGender.orElse("<N/A>")); //<N/A>
System.out.println(gender.orElseGet(() -> "<N/A>")); //MALE
System.out.println(emptyGender.orElseGet(() -> "<N/A>")); //<N/A>
}
}
Output
MALE <N/A> MALE <N/A>
6. Ví dụ khi không dùng Java 8 Optional
package vuta.test;
public class ScreenResolution {
private int width;
private int height;
public ScreenResolution(int width, int height){
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
package vuta.test;
public class DisplayFeatures {
private String size; // In inches
private ScreenResolution resolution;
public DisplayFeatures(String size, ScreenResolution resolution){
this.size = size;
this.resolution = resolution;
}
public String getSize() {
return size;
}
public ScreenResolution getResolution() {
return resolution;
}
}
package vuta.test;
public class Mobile {
private long id;
private String brand;
private String name;
private DisplayFeatures displayFeatures;
public Mobile(long id, String brand, String name,
DisplayFeatures displayFeatures){
this.id = id;
this.brand = brand;
this.name = name;
this.displayFeatures = displayFeatures;
}
public long getId() {
return id;
}
public String getBrand() {
return brand;
}
public String getName() {
return name;
}
public DisplayFeatures getDisplayFeatures() {
return displayFeatures;
}
}
package vuta.test;
public class MobileService {
public int getMobileScreenWidth(Mobile mobile){
//Check null, check null and check null :(
if(mobile != null){
DisplayFeatures dfeatures = mobile.getDisplayFeatures();
if(dfeatures != null){
ScreenResolution resolution = dfeatures.getResolution();
if(resolution != null){
return resolution.getWidth();
}
}
}
return 0;
}
}
7. Ốp Java 8 Optional vào
package vuta.test;
import java.util.Optional;
public class DisplayFeatures {
private String size; // Inches
private Optional<ScreenResolution> resolution;
public DisplayFeatures(String size, Optional<ScreenResolution> resolution){
this.size = size;
this.resolution = resolution;
}
public String getSize() {
return size;
}
public Optional<ScreenResolution> getResolution() {
return resolution;
}
}
package vuta.test;
import java.util.Optional;
public class Mobile {
private long id;
private String brand;
private String name;
private Optional<DisplayFeatures> displayFeatures;
public Mobile(long id, String brand, String name, Optional<DisplayFeatures> displayFeatures){
this.id = id;
this.brand = brand;
this.name = name;
this.displayFeatures = displayFeatures;
}
public long getId() {
return id;
}
public String getBrand() {
return brand;
}
public String getName() {
return name;
}
public Optional<DisplayFeatures> getDisplayFeatures() {
return displayFeatures;
}
}
package vuta.test;
import java.util.Optional;
public class MobileService {
public Integer getMobileScreenWidth(Optional<Mobile> mobile){
//ngon
return mobile.flatMap(Mobile::getDisplayFeatures)
.flatMap(DisplayFeatures::getResolution)
.map(ScreenResolution::getWidth)
.orElse(0);
}
}
All rights reserved