0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

(StreamAPI)コンパイルエラー:「シンボルを見つけられません シンボル: メソッド stream() 場所: タイプ」「シンボルを見つけられません シンボル: メソッド isEmpty() 場所: タイプ」の原因がjavaのバージョンにありました

Posted at

はじめに

javaに触れ始め、複雑なPGをする中で処理速度改善のためにstreamAPIを知り、無邪気にfor文から置き換えて使っていた際に本記事の表題にあるエラーが表示されました。
コンパイルエラーとなり、buildができない動かない。。。
エラーメッセージで検索してもクリティカルな記事を見つけられず、StreamAPIのリファレンスを再度確認して、Javaのバージョンが原因であることが判明。
Javaのバージョンを無暗に変更することもできない状況で、なんとか動くように修正した内容を備忘(また類似の内容でつまずいた方へ)のために記事を作成いたします。

エラー内容

①「シンボルを見つけられません
シンボル: メソッド isEmpty()
場所: タイプjava.util.Optionalの変数 」

②「シンボルを見つけられません
シンボル: メソッド stream()
場所: タイプjava.util.Optional>の変数」

原因

javaのバージョン合わないことが原因

自分の環境:java11
デプロイ先の環境:java8

javaのドキュメントを確認すると、エラーで表示されたOptional.isEmpty()はjava11以降、Optional.stream()はjava9以降で動作することが記載されています。
https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Optional.html

開発も終盤に差し掛かり、java8で動いているものをjava11に修正するリスクよりは、PGを修正する選択を取らざるを得ない状況だったため、修正いたしました。

エラー内容①、②の修正前のソースコード

// エラー内容①の元の処理
// listAのnameがtaroのデータが複数件ある場合、ageが最大のものをリストに追加する
Optional<Object> test1 = testA.stream()
                 .filter(i -> i.get("name").equals("taro"))
                 .max((s1, s2) -> Integer.parseInt(s1.get("age")) - Integer.parseInt(s2.get("age")))
                 .map(x -> x.get("age"));

// testAが空の場合、ageは20として設定する
// ここがエラーの原因
if (testA.isEmpty()) {
     age = "20";
}


// エラー内容②の元の処理
// listBのname毎にデータをグルーピング、ageが最大のものをリストに追加
Map<String, Optional<Map<String, Object>>> test2 = testB.stream()
     .collect(Collectors.groupingBy(data -> data.get("userName")
     Collectors.maxBy(Comparator.comparing(data -> (long) data.get("age")))));

// flatMapでtest2を平坦にする
// ここがエラーの原因
List<Map<String, Object>> testC = test2.values().stream()
     .flatMap(opt -> opt.stream())
     .collect(Collectors.toList());

エラー内容①、②の修正後のソースコード

// エラー内容①の修正後の処理
Object test1 = testA.stream()
                 .filter(i -> i.get("name").equals("taro"))
                 .max((s1, s2) -> Integer.parseInt(s1.get("age")) - Integer.parseInt(s2.get("age")))
                 .map(x -> x.get("age"))
                 .orElse(null); 

if (testA == null) {
     age = "20";
}


// エラー内容②の修正後の処理
Map<String, Optional<Map<String, Object>>> test2 = testB.stream()
     .collect(Collectors.groupingBy(data -> data.get("userName")
     Collectors.maxBy(Comparator.comparing(data -> (long) data.get("age")))));

List<Map<String, Object>> testC = test2.values().stream()
     .flatMap(opt -> opt.isPresent() ? Stream.of(opt.get()) : Stream.empty())
     .collect(Collectors.toList());

解説

■エラー内容①について
終端処理にorElse(null)を付記することで、test1の定義をOptionalではなく、Objectにする。
filter条件に一致しない場合はnullが返却させることで、testA.isEmpty()ではなくtestA == nullとすることで対応。

■エラー内容②について
Optional>が存在することを確認して、いたらStream化して返す。
それをflatMapで配列に変換することで対応。

終わりに

javaを使った開発を行うにあたって、初歩的な「バージョンによって使えるライブラリが異なる」という原因のエラーでつまずきました。
javaのバージョンを変えずに、試行錯誤して叶えたい実装を行う必要がある際、本記事が一助となれば幸いです。

参考

・StreamAPI
https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Optional.html

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?