高级java 8流使用问题

高级java 8流使用问题,java,java-8,java-stream,Java,Java 8,Java Stream,我试图使用Java8流对消息和成员的列表执行操作 消息是来自我的域模型的实体。消息具有类型为成员的发送方字段和接收方字段 成员是我的域模型中的第二个实体。成员具有已发送消息的集合和已接收消息的集合 成员JPA实体: @Entity public class Member implements UserDetails { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strate

我试图使用Java8流对
消息
成员
的列表执行操作

消息是来自我的域模型的实体。
消息
具有类型为
成员
发送方
字段和
接收方
字段

成员是我的域模型中的第二个实体。
成员具有已发送消息的集合和已接收消息的集合

成员JPA实体

@Entity
public class Member implements UserDetails {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    ...    

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "sender")
    private Collection<Message> sentMessages;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "recipient")
    private Collection<Message> receivedMessages;

    @Version
    private Integer version;
@Entity
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    private Member sender;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    private Member recipient;

    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(pattern = "dd/MM/yyyy HH:mm:ss")
    private Date sendDate;

    private boolean messageRead;

    @NotNull
    @Size(min = 5, max = 500)
    @Column(length = 500)
    private String text;

    @Version
    private Integer version;
集合
(来自给定成员的已发送和已接收消息的组合列表)中,我希望获得一个
SortedMap
,其中包含来自另一个成员的最新发送或已接收消息作为键,另一个成员作为值

有谁能提供一些关于如何使用Java8流来实现这一点的建议或想法吗

编辑1:以下是请求的输入/输出示例:

输入(
消息的内容
表格):

具有#2的成员的输出应该是具有#5和#4

说明:涉及成员#2和成员#1的最新发送或接收的消息是消息#4,涉及成员#2和成员#6的最新消息是消息#5

成员#2和成员#1之间的其他消息较旧,因此不考虑


最终目标是实现一个消息框,如whatsapp/hangout或fb,我可以在其中显示当前登录用户和其他每个用户之间最近发送或接收的消息。

您可以按收件人对发送的消息进行分组,然后为每个收件人找到最新的消息(未测试,可能有一些拼写错误):

Map
成员消息=
sentMessages.stream()
.collect(收集器).groupingBy(消息::getRecipient,
Collectors.maxBy(Comparator.comparingLong(m->m.getSendDate().getTime()));
这将为您提供与所需相反的键和值,但它应该可以帮助您开始。例如,您可以创建反向映射,方法是创建此映射的条目流,然后使用
toMap
收集它,在过程中反转键和值


我不确定是否可以在单个流管道中完成整个过程。

您可以按收件人对发送的邮件进行分组,然后查找每个收件人的最新邮件(未测试,可能有一些拼写错误):

Map
成员消息=
sentMessages.stream()
.collect(收集器).groupingBy(消息::getRecipient,
Collectors.maxBy(Comparator.comparingLong(m->m.getSendDate().getTime()));
这将为您提供与所需相反的键和值,但它应该可以帮助您开始。例如,您可以创建反向映射,方法是创建此映射的条目流,然后使用
toMap
收集它,在过程中反转键和值


我不确定整个过程是否可以在单流管道中完成。

如果我理解得很好,这(不是一条线性管道)是一种可能的实现:

SortedMap<Message, Member> sortedMap = new TreeMap<>(Comparator.comparing(Message::getSendDate).reversed());
myCombinedCollection.forEach(m -> sortedMap.put(m, m.getRecipient()));
完成后,将消息放入映射中,并使用下游收集器获取最新消息:

  Map<String, Optional<Message>> map = myCombinedCollection.stream()
                         .collect(groupingBy(Message::mapping, maxBy(Comparator.comparing(Message::getSendDate))));
这里的键并不重要,因为您只对消息感兴趣。您可以从该映射中获取一个
列表
,首先过滤空值:

List<Message> messages = map.entrySet().stream()
                                       .filter(e -> e.getValue().isPresent())
                                       .map(e -> e.getValue().get())
                                       .collect(toList());
如果你想看到一个小的实现,我创建了这个小的


我不知道这些藏品是怎么填满的;但是,为每个成员实现一个缓存映射可能是值得的,这样当发送/接收新消息时,您就可以更新映射。这将比获取所有组合消息更有效


希望有帮助!:)

如果我理解得很好,这(不是一行程序)是一种可能的实现:

SortedMap<Message, Member> sortedMap = new TreeMap<>(Comparator.comparing(Message::getSendDate).reversed());
myCombinedCollection.forEach(m -> sortedMap.put(m, m.getRecipient()));
完成后,将消息放入映射中,并使用下游收集器获取最新消息:

  Map<String, Optional<Message>> map = myCombinedCollection.stream()
                         .collect(groupingBy(Message::mapping, maxBy(Comparator.comparing(Message::getSendDate))));
这里的键并不重要,因为您只对消息感兴趣。您可以从该映射中获取一个
列表
,首先过滤空值:

List<Message> messages = map.entrySet().stream()
                                       .filter(e -> e.getValue().isPresent())
                                       .map(e -> e.getValue().get())
                                       .collect(toList());
如果你想看到一个小的实现,我创建了这个小的


我不知道这些藏品是怎么填满的;但是,为每个成员实现一个缓存映射可能是值得的,这样当发送/接收新消息时,您就可以更新映射。这将比获取所有组合消息更有效


希望有帮助!:)

重新阅读你的问题和我的答案,我不确定这是你想要实现的。有可能有一个输入/输出的小例子来确定吗?当然。请容忍我…谢谢你们两位的意见。我对我的问题进行了编辑,使之更加精确。我终于想出了一些办法。你能看一下吗?重新阅读你的问题和我的答案,我不确定这是你想要实现的。有可能有一个输入/输出的小例子来确定吗?当然。请容忍我…谢谢你们两位的意见。我对我的问题进行了编辑,使之更加精确。我终于想出了一些办法。你能看一下吗?
List<Message> messages = map.entrySet().stream()
                                       .filter(e -> e.getValue().isPresent())
                                       .map(e -> e.getValue().get())
                                       .collect(toList());
[5-Thu Apr 01 00:00:00 CEST 3915:Hi there dude, 4-Fri Apr 02 09:45:00 CEST 3915:Je suis disponible]