简体   繁体   中英

Cleaner way to filter collections in Java 7/Guava?

I have the following classes:

class ServiceSnapshot {
    List<ExchangeSnapshot> exchangeSnapshots = ...
    ...
}

class ExchangeSnapshot{
    Map<String, String> properties = ...
    ...
}

SayI have a collection of ServiceSnapshots, like so:

Collection<ServiceSnapshot> serviceSnapshots = ...

I'd like to filter the collection so that the resulting collection of ServiceSnapshots only contains ServiceSnapshots that contain ExchangeSnapshots where a property on the ExchangeSnapshots matches a given String.

I have the following untested code, just wondering is there a cleaner/more readable way to do this, using Java 7, and maybe Google Guava if necessary?

Updtae: Note also that the code sample I've provided below isn't suitable for my purposes, since I'm using iterator.remove() to filter the collection. It turns out I cannot do this as it is modifying the underlying collection , meaning subsequent calls to my method below result in fewer and fewer snashots due to previous calls removing them from the collection - this is not what I want.

    public Collection<ServiceSnapshot> getServiceSnapshotsForComponent(final String serviceId, final String componentInstanceId) {
        final Collection<ServiceSnapshot> serviceSnapshots = getServiceSnapshots(serviceId);
        final Iterator<ServiceSnapshot> serviceSnapshotIterator = serviceSnapshots.iterator();
        while (serviceSnapshotIterator.hasNext()) {
            final ServiceSnapshot serviceSnapshot = (ServiceSnapshot) serviceSnapshotIterator.next();
            final Iterator<ExchangeSnapshot> exchangeSnapshotIterator = serviceSnapshot.getExchangeSnapshots().iterator();
            while (exchangeSnapshotIterator.hasNext()) {
                final ExchangeSnapshot exchangeSnapshot = (ExchangeSnapshot) exchangeSnapshotIterator.next();
                final String foundComponentInstanceId = exchangeSnapshot.getProperties().get("ComponentInstanceId");
                if (foundComponentInstanceId == null || !foundComponentInstanceId.equals(componentInstanceId)) {
                    exchangeSnapshotIterator.remove();
                }
            }
            if (serviceSnapshot.getExchangeSnapshots().isEmpty()) {
                serviceSnapshotIterator.remove();
            }
        }
        return serviceSnapshots;
    }

Using Guava:

Iterables.removeIf(serviceSnapshots, new Predicate<ServiceSnapshot>() {
    @Override
    public boolean apply(ServiceSnapshot serviceSnapshot) {
        return !Iterables.any(serviceSnapshot.getExchangeSnapshots(), new Predicate<ExchangeSnapshot>() {
            @Override
            public boolean apply(ExchangeSnapshot exchangeSnapshot) {
                String foundComponentInstanceId = exchangeSnapshot.getProperties().get("ComponentInstanceId");
                return foundComponentInstanceId != null && foundComponentInstanceId.equals(componentInstanceId);
            }
        });
    }
});

I may have a ! missing or inverted somewhere, but the basic strategy is to remove any ServiceSnapshot objects that do not have any ExchangeSnapshot whose ID matches.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM