过滤器失去对内部对象的访问权限。通过泛型参数传递的方法

时间:2017-01-02 01:38:32

标签: 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 meetingWithId;
            meetingWithId = myMeetings.parallelStream()
                    .filter(meeting -> meeting.getId() == id )
                    .findFirst()
                    .get();
            return meetingWithId;
        }
}

但是,我必须从myClass中的其他几个方法执行此操作,所以我需要将该操作作为自己的方法,并且我已将下面的方法添加到myClass,因为我可能有不同的实现会议和因此不同类型的列表,所以我使参数成为通用的。但是,当我以这种方式运行时,过滤器无法访问Meeting的getId()方法,说它&#34;无法解析m.getId();&#34;

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可以假设的中断?谢谢。

3 个答案:

答案 0 :(得分:5)

由于您没有为通用参数添加类型边界,因此只有Object上的方法可用。

您有两种选择:

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

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

答案 1 :(得分:4)

首先,您不需要两个参数变量TR - 它们都必须相同。因此,您可以删除T meeting争论。

其次,向编译器明确R类型是实现Meeting接口的东西,因此getId()方法也是如此。

List<R extends Meeting> meetingList

整个代码:

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

另请注意,如果在列表中找不到会议,则.get()可能会导致NullPointerException,因此最好使用.orElse(null)或仅返回Optional本身。

答案 2 :(得分:3)

您的通用参数没有表明它们属于Meeting类型。此外,meeting参数是不必要的。试试这个:

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