[java] Android API <24에서 Java 8 Stream API를 사용할 수 있습니까?

여기 에서이 게시물을 읽었 습니다 . 그러나 여전히 minSdkVersion <24에서 다음과 같은 Java 8 Stream API 기능이 포함 된 코드를 실행할 수 없습니다.

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

오류 메시지로 인해 실행되지 않습니다.

호출에는 API 레벨 24가 필요합니다 (현재 최소값은 15) : java.util.Collection # stream

그래서 누군가가 해결책을 알고 있습니까?



답변

[원래 답변]

API 레벨 <24에서는 Java8 스트림을 사용할 수 없습니다.

그러나 일부 스트림 기능을 백 포트하는 일부 라이브러리가 있습니다.

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

https://github.com/konmik/solid

https://sourceforge.net/projects/streamsupport/ (@sartorius가 주석에 언급)

[k3b 2019-05-23 업데이트]

https://github.com/retrostreams/android-retrostreams 는 Jar 파일 경계에서 인터페이스 기본 및 정적 메서드를 사용하는 Android Studio 3.x D8 / desugar 도구 모음의 기능을 활용하는 streamsupport의 스핀 오프입니다. CompletableFuture에 대한 다른 android-retroXXX에 대한 링크도 있습니다.

[Aeracode 2020-07-24 업데이트]

좋은 소식입니다 . 이제 최소 API 레벨 없이도 Java 8 Stream API 등을 사용할 수 있습니다 .


답변

DexGuard 8.2 릴리스부터는 API 레벨 24 미만의 Android 장치에서도 Java 8 스트림 API를 사용할 수 있습니다.이를 위해서는 streamsupport 라이브러리 를 포함해야 하며 DexGuard는 모든 Java 8 스트림 API 호출을 제공된 도서관. 추가 처리가 필요하지 않으며 개발자는 제공된 Java 8 스트림 API를 사용하여 간단히 코딩 할 수 있습니다. 종속성도 자동으로 번역되므로 Android 개발에도 Java 8 기능이있는 라이브러리를 사용할 수 있습니다.

이 기능은 가까운 시일 내에 ProGuard에도 포함될 예정입니다. 계속 지켜봐 주시기 바랍니다.

편집 : 이미 베타 버전이있는 Proguard 6.1.0은 Java 8 스트림 및 시간 API 백 포팅을 지원합니다.


답변

파티에 조금 늦을 수도 있지만, 사용 java8.util.stream.StreamSupport하면 동일한 기능적 프로그래밍 접근 방식을 실행하고 Api 24 이전에 사용할 수 있음을 방금 보았습니다 . 예 : web3j에서 가져옴-

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


답변

네, 그렇습니다 ! (예를 들어, AGP 우리는 스트림 API를 사용하여 4.0.0과 다른 자바 8 + 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'
}


답변

내가 사용하고 싶은 또 다른 솔루션 은 프로젝트가 물론 두 가지 모두를 지원하는 경우 Java 코드의 컬렉션에 대해 Kotlin의 확장을 정적으로 사용 하는 것입니다 .

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

동일에 .map, .reduce, .first, … 등


답변

인터페이스를 만듭니다.

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"));


답변