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

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

ただいまの
回答率

92.00%

  • Java

    8012questions

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

  • Android

    3944questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

AndroidでJava8の機能が利用できない

解決済

回答 3

投稿 2017/03/14 10:39 ・編集 2017/03/14 11:52

  • 評価
  • クリップ 1
  • VIEW 220

aglkjggg

score 368

前提・実現したいこと

Personクラスを名前、年齢の2つのキーでソートをしたいです。
しかし、様々な方法を試しましたがすべてエラーになります。
どうにかしてソートする方法はありませんでしょうか。

また、Javaでも.NETのLINQのように書ければなぁ。。。と思っています。
いいライブラリ等ご存知でしたら教えてください><

該当のソースコード

  • MainActivity.java
// Person クラス
class Person {
  public Person(String name, Integer age){
    this.name = name;
    this.age = age;
  }

  private String name;
  public String getName() {
    return name;
  }

  private Integer age;
  public Integer getAge() {
    return age;
  }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  // persons にダミーデータを入れる
  List<Person> persons = new ArrayList<>();
  persons.add(new Person("a", 3));
  persons.add(new Person("b", 2));
  persons.add(new Person("b", 4));
  persons.add(new Person("c", 1));

  // persons をソートする
  persons.sort(comparing(Person::getName, reverseOrder()).thenComparing(Person::getAge));

  // 結果を出力する
  for(Person p : persons) {
    System.out.println(p.name + p.age);
  }
}

発生している問題・エラーメッセージ

03-14 10:16:07.788 13100-13100/com.example.user01.myproject W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41c33638)
03-14 10:16:07.798 13100-13100/com.example.user01.myproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user01.myproject, PID: 13100
  java.lang.NoClassDefFoundError: com/example/user01/myproject/-$Lambda$0
     com.example.user01.myproject.MainActivity.onCreate(MainActivity.java:42)
     android.app.Activity.performCreate(Activity.java:5246)
     android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
     android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2169)
     android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2271)
     android.app.ActivityThread.access$800(ActivityThread.java:144)
     android.app.ActivityThread$H.handleMessage(ActivityThread.java:1205)
     android.os.Handler.dispatchMessage(Handler.java:102)
     android.os.Looper.loop(Looper.java:136)
     android.app.ActivityThread.main(ActivityThread.java:5179)
     java.lang.reflect.Method.invokeNative(Native Method)
     java.lang.reflect.Method.invoke(Method.java:515)
     com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798)
     com.android.internal.os.ZygoteInit.main(ZygoteInit.java:614)
     de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
     dalvik.system.NativeStart.main(Native Method)
  Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.user01.myproject.-$Lambda$0" on path: DexPathList[[zip file "/data/app/com.example.user01.myproject-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.user01.myproject-2, /vendor/lib, /system/lib]]
     dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
     java.lang.ClassLoader.loadClass(ClassLoader.java:497)
     java.lang.ClassLoader.loadClass(ClassLoader.java:457)
     com.example.user01.myproject.MainActivity.onCreate(MainActivity.java:42) 
     android.app.Activity.performCreate(Activity.java:5246) 
     android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
     android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2169) 
     android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2271) 
     android.app.ActivityThread.access$800(ActivityThread.java:144) 
     android.app.ActivityThread$H.handleMessage(ActivityThread.java:1205) 
     android.os.Handler.dispatchMessage(Handler.java:102) 
     android.os.Looper.loop(Looper.java:136) 
     android.app.ActivityThread.main(ActivityThread.java:5179) 
     java.lang.reflect.Method.invokeNative(Native Method) 
     java.lang.reflect.Method.invoke(Method.java:515) 
     com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798) 
     com.android.internal.os.ZygoteInit.main(ZygoteInit.java:614) 
     de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) 
     dalvik.system.NativeStart.main(Native Method) 

