エンジニアの将来って?

現在7年目のCOBOL→Java→C#エンジニアが、将来への考えや勉強のアウトプット、たまに腎臓について書くブログです

【Java8】filterメソッドを解説【ラムダ式】

こんにちは。たいら(@tairaengineer2)です。
今回の記事はJava8で追加されたラムダ式の中の1つのfilterメソッドについてのアウトプットです。

filterメソッドとは

Stream<T> filter(Predicate<? super T> predicate)
このストリームの要素のうち、指定された述語に一致するものから構成されるストリームを返します。
これは中間操作です。

パラメータ:
predicate - 各要素を含めるべきか判定する目的で各要素に適用する、非干渉でステートレスな述語
戻り値:
新しいストリーム

Stream (Java Platform SE 8)から引用させて頂きました

一体どういうことでしょうか?
実際のプログラムをご覧ください。

filterメソッドの使い方その1

filterメソッドの使い方の例その1として、0から19までの数字のうち、偶数のみを表示するプログラムで解説します。

フォルダ構成

f:id:Tairax:20180319205628p:plain

1つのJavaプログラムだけでよいので、どこに置いても良いです。

Javaプログラム

package lambdaPractice;

import java.util.stream.IntStream;

/**
 * ラムダ式のfilterメソッドを練習するクラス
 *
 */
public class FilterPractice {
    public static void main(String[] args) {
        // 0から19までIntStreamを生成し、偶数のみ表示させる
        IntStream.range(0, 20).filter(num -> num % 2 == 0)
        .forEach(ans -> System.out.println(ans));
    }
}

実行結果

0
2
4
6
8
10
12
14
16
18

解説

IntStream.range(0, 20)の意味は0をスタートとして、そこから20を含まない範囲の数字のIntStreamを返します。
なので0から19までのIntStreamが返ってきます。

filter(num -> num % 2 == 0)の意味はIntStreamからとった各数字に対して、2で割って、余りが0だったものを返しています。
つまり、ここで奇数を振り落としています。

.forEach(ans -> System.out.println(ans));で残った偶数を表示しています。

filterメソッドの使い方その2

filterメソッドの使い方の例その2として、BookオブジェクトのListを作り、bookオブジェクトの値段が1000円より上のものを表示するプログラムで解説します。

フォルダ構成

f:id:Tairax:20180324161539p:plain

同じフォルダに格納します。

Javaプログラム

以下2つのプログラムを作りました。

  • Bookクラス
  • BookTernaryOperatorクラス

Bookクラス

package ternaryOperator;

/**
* 本クラス
*/
public class Book {
        /** 本の名前 */
        private String name;

        /** 本の価格 */
        private int price;

        /**
        * 本の名前を取得する
        * @return 本の名前
        */
        public String getName() {
                return name;
        }

        /**
        * 本の名前を設定する
        * @param name
        */
        public void setName(String name) {
                this.name = name;
        }

        /**
        * 本の価格を取得する
        * @return 本の価格
        */
        public int getPrice() {
                return price;
        }

        /**
        * 本の価格を設定する
        * @param price
        */
        public void setPrice(int price) {
                this.price = price;
        }
}

BookTernaryOperatorクラス

package ternaryOperator;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* 本の値段が1000円以上だった場合表示するクラス
*
*/
public class BookTernaryOperator {
        public static void main(String[] args) {
                // bookListを生成
                List bookList = new ArrayList();

                // comicオブジェクトを生成し、値を設定
                Book comic = new Book();
                comic.setName("OnePiece");
                comic.setPrice(500);

                // novelオブジェクトを生成し、値を設定
                Book novel = new Book();
                novel.setName("花火");
                novel.setPrice(1800);

                // bookListに生成したオブジェクトを追加
                bookList.add(comic);
                bookList.add(novel);

                // bookListから値段が1000円以上のbookオブジェクトのみ本の名前を表示する
                bookList.stream()
                .filter(book -> book.getPrice() > 1000)
                .collect(Collectors.toList())
                .forEach(res -> System.out.println(res.getName()));
        }
}

実行結果

花火

解説

Bookクラスはただのエンティティなので、解説はBookTernaryOperatorクラスのみします。
まずbookListに生成したbookオブジェクトを追加していきます。
そのbookListに対して.stream()をすることでBook型のStreamを生成します。

.filter(book -> book.getPrice() > 1000)の部分でbookListのそれぞれの要素、今回ではcomicオブジェクトとnovelオブジェクトに対して、1000円より値段が高いかどうか判定しています。
ここでcomicオブジェクトは値段が1000円未満なので、振り落とされます。

この時はBook型のStreamなので表示することができません。
.collect(Collectors.toList())の部分で、Streamから新しいListにしています。

.forEach(res -> System.out.println(res.getName()));で残っているnovelオブジェクトの名前を表示しています。

まとめ

いかがでしたか?
少しでもご参考になれば幸いです。
ではでは~(・ω・)ノシ

参考にさせて頂いたサイト様

IntStream (Java Platform SE 8)

Collectors(Java Platform SE 8)

Streamのcollectメソッドを学ぶ — 裏紙

 

ほかにも勉強記事を書いてます。
よければご参考ください。

【Java】標準入力から判定して、じゃんけんゲームをするプログラム

【Java】TreeSetの特徴を分かりやすく解説します。

今までブログで書いたJavaのアウトプット記事のまとめ