Android API <24でJava8 Stream APIを使用することは可能ですか?


89

私はここでこの投稿を読みました。しかし、それでもminSdkVersion <24で次のようなJava8 StreamAPI機能を含むコードを実行することはできません。

List<Car> newCars = cars.stream()
                        .filter(s -> s.getColor().equals("red"))
                        .collect(Collectors.toList());

エラーメッセージが原因で実行されません

呼び出しにはAPIレベル24が必要です(現在の最小値は15):java.util.Collection#stream

それで、誰かが解決策を知っていますか?


3
いいえ、API 24より下のJavaストリームを使用することはできません。同じことを実装するサードパーティのライブラリがありますが、それは機能します
tyczj 2016

1
下位API
njzk2

2
同様の質問(および回答)については、stackoverflow.com / questions / 39265004 / およびstackoverflow.com/questions/39039566/…を参照してください。
ザルトリウス2016

3
@PEMapModder GingerbreadまでさかのぼってAndroidをターゲットとする新しいJackコンパイラを使用して、ラムダ式とメソッド参照を使用できます。あなたがすることはできませんストリームAPIのようなデフォルト/静的インタフェース・メソッドおよびJava 8の特定のAPIはSDK 24の下に持っています。
ザルトリウス2016

あなたは、API 24の下StreamSupportクラスを使用することができます
OZER Ozcan氏

回答:


69

【元の回答】

APIレベル<24ではJava8ストリームを使用できません。

ただし、ストリーム機能の一部をバックポートするライブラリがいくつかあります

https://github.com/aNNiMON/Lightweight-Stream-API

https://github.com/konmik/solid

https://sourceforge.net/projects/streamsupport/(@sartoriusがコメントで言及)

[更新k3b2019-05-23]

https://github.com/retrostreams/android-retrostreamsは、streamsupportからのスピンオフであり、Android Studio 3.x D8 / desugarツールチェーンの機能を利用して、Jarファイルの境界を越えてインターフェイスのデフォルトメソッドと静的メソッドを使用します。他のandroid-retroXXX、つまりCompletableFutureへのリンクもあります。

[aeracode2020-07-24を更新]

朗報です最小のAPIレベルを必要せずに、Java 8 StreamAPIなどを使用できるようになりました


9
一方で固体軽量・ストリーム-APIは、ストリームのようなプログラミングのための確かに価値のある選択肢である、それらの私見なしでもリモートでのJava 8ストリームAPIの「バックポート」と考えることができません。私が知っている唯一のプロジェクトは、構文が近く、機能がJava 8ストリームと同等であると主張できるのは、streamsupportです。たとえば、並列ストリームもサポートします。それはAndroid開発者にとってそれほど重要ではないかもしれませんが。
ザルトリウス2016

IMO、Lightweight-Stream-APIは、Gradleがサポートされ、「select」、「groupBy」などの追加機能が追加されたため、Androidで最も優れていました。github.com/ aNNiMON / Lightweight-Stream-API #additional-operators
LordParsley 2017

2
@LordParsleystreamsupportにはGradleサポートもあります。エキストラに関しては、うん、それは本当です。私が理解しているように、公式のJava 8 APIからの拡張/迂回は、streamsupportの設計目標ではありませんでした。
ザルトリウス2017年

3
@Sartoriusは正しいです–使用法の詳細についてはGithubミラーをチェックすることをお勧めします。Gradleはgithub.com/streamsupport/streamsupportを参照します
LordParsley

一般に、Javaストリームはコレクションよりも遅いことを読みました。stackoverflow.com/questions/22658322/…これらのバックポートはどうですか?
Shikhar Shrivastav 2018

12

DexGuardのリリース8.2以降、Androidデバイス<APIレベル24でもJava 8ストリームAPIを使用できます。そのためには、streamsupportライブラリを含める必要があり、DexGuardはすべてのJava8ストリームAPI呼び出しを提供されたものに変換します。図書館。追加の処理は必要ありません。開発者は、提供されているJava8ストリームAPIを使用して簡単にコーディングできます。依存関係も自動的に変換されるため、Android開発でもJava8機能を備えたライブラリを使用できます。

この機能は、近い将来ProGuardにも含まれる予定ですので、ご期待ください。

編集:ベータ版がすでに存在するProguard 6.1.0は、Java8ストリームおよび時間APIのバックポートをサポートします。


公式ライブラリではありません
user25 2018

ライブラリ自体についてはよくわかりませんが、商用プロジェクトで使用する前に、ライブラリのライセンスを確認することをお勧めします。GNU General Public License、バージョン2、クラスパス例外あり。おそらく、レイヤーが確認する必要があります。
MichalHarakal19年

5
@MichalHarakalレイヤーが実際に弁護士であることに気付くのに数秒かかりました:)
superjos

6

パーティーに少し遅れるかもしれませんが、使用すればjava8.util.stream.StreamSupport、同じ関数型プログラミングアプローチを実行して、Api24より前に使用できることがわかりました。例:web3jから取得-

StreamSupport.stream(transactionReceipt.getLogs())
            .map(log -> extractEventParameters(event, log))
            .filter(Objects::nonNull)
            .collect(Collectors.toList());

3
@AjahnCharles質問が言語Aに関するものである場合に、言語Bを使用するように人々に指示することは良い答えではありません。多くのプロジェクトはまだJavaで書かれています。
mkuech

2
@AjahnCharles Androidエコシステムの変更を検討する可能性について、読者の注意を引くことについて良い点を述べています。とは言うものの、問題は、Android開発でまだ公式にサポートされている言語であるJavaの特定の機能に関するものです。アプリを「のみ」ハイブリッド化する場合でも、切り替えにはコストがかかり(学習曲線、チームがそれをサポートしていないなど)、質問で求められている以上の方法で飛び込む必要があります。さらに重要なことに、コメントはKotlinがどのようにソリューションであるかを扱っていないため、コンテキストから外れ、役に立たなくなります。
mkuech

3
@AjahnCharlesが明確に言及されJava 8 Stream APIている場合、答えはJAVAにもあるはずです!
Abhriya Roy

1

はい、そうです!AGP 4.0.0以降、StreamAPIおよびその他のJava8 + APIを使用できます(例java.time

アプリのbuild.gradleに必要な最小限の変更:

android {
  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
  }
}

dependencies {
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
}

-1

私が使用したい別の解決策は、プロジェクトがもちろん両方をサポートしている場合、 Javaコードからのコレクションに対してKotlinの拡張機能を静的に使用することです。

List<Car> newCars = CollectionsKt.filter(cars, s -> s.getColor().equals("red"));

同じのため.map.reduce.first、...など


-6

インターフェースを作成します。

public interface Pre<T,R> {
            R get(T item);
        }

フィルタメソッドを作成します。

public static  <T> List<T> Filter(List<T> list, Pre<T,Boolean> pre) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
        {
            return list.stream().filter(p -> pre.get(p)).collect(Collectors.toList());
        }
        else
        {
            List<T> col = new ArrayList<T>();
            for (int i = 0 ; i < list.size() ; i++)
                if (pre.get(list.get(i)))
                    col.add(list.get(i));
            return col;
        }
    }

コードの使用

    public static class model {
            public String Name;
        }
List<model> models = new ArrayList<>();
            ...
            List<model> filtermodels = Filter(models,p-> p.Name.equals("filter"));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.