試したこと

  • Lightweight-Stream-APIの利用
    Android 7.0が最低条件となるので使えなかった。
    Android 4.4以上の端末で動くアプリを作りたい。

  • IxJavaの利用
    問題なく動作した。
    しかし、orderByは存在するが、thenByが存在しない為
    複数キーでのソートができなかった。

  • jLinqerの利用
    以下のエラーが出てコンパイルができなかった。

Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.util.function.Predicate
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.util.function.Predicate
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.util.function.Function
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.util.Comparator
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.util.Comparator
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.util.Comparator
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.util.Comparator
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.util.function.Predicate
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable
Error:Lambda coming from jar file need their interfaces on the classpath to be compiled, unknown interfaces are java.lang.Iterable

補足情報(言語/FW/ツール等のバージョンなど)

2017/03/14 AM 11:52追記

情報追加
コードを一切変更せずに 以下の端末でテストしましたので結果を追加します。

 Android API Level   Android Version   結果 
 23                  6.0               NG   
 24                  7.0               OK   
 25                  7.1               OK   
  • 気になる質問をクリップする

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

    クリップした質問はマイページの「クリップ」タブからいつでも見ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

Lightweight-Stream-API + RetroLambdaの環境なら、低いAPIでも動きそう?
RetroLambdaを使う場合は、Jackが使えないのでそこらへんはいじる必要ありそう。

投稿 2017/03/14 12:00

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/03/14 15:59 編集

    ■Google等から検索してきた人用まとめ
    結論からすると Android 4.x.x でも Lightweight-Stream-API だけで動作確認ができました。
    import static com.annimon.stream.ComparatorCompat.*;
    する必要がありました。

    Gradleは以下の設定をしました。
    compile 'com.annimon:stream:1.1.6'

    詳しくは この下でabs123様とのやりとりを参照してください。


    ご回答ありがとうございます。
    以下の記事を参考にLSA + RetroLambdaを導入した所動作しました。
    (作者もLSAと略しているようですので、LSAと略させていただきました。)

    http://qiita.com/kojionilk/items/2795dcc2307a13abe1c1

    しかし、ThenBy に相当するものが無い為複数キーでのソートが出来ませんでした。

    persons = Stream.of(persons)
    .sortBy(Person::getName)
    .sortBy(Person::getAge)
    .toList();
    この結果が
    c1
    b2
    b3
    b4
    となってしまいます。

    キャンセル

  • 2017/03/14 14:02

    スタティックメソッドとして用意されているみたいですね
    書くとしたらこんな感じでしょうか。
    .sorted(thenComparing(comparing(Person::getName, reverseOrder()), comparing(Person::getAge)))

    キャンセル

  • 2017/03/14 14:26 編集

    Stream.of(persons)
    .sorted(comparing(Person::getName));

    試しにこちらの短めのコードを動かしてみると再びLambdaエラーが出てきました。
    sortBy は動くのですがsortedが何故か動きませんでした。。。><

    キャンセル

  • 2017/03/14 14:41

    何がスタティックインポートされているか、確認してください。
    java.util.Collections.reverseOrder;
    java.util.Comparator.comparing;
    こいつらがいるとエラーが出ると思います。

    代わりとなるのは、下記のものです。
    com.annimon.stream.ComparatorCompat.comparing;
    com.annimon.stream.ComparatorCompat.reverseOrder;

    キャンセル

  • 2017/03/14 15:51 編集

    ありがとうございます><
    Javaについての理解が足りてませんでした。。
    import static com.annimon.stream.ComparatorCompat.*;
    に修正した所、目的のソートが実現できました><

    ※追記
    RetroLambdaは不要で、LSAだけで動作しました。
    LSAが動作しないと勘違いしていたのは先程も指摘していただいた import するものが間違っていたからでした。

    キャンセル

+1

ラムダ式が正しく処理されてない感じですね。
でも JDK 1.8 でコンパイルしている(でなければそもそもラムダ式のコンパイルができない)のですから、実行ランタイム側がラムダ式対応になってない、のかな。

