nazar_art February 2016

Have to work with object which has Set of enties using Java 8?

I have to implement method with the following signature:

public Set<Event> getForDateRange(Calendar from, Calendar to)

My Event class looks like:

public class Event {

    private Integer id;
    private String name;
    private Integer price;
    private Rating rating;

    private Set<Calendar> eventDateTime;

I can not find how to get all dateTimes for everyone event. Here is what I have so far:

public Set<Event> getForDateRange(Calendar from, Calendar to) {
    Set<Event> result = Collections.emptySet();
    Set<Event> allEvents = getAll();
    for (Event event : allEvents) {
        Set<Calendar> eventDateTime = event.getEventDateTime();
        result.addAll(eventDateTime.stream()
                .filter(date -> date.after(from) && date.before(to))
                .map(date -> event)
                .collect(Collectors.toSet()));
    }
    return result;
}

I am using the mixture of iterative style with functional. How to write this method using functional style only?

Answers


Andremoniy February 2016

I guess you want to do this in one-line in functional style:

    Set<Event> result = allEvents.stream().
            filter(
                    event -> !event.getEventDateTime().
                            stream().
                            filter(date -> date.after(from) && date.before(to)).collect(Collectors.toSet())
                            .isEmpty()
            ).
            collect(Collectors.toSet());

UPD: where filter(date -> date.after(from) && date.before(to)).collect(Collectors.toSet()) .isEmpty() can be replaced with @Tunaki's solution with anyMatch(...) which is much better.


Tunaki February 2016

Your current code is a bit weird: .map(date -> event) is mapping for all dates the same event.

What you want is to retain all events such that one of the event time is between from and to. You can obtain that with anyMatch. This operation returns whether any of the stream element matches the given predicate. In this case, if any dates are between from and to, we keep the event and collect that into a Set.

public Set<Event> getForDateRange(Calendar from, Calendar to) {
    Set<Event> allEvents = getAll();

    return allEvents.stream()
            .filter(event -> event.getEventDateTime()
                    .stream()
                    .anyMatch(date -> date.after(from) && date.before(to))
            )
            .collect(Collectors.toSet());
}

Post Status

Asked in February 2016
Viewed 1,124 times
Voted 10
Answered 2 times

Search




Leave an answer