notification-portlet-api/src/main/java/org/jasig/portlet/notice/NotificationResponse.java
public NotificationResponse filter(Predicate<NotificationEntry> predicate) {

        final List<NotificationCategory> filteredCategories = categories.stream()
                .map(category -> {
                    final List<NotificationEntry> filteredEntries = category.getEntries().stream()
                            .filter(predicate)
                            .collect(Collectors.toList());
                    return filteredEntries.size() > 0
                            ? new NotificationCategory(category.getTitle(), filteredEntries)
                            : null;
                })
                .filter(value -> value != null)
                .collect(Collectors.toList());
        return new NotificationResponse(filteredCategories, getErrors()); // deep copy

    }
public NotificationResponse filter(Predicate<NotificationEntry> predicate) {

        final List<NotificationCategory> filteredCategories = categories.stream()
                .map(category -> {
                    final List<NotificationEntry> filteredEntries = category.getEntries().stream()
                            .filter(predicate)
                            .collect(Collectors.toList());
                    return filteredEntries.size() > 0
                            ? new NotificationCategory(category.getTitle(), filteredEntries)
                            : null;
                })
                .filter(value -> value != null)
                .collect(Collectors.toList());
        return new NotificationResponse(filteredCategories, getErrors()); // deep copy

    }
Return a <b>new instance</b> of {@link NotificationResponse} containing only
{@link NotificationEntry} objects within this response that match the specified
<code>Predicate</code>.  The category structure is preserved.  Empty categories are removed.