背景
我有一个接口
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
实现,但我宁愿避免这样做。
2条答案
按热度按时间zdwk9cvp1#
而不是一个返回
Set<Thing>
的方法。你可以写一个返回Supplier<Set<Thing>>
的方法。每次你想得到当前的Set
,你就调用那个Supplier
的get()
方法。字符串
quhf5bfb2#
使用
AbstractSet
来实现Set
是相当简单的。你所需要做的就是实现size
和iterator
方法。你已经在使用流了,所以你可以只使用流来实现这些方法:字符串
这是一个功能齐全的只读
Set
。它提供了后台集的“实时视图”,因为它的元素在每个操作中都被流式传输和过滤。这对于元素数量较少的集合是可行的,但随着元素数量的增加,它会明显变慢。例如,
contains
方法可能会迭代整个集合,因此是O(N)。您可以重写contains
方法以直接委托给后台集合。这将降低底层集合提供的时间复杂度-对于HashSet
,这是O(1)--但其中有一些微妙之处。要使set可读写,你需要实现
add
方法并重新实现迭代器,使其支持remove
方法。但是你首先返回的是不可修改的set,所以也许你不需要这样做。如果你需要用
List
做一些类似的事情,看看AbstractList
。它相当简单。或者用AbstractCollection
Package 任何集合,就像这里用AbstractSet
Package 集合一样。