如何使用Java 8 Streams填充ArrayList直到达到指定的最大项目数?

4

我是Java 8的新手,正在学习流。我试图填充一个消息ArrayList,该列表具有指定日期之后的日期。我需要这个新的ArrayList最多有16个项目。我尝试了以下内容:

private static final int MAX_MESSAGES_NUM = 16;

public ArrayList<Messages> filterMessagesByData(Calendar filterDate, ArrayList<Messages> messagesList) {
    ArrayList<Messages> filteredMessages = new ArrayList<Messages>();
    int msgCount = 0;
    messagesList.stream().filter(message -> {

        Calendar msgDate = new GregorianCalendar();
        try {
            msgDate.setTime(new SimpleDateFormat("dd/MM/yy").parse(message.getDate()));
            msgCount ++;
        } catch (ParseException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
        return (msgDate.compareTo(filterDate) >= 0) && msgCount < MAX_MESSAGES_NUM;
    }).forEach(filteredMessages::add);

    return filteredMessages;
}

但是在msgCount++这一行,它给我报错:

定义在封闭作用域中的局部变量msgCount必须是final或有效final。

我认为在lambda表达式中不能修改外部变量。

是否可以使用流和过滤器来完成?

1个回答

8

您可以使用Stream.limit(maxSize)来限制Stream中元素的数量:

public List<Messages> filterMessagesByData(Calendar filterDate, ArrayList<Messages> messagesList) {
    return messagesList.stream().filter(message -> {
        Calendar msgDate = Calendar.getInstance();
        try {
            msgDate.setTime(new SimpleDateFormat("dd/MM/yy").parse(message.getDate()));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return msgDate.compareTo(filterDate) >= 0;
    }).limit(MAX_MESSAGES_NUM).collect(Collectors.toList());
}

我对您最初的代码进行了一些更改:

  • new GregorianCalendar()被替换为Calendar.getInstance()
  • 可以直接使用Collectors.toList()将所有元素收集到列表中,而不是使用forEach
  • 简化了异常处理,使原始异常保存为原因,从而无需将堆栈跟踪写入stderr。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接