在Java 7 / Guava中过滤集合的更清洁方法?

时间:2015-07-29 14:17:06

标签: java refactoring guava code-readability

我有以下课程:

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

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

SayI有一组ServiceSnapshots,如下所示:

Collection<ServiceSnapshot> serviceSnapshots = ...

我想过滤集合,以便生成的ServiceSnapshots集合仅包含ServiceSnapshots,其中包含ExchangeSnapshots,其中ExchangeSnapshots上的属性与给定的String匹配。

我有以下未经测试的代码,只是想知道是否有更清晰/更易读的方法来执行此操作,使用Java 7,如果需要可能还有Google Guava?

更新:另请注意,我在下面提供的代码示例不适合我的目的,因为我使用iterator.remove()来过滤集合。事实证明我不能这样做,因为它正在修改底层集合,这意味着后面对我的方法的调用导致越来越少的snashots由于之前的调用从集合中删除它们 - 这不是我想要的。

    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;
    }

1 个答案:

答案 0 :(得分:0)

使用番石榴:

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);
            }
        });
    }
});

我的某个地方可能遗漏了某个!,但基本策略是删除任何没有ID匹配的ServiceSnapshot的{​​{1}}个对象。