java 如何基于 predicate 创建活动子集合?

sxissh06  于 12个月前  发布在  Java
关注(0)|答案(2)|浏览(121)

背景

我有一个接口

public interface ThingRegistry {

    public Set<Thing> getAllThings();
    public Set<Thing> getAllThingsWithProperty(String property);
}

字符串
及其实现

public class MemoryThingRegistry {
    private final Set<Thing> things = new HashSet<>();

    public Set<Thing> getAllThings() {
        return Collections.unmodifiableSet(this.things);
    }

    public Set<Thing> getAllThingsWithProperty(final String property) {
        return this.things.stream().filter((thing) -> thing.hasProperty(property)).collect(Collectors.toUnmodifiableSet());
    }
}

  • 问题 *
  • getAllThings()返回的Set将反映在我的注册表中所做的任何更改
  • 但是,getAllThingsWithProperty()返回的Set不会反映这些更改
  • 问题 *

有没有办法使用标准的java库,或者一些非常常见的第三方库,使getAllThingsWithProperty()的返回值成为一个“活”的子Set?即它“支持”原来的Set,但每次访问时都重新应用Predicate?最好是可以应用于任何Collection的东西,因为我有另一个使用List的注册表接口。
我知道我可以编写自己的Set实现,但我宁愿避免这样做。

zdwk9cvp

zdwk9cvp1#

而不是一个返回Set<Thing>的方法。你可以写一个返回Supplier<Set<Thing>>的方法。每次你想得到当前的Set,你就调用那个Supplierget()方法。

public Supplier<Set<Thing>> getAllThingsWithProperty(final String property) {
    return () -> this.things.stream().filter((thing) -> thing.hasProperty(property)).collect(Collectors.toSet());
}

字符串

quhf5bfb

quhf5bfb2#

使用AbstractSet来实现Set是相当简单的。你所需要做的就是实现sizeiterator方法。你已经在使用流了,所以你可以只使用流来实现这些方法:

public static <E> Set<E> filteredSet(Set<E> set, Predicate<? super E> pred) {
    return new AbstractSet<>() {
        public int size() {
            return (int) set.stream().filter(pred).count();
        }

        public Iterator<E> iterator() {
            return set.stream().filter(pred).iterator();
        }
    };
}

字符串
这是一个功能齐全的只读Set。它提供了后台集的“实时视图”,因为它的元素在每个操作中都被流式传输和过滤。
这对于元素数量较少的集合是可行的,但随着元素数量的增加,它会明显变慢。例如,contains方法可能会迭代整个集合,因此是O(N)。您可以重写contains方法以直接委托给后台集合。这将降低底层集合提供的时间复杂度-对于HashSet,这是O(1)--但其中有一些微妙之处。
要使set可读写,你需要实现add方法并重新实现迭代器,使其支持remove方法。但是你首先返回的是不可修改的set,所以也许你不需要这样做。
如果你需要用List做一些类似的事情,看看AbstractList。它相当简单。或者用AbstractCollection Package 任何集合,就像这里用AbstractSet Package 集合一样。

相关问题