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


89

여기 에서이 게시물을 읽었 습니다 . 그러나 여전히 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

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


3
아니 당신은 api 24 아래의 자바 스트림을 사용할 수 없습니다. 작동하지만 동일한 것을 구현하는 타사 라이브러리가 있습니다
tyczj

1
하위 API에 대해 유사한 작업을 수행하는 작은 라이브러리가 있습니다. github.com/smaspe/FunctionalIterables
njzk2

2
유사한 질문 (및 답변) 은 stackoverflow.com/questions/39265004/…stackoverflow.com/questions/39039566/… 을 참조하십시오 .
Sartorius

3
@PEMapModder Gingerbread까지 Android를 대상으로하는 새로운 Jack 컴파일러를 사용하여 람다 식과 메서드 참조를 사용할 수 있습니다 . 당신이 할 수없는 스트림 API 등의 기본 / 정적 인터페이스 방법 및 Java 8 특정 API는 SDK 24 이하가 있습니다.
Sartorius

API 24
Özer Özcan

답변:


69

[원래 답변]

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 등을 사용할 수 있습니다 .


9
반면 고체경량 - 스트림-API는 확실히 스트림과 같은 프로그래밍, 그들의 이럴 없음에도 원격으로 자바 8 스트림 API의 "백 포트"로 간주 할 수없는 가치있는 옵션입니다. 내가 아는 유일한 프로젝트는 구문이 비슷하고 Java 8 스트림과 동등한 기능을 가지고 있다고 주장 할 수있는 유일한 프로젝트는 streamsupport 입니다. 예를 들어 병렬 스트림도 지원합니다. Android 개발자에게는 그다지 중요하지 않을 수도 있습니다.
Sartorius

IMO, Lightweight-Stream-API는 Gradle 지원과 "select", "groupBy"등과 같은 추가 기능으로 인해 Android에서 가장 좋았습니다 . github.com/aNNiMON/Lightweight-Stream-API#additional-operators .
LordParsley

2
@LordParsley streamsupport는 Gradle도 지원합니다. 엑스트라는 사실입니다. 내가 이해하는 바와 같이 공식 Java 8 API에서 확장 / 전환은 스트림 지원의 설계 목표가 아닙니다.
Sartorius

3
@Sartorius은 맞다 - 나는 Github에서 사용 자세한 내용은 거울과 Gradle을 심판 체크 아웃하는 것이 좋습니다 github.com/streamsupport/streamsupport
LordParsley

일반적으로 Java Streams가 컬렉션보다 느리다는 것을 읽었습니다. stackoverflow.com/questions/22658322/… 이 백 포트는 어떻습니까?
Shikhar Shrivastav

12

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 백 포팅을 지원합니다.


공식 도서관이 아닙니다
user25 dec.

도서관 자체에 대해서는 잘 모르겠지만 상업 프로젝트에 사용하기 전에 도서관 라이센스를 확인하는 것이 좋습니다. GNU General Public License, 버전 2, 클래스 경로 예외 . 아마도 레이어는 확인해야합니다.
Michal Harakal

5
그것은 그 실현하기 위해 나에게 몇 초를했다 @MichalHarakal 실제로이었다 변호사 :
superjos

6

파티에 조금 늦을 수도 있지만, 사용 java8.util.stream.StreamSupport하면 동일한 기능적 프로그래밍 접근 방식을 실행하고 Api 24 이전에 사용할 수 있음을 방금 보았습니다 . 예 : 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 개발을 위해 공식적으로 지원되는 언어 인 Java의 특정 기능에 대한 질문입니다. "전용"당신의 응용 프로그램을 교배 경우에도 비용 (학습 곡선, 어쩌면 자신의 팀이 등을 지원하지 않습니다)를 제공하고 그 다이빙을 필요로 전환 방법을 더 이상 질문 요청을 받고 것보다. 더 중요한 것은 주석이 Kotlin이 솔루션 인 방식을 다루지 않아 컨텍스트에서 벗어나 유용 하지 않게 만든다는 것입니다.
mkuech

3
@AjahnCharles가 명확하게 언급 Java 8 Stream API되면 대답도 JAVA에 있어야한다고 생각합니다!
Abhriya Roy

1

네, 그렇습니다 ! (예를 들어, 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'
}

-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.