0. 最初に
開発経験のない新入社員が突然、現場に放り込まれて「簡単な開発だから」と任されたけど、わからなさすぎて泣き寝入り状態だったので、自分の研鑽かつ同様の境遇の人達を救うためJava8(Optional編)についてまとめた。
0.5. ラムダ式
Optionalを記す前に、ラムダ式といったものの説明をしないとだめだと気付きました。
ラムダ式をひとことで表すと、、、省略して、矢印みたいになってるもの
({引数} -> {処理})
こんな感じです。
サンプルコードを作ってみると
これがインターフェースで
interface Color{
void printColor();
}
これが匿名クラス(匿名クラスとはこちら)
public static void main(String[] args) {
Color obj = new Color() {
@Override
public void printColor() {
System.out.println("Blue");
}
};
obj.printColor();//Blue
}
この匿名クラスにラムダ式を適応すると
public static void main(String[] args) {
Color obj = () -> {System.out.println("Blue");};
obj.printColor();//Blue
}
と自分で書いていたら省略されて楽~と思うのですが、初見で来られたらまったく意味不明なものです。
これを踏まえてOptionalクラスを見ていきたいと思います。(最後のほうに出てきます)
1. Optionalクラス
Optionalクラス(java.utilパッケージ)は、nullチェックを簡単化し、NullPointerExceptionの発生を未然に防ぐためのクラスです。
まず、試しにnullが発生するソースを超簡単に作ってみました。
package optional;
import java.util.HashMap;
import java.util.Map;
public class demoOptional {
public static Map<String, String> colorMap = new HashMap<>();
public static void setData(){
//名前とカラーを格納したマップ
colorMap.put("blue","ogi");
colorMap.put("green","tomita");
colorMap.put("pink","suzuki");
}
public static String getName(String key) {
//引数で渡されたkeyをもとに名前を取得
return colorMap.get(key);
}
public static void main(String[] args) {
//Mapに挿入
setData();
//白が好きな人しりたい
String searchColor = "white";
String searchName = getName(searchColor);
System.out.println(searchColor+"は"+searchName+"さんの好きなカラーです");
}
}
出力結果は
whiteはnullさんの好きなカラーです
これでは白が好きな人がまるでnullさんと存在する人のような出力の仕方で困ります。
Mapに登録してある人のみを出力したいので、Optionalを知らない私は以下のように書きます。
public static void main(String[] args) {
//Mapに挿入
setData();
//白が好きな人しりたい
String searchColor = "white";
String searchName = getName(searchColor);
//if分岐を追加
if(searchName != null) {
System.out.println(searchColor+"は"+searchName+"さんの好きなカラーです");
}
}
}
searchNameがnullではないときに出力すればいいだけの話です。
しかし、可読性が低い!簡易化できる!と偉い人に怒られます。
ITの世界では最前線にいる方が全てです。どんどん更新されていきます。今の国のお偉いさんのように更新すると口だけ言って何もしない彼らはITの世界では門前払いというわけです。
そこで本題のOptionalを使えばわざわざif分岐をしなくともnull判定ができます。
package optional;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class demoOptional {
public static Map<String, String> colorMap = new HashMap<>();
public static void setData(){
//名前とカラーを格納したマップ
colorMap.put("blue","ogi");
colorMap.put("green","tomita");
colorMap.put("pink","suzuki");
}
public static Optional<String> getName(String key) {
//引数で渡されたkeyをもとに名前を取得
return Optional.ofNullable(colorMap.get(key));
}
public static void main(String[] args) {
//Mapに挿入
setData();
//白が好きな人しりたい
String searchColor = "blue";
Optional<String> searchName = getName(searchColor);
searchName.ifPresent(name -> System.out.println(searchColor+"は"+name+"さんの好きなカラーです"));
}
}
isPresentの説明はこちら
public void ifPresent(Consumer super T> consumer)
値が存在する場合は指定されたコンシューマをその値で呼び出し、それ以外の場合は何も行いません。
パラメータ:
consumer - 値が存在する場合に実行されるブロック
例外:
NullPointerException - 値が存在しconsumerがnullの場合
要するにsearchNameがnullでない場合は引数nameをsearchNameで呼び出すということです。
ほかにもOptionalは多くのメソッドがあり、よく使われるものをピックアップして紹介します。
- ・empty:null値であるOptionalインスタンスを返します。
example.java
Optional<String> empty = Optional.empty(); //emptyはnull
- ・of:非null値に対してOptionalインスタンスを返します。(感覚は型変換)
example2.javaString str = "ogi"; Optional<String> angel = Optional.of(str); //strは非null。strがnullだとNullPointerException
- ・ofNullable:値が非nullであればOptionalインスタンスを、nullであれば空のOptionalインスタンスを返します。(null判定の簡略化)
example3.javaString str = null; Optional<String> god = Optional.ofNullable(str); //日本人らしいコードですね
という感じでIT専門家には何を言っているんだといわれそうな内容ですが初心者の方が理解できればそれでいいです。
2. 引用
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Optional.html
https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/package-summary.html - ・of:非null値に対してOptionalインスタンスを返します。(感覚は型変換)