【问题标题】:Filter a list of objects in Android using gradle-retrolambda and Lightweight-Stream-API使用 gradle-retrolambda 和 Lightweight-Stream-API 过滤 Android 中的对象列表
【发布时间】:2023-03-19 16:15:01
【问题描述】:

我正在尝试在我的 Android 应用程序中过滤 Java 中的对象列表,为此我遵循 this answer(Java 8 建议),但由于 Android SDK 不支持 Lambda,我使用了 gradle-retrolambda 但我得到这个运行时错误
java.lang.NoSuchMethodError: No interface method stream()Ljava/util/stream/Stream; in class Ljava/util/List; or its super classes (declaration of 'java.util.List' appears in /system/framework/core-libart.jar)

这是我正在使用的代码行:

List<CaseDetails> closedCaseDetailsList = caseDetailsList.stream().filter(item -> item.caseClosed.equals(true)).collect(Collectors.toList());

我相信它应该可以工作,因为 gradle-retrolambda 应该负责 Java7 上的 Lambda。

接下来,我尝试了 Lightweight-Stream-APIgradle-retrolambda 并根据 Lightweight-Stream-API 的用法稍微更改了我的代码

List<CaseDetails> closedCaseDetailsList = Stream.of(caseDetailsList).filter(item -> item.caseClosed.equals(true)).collect(Collectors.toList());  

但它给了我一个错误,而不是Collectors.toList()

collect
(com.annimon.stream.Collector<? super com.example.yankee.cw.CaseDetails,java.lang.Object,java.lang.Object>)
in Stream cannot be applied
to
 (java.util.stream.Collector<T,capture<?>,java.util.List<T>>) 

我还尝试将Stream 显式类型转换为List&lt;CaseDetails&gt;,但这没有用(当然)。

我尝试了 Slack 社区、SO 聊天室,但找不到解决方案。我发现最接近我的问题的是question,但这是一个不同的错误。
谢谢

【问题讨论】:

    标签: java android lambda java-8


    【解决方案1】:

    我只能给你举个例子streamsupport

    import java.util.Arrays;
    import java.util.List;
    
    import java8.util.stream.Collectors;
    import java8.util.stream.StreamSupport;
    import static java.lang.Boolean.TRUE;
    import static java.lang.Boolean.FALSE;
    
    public class CaseDetails {
    
        Boolean caseClosed = FALSE;
    
        public CaseDetails(Boolean caseClosed) {
            this.caseClosed = caseClosed;
        }
    
        public String toString() {
            return "caseClosed: " + caseClosed;
        }
    
        public static void main(String[] args) {
            List<CaseDetails> caseDetailsList = Arrays.asList(
                    new CaseDetails(TRUE), new CaseDetails(FALSE), new CaseDetails(
                            TRUE));
            List<CaseDetails> closedCaseDetailsList = StreamSupport
                    .stream(caseDetailsList)
                    .filter(item -> item.caseClosed.equals(TRUE))
                    .collect(Collectors.toList());
    
            System.out.println(closedCaseDetailsList);
        }
    }
    

    希望这会有所帮助。

    【讨论】:

    • 知道了。我的Collectors 是一个较早导入的Java7 类,并且它继续使用相同的类。非常感谢你和@Jahnold
    【解决方案2】:

    不幸的是,Retrolambda 不会向后移植流。来自文档:

    Retrolambda 让您可以在 Java 7、6 或 5 上使用 lambda 表达式、方法引用和 try-with-resources 语句运行 Java 8 代码

    对于轻量级流 API 的反向移植,您可以尝试:

    https://sourceforge.net/projects/streamsupport/

    您也可以使用 RxJava 实现类似的功能

    【讨论】:

    • 谢谢,我也尝试将 Apache Commons 与 Predicates 一起使用,但也遇到了一些错误。我会试试看,谢谢你的帮助。
    • 另外,Lightweight-Stream-API 不能弥补 retrolambda 的这个缺点吗?如何解决我提到的第二个错误?
    • 我还没有尝试过 Lightweight-Steam-API,只有 streamsupport 库。它确实有效,但是由于接口名称的更改,我经常发现您遇到的上述问题 - 我认为这将是问题所在。我现在只使用 Rx
    • @Yankee 这不是 RefStreams.of(这相当于 Java 8 Stream.of 并生成一个包含您的 List 作为单个元素的流)。而是使用静态方法java8.util.stream.StreamSupport.stream(Collection),一切都应该没问题。
    • @Yankee 这没有意义。 com.util.stream 是什么?为什么你有一个collect 方法需要java.util.stream.Collector 而不是java8.util.stream.Collector。错误的进口?有关可编译的代码,请参见我的示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2017-09-26
    • 1970-01-01
    • 2021-03-16
    • 2017-06-14
    相关资源
    最近更新 更多