I'm new to Java 8 and I'm studying streams. I'm trying to populate an ArrayList of Messages that has a date after a specified date. I need that this new ArrayList has a maximum of 16 items. I tried the following:
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;
}
but it gives me an error at line msgCount++
:
Local variable msgCount defined in an enclosing scope must be final or effectively final.
I suspect that external variables can't be modified in a lambda expression.
Is there a way that it can accomplished using streams and filters?
You can use Stream.limit(maxSize)
to limit the number of elements in the 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());
}
I changed a couple of things in your initial code:
new GregorianCalendar()
was replaced with Calendar.getInstance()
.forEach
, you can directly collect all the elements in a list using Collectors.toList()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With