Java 8 Stream API'yi Android API <24'te kullanmak mümkün müdür?


89

Bu yazıyı burada okudum . Ancak yine de minSdkVersion <24 üzerinde Java 8 Stream API özelliklerini içeren kodu çalıştıramıyorum.

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

Hata mesajı nedeniyle bu çalışmıyor

Çağrı, API düzeyi 24 gerektirir (geçerli dakika 15): java.util.Collection # stream

Öyleyse birisi bir çözüm biliyor mu?


3
hayır, api 24'ün altındaki java akışını kullanamazsınız. Aynı şeyi uygulayan üçüncü taraf kitaplıkları var
tyczj

1
Daha düşük apiler
njzk2


3
Sen @PEMapModder olabilir kadar geriye Gingerbread kadar Android'i hedef alan yeni Jak derleyici kullanarak lambda ifadeleri ve yöntem başvuruları kullanın. Ne edemez Akış API gibi varsayılan / statik arayüz yöntemleri ve Java 8 özgü API'ler SDK 24 altında olması vardır.
Sartorius

StreamSupport sınıfını API 24
Özer Özcan

Yanıtlar:


71

[orijinal cevap]

Java8 akışlarını <24 API düzeyinde kullanamazsınız.

Bununla birlikte, akış işlevlerinin bir kısmını geri yükleyen bazı kitaplıklar vardır.

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

https://github.com/konmik/solid

https://sourceforge.net/projects/streamsupport/ (yorumda @ sartorius tarafından bahsedilmiştir)

[güncelleme k3b 2019-05-23]

https://github.com/retrostreams/android-retrostreams , Android Studio 3.x D8 / desugar araç zincirinin Jar dosyası sınırları boyunca arayüz varsayılanı ve statik yöntemlerini kullanma özelliğinden yararlanan akış desteğinin bir yan ürünüdür. CompletableFuture için diğer android-retroXXX'e bağlantılar da vardır.

[aeracode 2020-07-24'ü güncelle]

İyi haber , artık Java 8 Stream API ve daha fazlasını minimum API seviyesi gerektirmeden kullanabiliriz .


9
İken katı ve Hafif İçi-API kesinlikle Akış benzeri programlama, bunlardan IMHO hiçbiri uzaktan bile Java 8 Akış API "backport" olarak kabul edilebilir değerli seçeneklerdir. Keşke yakın sözdiziminde ve eşit işlevselliği Java 8 akışları olduğunu olmayı o kutunun iddianın biliyoruz proje streamsupport . Örneğin, paralel akışları da destekler. Yine de bu, Android geliştiricileri için çok önemli olmayabilir.
Sartorius

IMO, Lightweight-Stream-API, Gradle desteği nedeniyle Android'deki en iyisiydi ve "select", "groupBy" vb. Gibi ekstralar eklendi. Github.com/aNNiMON/Lightweight-Stream-API#additional-operators .
LordParsley

2
@LordParsley streamsupport ayrıca Gradle desteğine sahiptir. Ekstralara gelince, evet bu doğru. Anladığım kadarıyla, resmi Java 8 API'sinden genişletme / yönlendirme hiçbir zaman akış desteğinin tasarım hedefi olmamıştı.
Sartorius

3
@Sartorius haklı - Kullanım ayrıntıları için Github aynasına ve Gradle refs github.com/streamsupport/streamsupport
LordParsley

Genel olarak Java Akışlarının koleksiyonlardan daha yavaş olduğunu okudum. stackoverflow.com/questions/22658322/… Peki ya bu arka portlar?
Shikhar Shrivastav

12

Yayımlanmasından 8.2 yana DexGuard o olarak içerecek şekilde, tek ihtiyaçlarının yapabilmek için Android cihazlar <API düzeyinde 24. Ayrıca Java 8 akışları API kullanmak mümkündür streamsupport kütüphane ve DexGuard sağlanan tüm Java 8 akışı API çağrıları çevirir kütüphane. Ek işlem gerekmez ve geliştiriciler sağlanan Java 8 akışları API'sini kullanarak kodlayabilirler. Bağımlılıklar da otomatik olarak çevrilir, bu nedenle Java 8 özellikli kitaplıkları Android geliştirme için de kullanmak mümkündür.

Bu özellik yakın gelecekte ProGuard'a da dahil edilecek, bizi izlemeye devam edin.

Düzenleme: Bir beta sürümü zaten mevcut olan Proguard 6.1.0, Java 8 akışını ve zaman API'sini desteklemektedir.


bu resmi kütüphane değil
kullanıcı25

Kütüphanenin kendisi hakkında hiçbir fikrim yok, ancak ticari bir projede kullanmadan önce kütüphanenin lisansını kontrol etmenizi tavsiye ederim. Classpath İstisnası ile GNU Genel Kamu Lisansı sürüm 2 . Muhtemelen bir katmanın doğrulanması gerekir.
Michal Harakal

5
@MichalHarakal katmanın aslında avukat olduğunu anlamam birkaç saniyemi aldı :)
superjos

6

Partiye biraz geç kalmış olabilir, ancak az önce gördüm ki eğer kullanırsak java8.util.stream.StreamSupportaynı işlevsel programlama yaklaşımını çalıştırabilir ve Api 24'ten önce kullanabiliriz. Örneğin web3j'den alınmıştır -

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

3
@AjahnCharles İnsanlara soruları A dili ile ilgili olduğunda sadece B dilini kullanmalarını söylemek iyi bir cevap değil. Birçok proje hala Java ile yazılıyor.
mkuech

2
@AjahnCharles Okuyucuların dikkatini muhtemelen Android ekosistemindeki değişiklikleri düşünmeye çekme konusunda iyi bir noktaya değindiniz . Bununla birlikte, soru, Android geliştirme için hala resmi olarak desteklenen bir dil olan Java'nın belirli bir özelliğiyle ilgili. "Sadece" uygulamanızı hibritleşme bile, bir maliyet (öğrenme eğrisi, belki onların takım vb bunu desteklemez) getirilen ve içine dalış gerektirir Switching şekilde daha söz konusu soruluyor olandan. Daha da önemlisi, yorum Kotlin'in nasıl bir çözüm olduğuna değinmiyor, bu da onu daha bağlam dışı ve daha az yararlı hale getiriyor.
mkuech

3
@AjahnCharles açıkça bahsedildiğinde Java 8 Stream API, cevabın JAVA'da olması gerektiğini hissediyorum!
Abhriya Roy

2

Evet öyle ! AGP 4.0.0'dan başlayarak Stream API ve diğer bazı Java 8+ API'lerini kullanabiliriz (örneğin java.time)

Uygulamanızın build.gradle'ında gerekli minimum değişiklikler :

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

Kullanmaktan hoşlandığım bir başka çözüm de, eğer proje her ikisini de destekliyorsa , Kotlin'in uzantılarını Java kodundan Koleksiyonlar üzerinden statik olarak kullanmaktır :

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

Aynı için .map, .reduce, .first, ... vb


-5

Bir Arayüz oluşturun.

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

Bir Filtre Yöntemi Oluşturun.

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;
        }
    }

Kodu Kullanma

    public static class model {
            public String Name;
        }
List<model> models = new ArrayList<>();
            ...
            List<model> filtermodels = Filter(models,p-> p.Name.equals("filter"));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.