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

时间:2015-09-25 12:34:07

标签: java lambda java-8 java-stream

我是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必须是最终的或有效的最终。

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

有没有办法可以使用流和过滤器完成?

1 个答案:

答案 0 :(得分: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。