はじめに
業務でJavaのStream APIを書いたときにエラーが出たので調べたことをメモします。
問題
日付と値を持つオブジェクトのリストと、対象期間が与えられ対象期間内でリストにない日付のデータを補完する処理を書きました。
List<Object> dateAndValList = List.of(); // 実際には検証したいオブジェクトのリスト
LocalDate startDate = LocalDate.parse("2024-01-01");
LocalDate endDate = LocalDate.parse("2024-02-01");
while(!startDate.isAfter(endDate)) {
if (dateList.stream().filter(date -> date.isEqual(startDate)).count() < 1) {
// 補完する処理
}
startDate.plusDays(1);
}
StreamAPIを利用している行で以下のエラーが発生してしまいます。
Local variable defined in an enclosing scope must be final or effectively final
どうやら、ラムダ式の中で使う変数は「実質的にfinalな変数」である必要があるらしい。
実質的にというのはfinalで修飾されていなくても変更されない変数ならOK、ということのようです。
解決方法
以下のように修正しました。
List<Object> dateAndValList = List.of(); // 実際には検証したいオブジェクトのリスト
LocalDate startDate = LocalDate.parse("2024-01-01");
LocalDate endDate = LocalDate.parse("2024-02-01");
while(!startDate.isAfter(endDate)) {
LocalDate checkDate = startDate;
if (dateList.stream().filter(date -> date.isEqual(checkDate)).count() < 1) {
// 補完する処理
}
startDate.plusDays(1);
}
おわりに
だいぶ苦肉の策でした。
もっと良い方法があればぜひ教えてください。