参考にされた Web ページにあるように、Jack がきちんと設定されてコンパイルに使用されているのか、くらいですかね。

投稿 2017/03/14 11:28

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/03/14 12:03 編集

    ご回答ありがとうございます。
    読み直したところ、気になる文章があったので検証して追記します。

    以下、引用します。
    ------------------------------
    Android では Java 8 の全言語機能はサポートしていません。
    ただし、Android 7.0(API レベル 24)向けにアプリを開発している場合は、次の機能を使用できます。
    (中略)
    以前のバージョンの Android でラムダ式、メソッド参照、タイプ アノテーションをテストするには、
    build.gradle ファイルで compileSdkVersion と targetSdkVersion を 23 以下に指定します。
    ------------------------------
    https://developer.android.com/guide/platform/j8-jack.html?hl=ja

    キャンセル

  • 2017/03/14 12:38 編集

    結論からするとダメでした。

    以下が試した手順です。

    ■1. Android 6.0 (Marshmallow)(Android API Level 23)用SDK をインストール
    ■2. compileSdkVersion と targetSdkVersionを 23に変更
    ■3. compile 'com.android.support:appcompat-v7:25.x.x'

    compile 'com.android.support:appcompat-v7:23+'
    に修正
    ■4. jackOptions{ enabled true } を追加

    Java8の機能が使えなくなり、コンパイルが成功しなくなった。
    http://i.imgur.com/iW0H0Xj.png

    ※エラー対処
    Error:No resource identifier found for attribute 'roundIcon' in package 'android'
    というエラーが出たので、

    AndroidManifest.xmlの
    android:roundIcon="@mipmap/ic_launcher_round"
    の1行を削除した。

    キャンセル

  • 2017/03/14 13:00 編集

    Jack ツールチェーンの設定をしてないのでは? …と思ったけど、jack ツールチェーンは Android 6.0 から標準扱いだったっけか……
    あとは build.gradle で
    compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
    }
    を指定していないとか?

    キャンセル

  • 2017/03/14 13:23

    再度確認しましたが指定しておりました。
    念のためプログラムとbuild.gradleをすべて貼り付けます。

    また、今までWindows で試していたのですが、
    macOSに1からAndroidStudio をインストールして同様のことを試しましたが、
    全く同じエラー(lambdaのエラーが出る)が再現されてうまく動きませんでした。

    ・build.gradle
    https://gist.github.com/anonymous/c806436be2c565ddf04d1d8f7c32ce59

    ・MainActivity.java
    https://gist.github.com/anonymous/099320997c8b4d62dcdafc2663f87175

    キャンセル

0

persons.sort(comparing(Person::getName, reverseOrder()).thenComparing(Person::getAge));

このままで動いたけど。

投稿 2017/03/14 11:19

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/03/14 11:21

    あー、ごめん。Androidでの話か。

    キャンセル

  • 2017/03/14 11:42 編集

    Android StudioでもGradleの設定をすればそのままのコードで動きました。

    キャンセル

  • 2017/03/14 11:54 編集

    ご回答ありがとうございます。
    お手数をおかけします…><
    ご利用されているのはAndroid 7.0以上でしょうか?

    私の環境でエミュレータを作成して試したところ、
    Android 7.0未満はエラーが出てしまうということがわかりまして…

    キャンセル

  • 2017/03/14 13:07

    全部エミュレータですが 7o 6x 5x 4x でした。失礼しました。

    キャンセル

  • 2017/03/14 13:27

    ありがとうございます。
    やはりAndroid 7.xは動作可で、それ以下となると動作不可になるのですね。。。

    キャンセル

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

ただいまの回答率

92.00%

関連した質問

同じタグがついた質問を見る

  • Java

    8012questions

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

  • Android

    3944questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

閲覧数の多いJavaの質問