いまさらながらOptionalに触る機会があったので覚書です
Optionalクラス
- nullかもしれない値をラップすることで、その値がnullかもしれないことを示すクラス。java8から登場
-
modelクラスのgetterやdaoからの戻り値がこのクラスでラップされていると扱いやすい(と感じています)
例
ユーザが無職(jobがnull)である場合があるので、
Optional
クラスを使ってgetterの戻り値の型String
をラップし、Optional.ofNullable()
を使ってOptional
型のインスタンスを返却-
Optional
型のインスタンスを作成するには、下記のメソッドを使用する- Optional.of():値がnullではないと分かっている時
- Optional.ofNullable():値がnullかもしれない時
- Optional.empty():値がnullの時
User.java
public class User {
private String name;
private String job;
public User(String name, String job) {
this.name = name;
this.job = job;
}
public Optional<String> getName() { return Optional.ofNullable(name); }
public void setName(String name) { this.name = name; }
public Optional<String> getJob() { return Optional.ofNullable(job); }
public void setJob(String job) { this.job = job; }
}
- 取得した
Optional
型のインスタンスの値を扱いたい-
Optional
型のインスタンスの値がnullかもしれないのでチェックする-
Optional.isPresent()
:Optional
型のインスタンスに値があればtrue、なければfalse
-
-
Optional
型のインスタンスの値を取り出す-
Optional.get()
:値の取り出し -
Optional.orElse(デフォルト値)
:値がnullの場合はデフォルト値を返す
-
-
Main.java
public class Main {
public static void main(String[] args) {
User user = new User(null, null);
System.out.println("name:" + user.getName().orElse("anonymouse"));
if(user.getJob().isPresent()) {
System.out.println("job:" + user.getJob().get());
} else {
System.out.println("job:neet");
}
}
}
-
if文が出てきてちょっとコードがスマートじゃない・・・時はラムダを使ってスッキリさせられる
-
Optional.ifPresent
:Consumerを引数に取り、値がある時だけ処理を行う -
Optional.ifPresentOrElse
:ConsumerとRunnableを引数に取り、値がある時はConsumerの処理、ない時はRunnableの処理が実行される
-
Main.java
user.getJob().ifPresent(job -> System.out.println("job:" + job));
user.getJob().ifPresentOrElse(job -> System.out.println("job:" + job), () -> System.out.println("job:neet"));
- コレクションで
Oprional
を扱う- コレクションの
Oprional
からstreamを直接作成できる - streamの
map()
のようにそのままmap()
を呼び出すと、Optional<Optional<?>>
のようにOptional
の入れ子になってしまうので、flatMap()
を使用して展開する-
Optional.stream
:ストリームを作成する -
Optional.flatMap
:Functionを引数に取り、Optional
から値を取り出して新しいOptional
を作成する
-
- コレクションの
Main.java
Optional<List<User>> userList = Optional.of(Arrays.asList(new User("taro", "engineer"), new User(null, null)));
userList.stream().flatMap(userMap -> userMap.stream()).forEach(u -> System.out.println(u.getJob().orElse("nothing")));