Sketchy

大雑把でいかがわしいブログ

ラムダ式よりメソッド参照 Javaのお話

はじめに

最近Javaの勉強し始めました
勉強をする前は、あまりJavaを好きではなかったのですが、勉強しているうちに愛着が沸いて結構お気に入りになってきています。笑
そこでふと疑問に思ったことを今回はだらだらと書いてみたいと思います。

f:id:tsudukihashi0817:20190420123338j:plain 出典: https://duke.kenai.com/SunRIP/.Midsize/SunRIP.png.png

疑問

Java8以降から存在しているラムダ式とメソッド参照どちらがよりスマートなのか?

準備

簡単なソートを行います。
まずID番号と名前を持ったメンバークラスを用意します。

public class Member {
    private  int id;
    private String name;

    public Member(int id, String name){
        this.id = id;
        this.name = name;
    }

    public Member(){
        this(0,"名無し");
    }

    public int getId(){
        return this.id;
    }

    public void setId(int id){
        this.id = id;
    }

    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }

    @Override
    public String toString(){
        return "ID: " + this.id + "\t名前: " + this.name;
    }
}

次にMainクラスを用意します。

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        Member member= new Member();

        List<Member> list = new ArrayList<>();
        list.add(new Member(3,"田中太郎"));
        list.add(new Member(19,"山田太郎"));
        list.add(new Member(1,"鈴木一郎"));

        for(Member m : list){
            System.out.println(m);
        }
    }
}

実行結果:

ID: 3   名前: 田中太郎
ID: 19  名前: 山田太郎
ID: 1   名前: 鈴木一郎

ソートしてみよう

これを昇順にソートする方法を調べてみると以下のようなものが出てきました。

list.sort((o1, o2) -> o1.getId() - o2.getId());

出力結果:

ID: 1   名前: 鈴木一郎
ID: 3   名前: 田中太郎
ID: 19  名前: 山田太郎

?!?!?!!?!?!!?!

って感じでした。

これは以下の処理をlistに対して行なっているそうです。

  • Comparatorインターフェースのcompare()が省略
  • o1.getId() - o2.getId() が正ならsort()によりo1が前に来る
  • 負ならsort()によりo1が前に来る
  • 0なら移動しない

すごくスマートな書き方ですが、分かり難かったです、、、
自分がスマートではないので、もっと優しい解決方法を探しました!

メソッド参照

list.sort(Comparator.comparing(Member::getId));

(※import java.util.Comparator;が必要)

さっきよりはわかりやすい!

逆順

逆順にするのも簡単!

list.sort(Comparator.comparing(Member::getId).reversed());

import static java.util.Comparator.*; をすることによってコードも短くできました。

list.sort(comparing(Member::getId).reversed());

Null処理

Null処理も簡単!
import static java.util.Comparator.*; を忘れずに行なってください。

Null処理を見せるためメンバー変数のint型を全てIntegerに変更
Autoboxing最高

public class Member {
    private  Integer id;
    private String name;

    public Member(Integer id, String name){
        this.id = id;
        this.name = name;
    }

    public Member(){
        this(0,"名無し");
    }

    public Integer getId(){
        return this.id;
    }

Mainクラス

import java.util.ArrayList;
import static java.util.Comparator.*;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        Member member= new Member();

        List<Member> list = new ArrayList<>();
        list.add(new Member(3,"田中太郎"));
        list.add(new Member(19,"山田太郎"));
        list.add(new Member(null,"摩利男"));
        list.add(new Member(1,"鈴木一郎"));

        list.sort(comparing(Member::getId,nullsLast(naturalOrder())));

        for(Member m : list){
            System.out.println(m);
        }
    }
}

出力結果:

ID: 1   名前: 鈴木一郎
ID: 3   名前: 田中太郎
ID: 19  名前: 山田太郎
ID: null    名前: 摩利男

まとめ

  • ラムダ式はカッコイイけど、個人的にはわかりづらい
  • メソッド参照は記述は増えるけど、わかりやすく使いやすい

多分、規約がなければ自分はメソッド参照を使用していくと思います。

以上駄文にお付き合いいただきありがとうございました。

参考文献

qiita.com

www.ne.jp

Swift入門学習メモ  #004_Swiftタプル

f:id:tsudukihashi0817:20190415225531p:plain:w200

タプル(tuple)

  • 複数の変数をまとめ上げる
  • 一つの変数に容易にわかりやすく意味を与える
var person = ("Ichiro", 30)
print(person.0)
print(person.1)

実行結果

Ichiro

30

それぞれの値にラベルをつけることも可能

var person = (name: "Ichiro", age:30)
print(person.name)
print(person.age)
  • タプルから値を代入する場合
var person = ("Ichiro", 30)
print(person.0)
print(person.1)

var (a, b) = person
print("a=\(a)")
print("b=\(b)")

実行結果

Ichiro
30
a=Ichiro
b=30
  • personにおけるageが不要な場合

    アンダースコアを利用する

var person = ("Ichiro", 30)
print(person.0)
pritn(person.1)

var(a, _) = person
print("a=\(a)")
  • タプルを用いて、配列やディクショナリからも値とインデックスを受け取ることができる

Swift入門学習メモ  #003_コレクション

f:id:tsudukihashi0817:20190415225531p:plain:w200

  • コレクションも基本的なデータ型として作成
  • 配列(array)
  • セット(set)
  • ディクショナリ(dictionary)

配列(array)

  • 同種のデータにインデックスアクセスするコレクション
var states = ["California", "Texas", "Hawaii"]

States[0] //California
  • 型を明示的に指定して作成することもできる
let a:[Int] = [1, 2, 3]
  • プラス( + ) 演算子で二つの配列の要素を付け加えることが可能

セット(set)

集合のこと、ある情報の存在確認などを行うには便利

var states:Set = ["California", "Texas", "Hawaii"]
  • Setを宣言するときはSetと記述する必要がある
    • ない場合は配列として作成される!
  • 型を指定する場合
var a:Set<Int> = [1, 2, 3]

ディクショナリ(dictionary)

  • キー・バリューペアと同等
var home:[String:String] = [
    "state":"California",
    "city": "Los Angeles"]

home["state"]
home["city"]

Ryo Tsuzukihashi