Java 当通过泛型参数传递时,筛选器将失去对内部对象方法的访问

Java 当通过泛型参数传递时,筛选器将失去对内部对象方法的访问,java,generics,lambda,filter,java-8,Java,Generics,Lambda,Filter,Java 8,我在一个方法中有一个并行流,当我以这种方式运行它时,它工作得很好 Meeting是一个接口,其实现有一个私有的int-id成员字段和一个getter方法getId public class MyClass { private List<Meeting> myMeetings = new ArrayList<>(); public PastMeeting getPastMeeting (int id){ Meeting meetingW

我在一个方法中有一个并行流,当我以这种方式运行它时,它工作得很好

Meeting是一个接口,其实现有一个私有的int-id成员字段和一个getter方法getId

public class MyClass {
   private List<Meeting> myMeetings = new ArrayList<>();

   public PastMeeting getPastMeeting (int id){
            Meeting meetingWithId;
            meetingWithId = myMeetings.parallelStream()
                    .filter(meeting -> meeting.getId() == id )
                    .findFirst()
                    .get();
            return meetingWithId;
        }
}
但是,我必须从myClass中的其他几个方法执行此操作,因此我需要将该操作作为自己的方法,并将下面的方法添加到myClass中,因为我可能有不同的Meeting实现,因此列表的类型也不同,所以我将参数设置为泛型。但是,当我以这种方式运行它时,过滤器无法访问会议的getId方法,说它无法解析m.getId

private <T, R> T returnMeeting(T meeting, List<R> meetingList, int id) {        
        meeting = meetingList.parallelStream()
                .filter(m -> m.getId() == id )
                .findFirst()
                .get();
        return meeting;
}

我不知道为什么,因为代码完全相同。运行通用参数字段是否导致lambda可以假定的中断?谢谢。

因为您没有向泛型参数添加类型边界,所以只有对象上的方法可用

您有两个选择:

添加一个类型绑定,该绑定强制具有要使用的方法的特定类型/接口

interface IdProvider {
   int getId();
}

private <T extends IdProvider> T returnMeeting(List<T> meetingList, int id)    {        
    return meetingList.parallelStream()
            .filter(m -> m.getId() == id )
            .findFirst()
            .get();
}
或者向定义如何解析id的方法添加另一个参数

private <T> T returnMeeting(List<T> meetingList, int id, Function<T,Integer> idGetter) {        
    return meetingList.parallelStream()
            .filter(m -> idGetter.apply(m).equals(id) )
            .findFirst()
            .get();
}

由于不向泛型参数添加类型边界,所以只有对象上的方法可用

您有两个选择:

添加一个类型绑定,该绑定强制具有要使用的方法的特定类型/接口

interface IdProvider {
   int getId();
}

private <T extends IdProvider> T returnMeeting(List<T> meetingList, int id)    {        
    return meetingList.parallelStream()
            .filter(m -> m.getId() == id )
            .findFirst()
            .get();
}
或者向定义如何解析id的方法添加另一个参数

private <T> T returnMeeting(List<T> meetingList, int id, Function<T,Integer> idGetter) {        
    return meetingList.parallelStream()
            .filter(m -> idGetter.apply(m).equals(id) )
            .findFirst()
            .get();
}

首先,你不需要两个参数变量t和R——它们总是一样的。因此,您可以删除T会议辩论

第二,向编译器显式说明R类型是实现会议接口的东西,getId方法也是如此

整个代码:

private <R extends Meeting> R returnMeeting(List<R> meetingList, int id) {
        return meetingList.parallelStream()
                .filter(m -> m.getId() == id )
                .findFirst()
                .get();
}

另外请注意,如果列表中未找到meeting,则.get可能会在此处导致NullPointerException,因此最好使用.orElsenull或只返回可选变量本身。

首先,您不需要两个参数变量t和R-它们总是相同的。因此,您可以删除T会议辩论

第二,向编译器显式说明R类型是实现会议接口的东西,getId方法也是如此

整个代码:

private <R extends Meeting> R returnMeeting(List<R> meetingList, int id) {
        return meetingList.parallelStream()
                .filter(m -> m.getId() == id )
                .findFirst()
                .get();
}

另外请注意,如果列表中未找到meeting,则.get可能会导致此处出现NullPointerException,因此最好使用.orElsenull,或者只返回可选参数本身。

您的泛型参数没有表示它们属于meeting类型。此外,会议参数是不必要的。请尝试以下方法:

private <T extends Meeting> T returnMeeting(List<T> meetingList, int id) {        
    return meetingList.parallelStream()
            .filter(m -> m.getId() == id )
            .findAny()
            .orElse(null);
}

您的泛型参数不表示它们属于会议类型。此外,会议参数是不必要的。请尝试以下方法:

private <T extends Meeting> T returnMeeting(List<T> meetingList, int id) {        
    return meetingList.parallelStream()
            .filter(m -> m.getId() == id )
            .findAny()
            .orElse(null);
}

不幸的是,在这种情况下,返回可选项不是一个选项。如果使用.orElsenull,则无法再调用get返回会议。有没有一种简单的方法可以返回空会议?@NateH06你认为orElse会做什么?@NateH06 orElsenull就是这样做的!返回find Meeting或null(如果未找到任何内容)。你不需要去追orElse。orElsenull就像是如果!optional.isEmtpy{return optional.get;}else{return null;}。啊,这很有道理,谢谢!我原以为orElse自己会返回一个可选选项。以前,get抛出了一个NoSuchElementException,但是现在。当我调用该方法时,orElsenull抛出了一个NullPointerException,例如,假设myBadInt不包含在meetingList中:`Meeting myMeeting=returnMeetingmeetingList,myBadInt;不,如果使用.orElsenull,您的returnMeeting只返回null。代码中还有其他内容,它使用该返回值并抛出NullPointerException。观察这个NPE抛出的轨迹。实际上,这正是为什么返回Optional是一个更好的主意以及为什么Optional类被引入Java语言的原因。这将强制代码使用返回值显式检查它是否存在。不幸的是,在这种情况下,返回可选值不是选项。如果使用.orElsenull,则无法再调用get返回会议。有没有一种简单的方法可以返回空会议?@NateH06你认为orElse会做什么?@NateH06 orElsenull就是这样做的!返回find Meeting或null(如果未找到任何内容)。你不需要去追orElse。orElsenull就像是如果!optional.isEmtpy{return optional.get;}else{return null;}。啊,这很有道理,谢谢!我原以为orElse自己会返回一个可选选项。以前,get抛出了一个NoSuchElementException,但是现在。当我调用该方法时,orElsenull抛出了一个NullPointerException,例如,假设myBadInt不包含在meetingList中:`Meeting myMeeting=returnMeetingmeetingList,myBadInt;不,如果使用.orElsenull,您的returnMeeting只返回null。代码中还有其他内容,它使用该返回值并抛出NullPointerException。观察这个NPE抛出的轨迹。实际上这是我的前任 实际上,返回Optional是一个更好的主意,也是将Optional类引入Java语言的原因之一。这将强制代码,它将使用返回值显式检查它是否存在。