質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

1647閲覧

java8のOptionalの複数オブジェクトの判定方法

keinon

総合スコア11

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/03/24 12:19

編集2018/03/24 14:02

実現したいこと

画面から入力された2つの日付でDB検索を行うのですが、
開始日だけ入力される場合と、終了日だけ入力される場合と、両方入力される場合があり、
それぞれのwhere句文作成したい。

以下の記述で両方ある場合は実現できたのですが、片方だけある場合の記述の仕方がわかりません・・・。

試したソース

java

1 public static void main(String[] args) { 2 Optional<Date> day1 = Optional.ofNullable(new Date()); 3 Optional<Date> day2 = Optional.ofNullable(new Date()); 4 5 Optional<String> ret = day1.flatMap(str1 -> 6 day2.flatMap(str2 -> { 7 return Optional.ofNullable("両方ある場合"); 8 }) 9 ); 10 } 11

環境

Java 8
Spring 4.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

StringJoiner使っちゃダメ?

java

1StringJoiner sj = new StringJoiner(" AND "); 2Optional<Date> day1 = Optional.ofNullable(new Date()); 3Optional<Date> day2 = Optional.ofNullable(new Date()); 4 5day1.ifPresent(d -> sj.add("DATE >= " + d)); 6day2.ifPresent(d -> sj.add("DATE <= " + d)); 7System.out.println(sj);

投稿2018/03/24 15:36

swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2018/03/24 15:41

あっけないぐらい分かり易いですね!
keinon

2018/03/25 01:54

StringJoinerなんてできたんですね! 知らかなったです。 こちらも検討してみます。
guest

0

ベストアンサー

最初に直接関係ない話ですが、値がnullの可能性があるかないかでOptional.ofとOptional.ofNullableは使い分けた方がよいと思います。

それはそれとして、以下のような感じではいかがでしょう

java

1import java.sql.Date; 2import java.text.ParseException; 3import java.text.SimpleDateFormat; 4import java.util.Optional; 5import java.util.stream.Collectors; 6import java.util.stream.Stream; 7 8public class Boo { 9 public static void main(String[] args) { 10 Optional<Date> d1 = Optional.of(new Date(sdf.parse("2018-01-01").getTime())); 11 Optional<Date> d2 = Optional.of(new Date(sdf.parse("2018-02-02").getTime())); 12 Optional<Date> dn = Optional.empty(); 13 14 System.out.println(buildCondition(d1, d2)); 15 System.out.println(buildCondition(d1, dn)); 16 System.out.println(buildCondition(dn, d2)); 17 } 18 19 static String buildCondition(Optional<Date> from, Optional<Date> to) { 20 return Stream.of( 21 from.map(d -> "DATE >= " + fmt(d)), 22 to.map(d -> "DATE <= " + fmt(d)) 23 ).flatMap(Optional::stream).collect(Collectors.joining(" AND ")); 24 } 25 26 static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 27 28 static String fmt(Date date) { 29 return sdf.format(date); 30 } 31}

==>
DATE >= 2018-01-01 AND DATE <= 2018-02-02
DATE >= 2018-01-01
DATE <= 2018-02-02


ご質問にあるコードからPreparedStatementのsetDateは使わない想定のようでしたので、日付はリテラルとしてフォーマットするようなコードにしています。フォーマットの仕方そのものはいいかげんです。


追記:Java9前提です。Java8にはOptional#stream()がありませんので。


追記2:Java8で上記の方針とするならちょっと長めのコードになりますね。
.flatMap(Optional::stream).~
=>
.flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty)).~

投稿2018/03/24 13:01

編集2018/03/24 13:56
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keinon

2018/03/24 13:40

回答ありがとうございます。 こちらの環境がjava8のため、そのままは使えませんが、文字列の組み立て方が良いヒントになりそうです。 自分の頭ではif-elseの中身をそれぞれの分岐ですべて記述しないと無理そうだったのですが、こんな組み立て方もできるのですね・・・。 勉強になります。
KSwordOfHaste

2018/03/24 14:00

Optionalを要素が0個か1個のストリーム的なものとみなすことができ、実際他の言語ではそのままストリーム的なものと互換性があるものとして設計されてたりするようです。そうなってるとflatMapと組み合わせて便利なことが多いと思います。残念ながらJavaはそうではないので、Java9でOptional#streamがサポートされたのだと思います。Java8のコードも追記してみました。 ついでに元のコードで「flatMap(o -> o.stream())」とちょっと迂遠なことをしていたので、 「flatMap(Optional::Stream)」に直しました ;;;
keinon

2018/03/24 14:08

ご親切にありがとうございます。 ご提示くださった仕組みでメンバーと相談してみます。
guest

0

java

1Optional<String> ret = day1 2 .map(Optional::of) 3 .orElse(day2) 4 .map(day -> "どちらかがnullでない場合");

シンプルに書くなら、こちらでいかがでしょうか。

投稿2018/03/24 13:36

kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keinon

2018/03/24 14:10

ご回答ありがとうございます。 どちらかnullではなく、day1がnullの場合とday2がnullの場合で挙動が変わってくる為、この案を元にもう少し考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問