[Java]使用オプションTIPS!


最近開発時にOptionを使うことが多くなりました.Optionalがうまく使えば非常に強力な機能ですが、うまく使えないと無駄になります.
使用したからにはしっかり使いたいので、使い方を整理してみました.

1.Null値をOptional変数に割り当てる場合はOptionalです。empty()の使用

Optional<Sample> sampleVar = null; // Bad!

Optional<Sample> sampleVar = Optional.empty(); // Good!

2. Optional.get()を使用する場合は、まず値があるかどうかをチェックします。

if (sampleVar.isPresent()){
    sampleVar.get();
}else{
  // 
}

3.固定値を返すときにorElse()を使用します。また、isPresent()ではなくorElse()を使用します。

// Bad!
public static final String NO_VALUE = "UNKNOWN";  
 
pulic String findSample(Integer id){

    Optional<String> sampleVal = ... ;

    if (status.isPresent()) {
        return status.get();
    } else {
        return NO_VALUE;
    }
}  
// Good!
public static final String NO_VALUE = "UNKNOWN";  
 
pulic String findSample(Integer id){

    Optional<String> sampleVal = ... ;

    return sampleVal.orElse(NO_VALUE);
    }
}  

4.非固定値を使用する場合は、ORElse()ではなくORElseGet()を使用します。


orElse()を使用すると、外部値が空でなくても、orElse()に達していない場合でも、その内部にあるオブジェクトが生成されます.
// Bad!
 
pulic String findSample(Integer id){

    Optional<String> sampleVal = ... ;

    return sample.orElse(new Sample()); // sample이 빈 값이여도 orElse()을 호출하여 객체를 생성한다 => 낭비
}  
// Good!
 
pulic String findSample(Integer id){

    Optional<String> sampleVal = ... ;

    return sample.orElseGet(Sample::new); // sample이 빈 값이면 orElseGet()은 호출되지 않는다.
}  
}  
orElseGet()とは異なり、orElseGet()はSupplier関数型インタフェースをパラメータとして受け入れるため、ram多式またはmethod reprenceをパラメータに渡すことができる.

5. java.util.NoSuchElementExceptionを起動する場合はorElseThrow()を使用します(Java 10)

public String findSample(Integer id) {

    Optional<String> sample = ... ; 

    return sample.orElseThrow();
}  
Javaバージョンが8または9の場合、次の方法が使用できます.
public String findSample(Integer id) {

    Optional<String> sample = ... ; 

    return sample.orElseThrow(NoSuchElementException::new); 
}  

6.Optionalを使用してnullを参照する場合、orElse(null)を使用します。

// Bad!
 
Optional<Sample> sampleClass = ... ;

if (sampleMethod.isPresent()){
    myMethod.invoke(sampleClass.get(), ...);
}else{
	myMethod.invoke(null, ...);  
}
// Good!
 
Optional<Sample> sampleClass = ... ;

myMethod.invoke(sampleClass.get().orElse(null), ...);  

7.OptionalのisPresent()を使用する場合、存在しない場合は何もしない(else条件を使用しない)

// Bad!
 
Optional<Sample> sampleClass = ... ;

if (sampleMethod.isPresent()){
    System.out.println("Sample: " + sampleMethod.get());
}
// Good!
 
Optional<Sample> sampleClass = ... ;

sample.ifPresent(System.out::println); 

8.OptionalのisPresent()を使用する場合、else条件を使用する場合、を選択します。ifPresentOrElse()の使用(Java 9)

// Bad!
 
Optional<Sample> sampleClass = ... ;

if (sampleMethod.isPresent()){
    System.out.println("Sample: " + sampleMethod.get());
}else{
 	System.out.println("Status not found"); 
}  
// Good!
 
Optional<Sample> sampleClass = ... ;

sample.ifPresentOrElse(
  System.out::println, // if 절의 action
  () -> System.out.println("Status not found") // else 절의 action
); 

9.オプションが空の場合、他のオプションに戻りたい場合は、オプションです。使用or()(Java 9)


Optional.or()orElse()またはorElseGet()とは異なり、オプションを返します
// Good!
 
Optional<Sample> sampleClass = ... ;
Optional<Sample> dafaultSample = Optional.of("DEFAULT");

return sampleClass.or(() -> defaultSample);  

10.Lambdaを使用する場合はオプションです。使用orElse/orElseXXX

// Bad!
 
Optional<Sample> sampleClass = sampleClasses.stream()
  				     .filter(x -> p.getNumber < num)
                                     .findFirst();

if (sampleClass.isPresent()) {
    return sample.get().getName();
} else {
    sampleClass "NOT FOUND";
}
// Good!
 
Optional<Sample> sampleClass = ... ;

Optional<Sample> sampleClass = sampleClasses.stream()
  				     .filter(x -> p.getNumber < num)
                                     .findFirst();
                                     .orElse("NOT FOUND");