Java祝日計算の変更リリースについて

10年以上前に作った Java で作成した祝日計算を、昨日、皇室会議で皇太子即位日が決まったので、そろそろバージョンUPを考えなくてはならない。

 

その前に、このプログラムが抱えていた、java.util.Date の使用をいいかげんに辞めることにした。

まだ、2019年以降の天皇誕生日は、未対応だが、とにかく java.time.LocalDate 使用にする。

 

 

配列の比較が Java9 でメソッド追加

Java8 までは、単純に equal を調べるなら、java.util.Arrays の equals や、deepEquals(Object a1, Object a2) で
事足りた。
Java9 から、Arrays には以下の static メソッドが追加されている。
int Arrays.compare(T a, T b)
int Arrays.compare(int a, int b)
int Arrays.compare(byte a, byte b)

int Arrays.compareUnsigned(int a, int b)
int Arrays.compareUnsigned(byte a, byte b)

int Arrays.mismatch(Object a, Object b)
int Arrays.mismatch(int a, int b)
int Arrays.mismatch(byte a, byte b)

char, double, float, long, short も同様。
compare 辞書順比較、int なら、Integer.compare(int, int) で配列の要素を比較した結果を返してくれる。
詳細は、APIドキュメントを参照

int[] a = Arrays.asList(1, 2, 3, 4).stream().mapToInt(i->i).toArray();
int[] b = Arrays.asList(1, 2, 3, 4).stream().mapToInt(i->i).toArray();

System.out.println("Arrays.compare(a, b) = " + Arrays.compare(a, b));
System.out.println("Arrays.compareUnsigned(a, b) = " + Arrays.compareUnsigned(a, b));
System.out.println("Arrays.mismatch(a, b) = " + Arrays.mismatch(a, b));

の結果は、

Arrays.compare(a, b) = 0
Arrays.compareUnsigned(a, b) = 0
Arrays.mismatch(a, b) = -1

compare と compareUnsigned の差は注意が必要

int[] a = Arrays.asList(1, 2, 3, 4).stream().mapToInt(i->i).toArray();
int[] b = Arrays.asList(1, 2, -3, 4).stream().mapToInt(i->i).toArray();

System.out.println("Arrays.compare(a, b) = " + Arrays.compare(a, b));
System.out.println("Arrays.compareUnsigned(a, b) = " + Arrays.compareUnsigned(a, b));
System.out.println("Arrays.mismatch(a, b) = " + Arrays.mismatch(a, b));

の結果は、

Arrays.compare(a, b) = 1
Arrays.compareUnsigned(a, b) = -1
Arrays.mismatch(a, b) = 2

配列要素、インデックスを注意したロジック設計では活躍しそうと思います。

日付のStream生成 Java9 で追加がある。

Java8 までは、過去書いたように、、、
LocalDate の Stream 生成 - Oboe吹きプログラマの黙示録
Stream で LocalDateリストを生成 - Oboe吹きプログラマの黙示録
Java で横長カレンダーを書くための処理 - Oboe吹きプログラマの黙示録
のように、LocalDate の Stream の Iterator あるいは、IntStream で期間の範囲のSteam 生成をしていた。

LocalDate start = LocalDate.of(2017, 11, 28);
LocalDate end   = LocalDate.of(2017, 12, 5);

の時に、

Stream<LocalDate> stream
 = Stream.iterate(start, t->t.plusDays(1)).limit(Period.between(start, end).getDays() + 1);

あるいは、、

Stream<LocalDate> stream
= IntStream.rangeClosed(1, Period.between(start, end).getDays()).mapToObj(i->start.plusDays(i));

Java9 で、Jigsaw 以外の機能追加は、Stream の of の他に、limit が数値しか渡せず不便であったのをカバーするような
dropWhile(Predicate predicate)
takeWhile(Predicate predicate)

が追加されたことがよく、focus されている。
この ~まで、という考え方は、日付クラス LocalDate にも期間の Stream 生成でも
Java9 では以下のメソッドが追加された。
public Stream datesUntil(LocalDate endExclusive)
public Stream datesUntil(LocalDate endExclusive, Period step)

LocalDate start = LocalDate.of(2017, 11, 28);
LocalDate end   = LocalDate.of(2017, 12, 5);

Stream<LocalDate> stream = start.datesUntil(end.plusDays(1));

と簡潔に書けてしまうのである。

LocalDate start = LocalDate.of(2017, 11, 28);
LocalDate end   = LocalDate.of(2017, 12, 5);
start.datesUntil(end, Period.ofDays(2)).forEach(System.out::println);

と書けば、結果は、以下のよぅになる。

2017-11-28
2017-11-30
2017-12-02
2017-12-04

java9 で追加された Objects.requireNonNullElse / requireNonNullElseGet

NULL でない時の値の取得などは、Java8 で追加された Optional で充分事足りるのにと思うのだが、
Java9 で java.util.Objects には、requireNonNullElse / requireNonNullElseGet
が追加されてる。

public static <T> T requireNonNullElse<200b>(T obj, T defaultObj)
public static <T> T requireNonNullElseGet<200b>(T obj,  Supplier<? extends T> supplier)

3項演算子( ? : ) で NULL かどうかチェックする方法、Optional の方法、今回追加された方法、どれを使うかはセンスが問われる。

java.util.Objects に追加されたメソッドでいったいどこで使う?このメソッド?
public static int checkIndex​(int index, int length)
public static int checkIndex​(int index, int toIndex, int length)
public static int checkFromIndexSize​(int fromIndex, int size, int length)

使うことがありそうで、ないような?この単に範囲チェックなるメソッドで
範囲外で IndexOutOfBoundsException を発生させる。RuntimeException 系で実行時例外、

スライドしてループする jQuery で

メモ。

スライドしてループするデザインの作り方を紹介しているのを見つけたのでリンクのメモです。

jQueryで中央が拡大表示されたカルーセルパネルUIを実装する方法 | BlackFlag