How to check if two ZonedDateTime objects represent the same day?

ZonedDateTime has been introduced in Java 8 and is a great choice when you would like to work with dates that contain time zone information.

It has an awesome truncatedTo(...) method, that lets you truncate it to specific parts. If we would like to check if two ZonedDateTime objects refer to the same day, we could use this method to first truncate them to days, then we can compare them using the equals method.

Here is an example of a method that does this:

private boolean isSameDay(ZonedDateTime date1, ZonedDateTime date2) {
    return date1.truncatedTo(ChronoUnit.DAYS).equals(date2.truncatedTo(ChronoUnit.DAYS));
}

Of course, if you want to do the check for something else (like hours, months, etc.), you can use a different ChronoUnit.

How to create a list of objects using a range of numbers in Java 8

The Java 8 Stream API could come in handy when you would like to generate a series of objects for example for using them in a unit test.

The following snippet generates a list of 5 User objects with the id and name populated:

List<User> users = IntStream.range(0, 5).mapToObj(i -> {

    User user = new User();
    user.setId(i);
    user.setName(USER_NAME_PREFIX + String.valueOf(i));

    return user;

}).collect(Collectors.toList());

If you have a suitable constructor, you can even make it a lot shorter:

List<User> users = IntStream.range(0, 5)
    .mapToObj(i -> new User(i, USER_NAME_PREFIX + String.valueOf(i)))
    .collect(Collectors.toList());

 

Remove element from a list during iteration in Java

When you are iterating through a list it often happens that you also want to remove some elements in the process. For example, you have a list of elements, and you only want to keep some of them, that match certain criterias. This seems like a very easy task to do, but it has some pitfalls that is not so obvious to avoid.

Let’s create a list of 5 integers, that we will use throughout our examples.

List<Integer> elementList = new ArrayList<>();
elementList.add(10);
elementList.add(20);
elementList.add(30);
elementList.add(40);
elementList.add(50);

Our task is to remove all the numbers that are either greater than 45 or less than 25. You can easily see, that this should leave us with a list that contains only 30 and 40.

Try to remove element with foreach

One of the obvious options is to go through the list with a foreach loop and just remove the elements that you don’t need. Like this:

for (Integer element : elementList) {
    if((element > 45) || (element < 25)) {
        elementList.remove(element);
    }
}

You might think that this should work. But it does not. It will throw you an exception similar to this:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    at java.util.ArrayList$Itr.next(ArrayList.java:851)
    at example.ExampleMain.main(ExampleMain.java:18)

This is because you cannot remove elements from a list while iterating over it in a foreach loop, as it could cause some unexpected behaviour, so to be on the safe side, this is simply not allowed. But there are ways to overcome this limitation.

Working example: Iterator

Using an iterator you are able to remove elements on the fly, while iterating.

Iterator<Integer> elementListIterator = elementList.iterator();
while (elementListIterator.hasNext()) {
    Integer element = elementListIterator.next();
   
    if((element > 45) || (element < 25)) {
        elementListIterator.remove();
    }
}

This works, because the iterator acts as a middle layer to make sure that iterating can continue even if the underlying collection changes.

And to give a more concrete explanation of the failure of our previous method, here is a snippet from the documentation of the ArrayList:

The iterators returned by this class’s iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator’s own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

So only the iterator’s own methods could be used, but in the first example we modified the list by using the list’s own remove method. This was what caused the problem.

Working example: Java 8 lamba expression

In Java 8, the method removeIf has been introduced for collections. It allows you to remove all elements from the collection that satisfy the given predicate. It is nice and short, only takes one line:

elementList.removeIf(element -> (element > 45) || (element < 25));

That’s it. One line, no frills, it just works and easily understandable.