我需要公开一个API-consume(sequence)
(见下文),该API要求其argument sequence
集合按以下节选进行排序:
interface Consumer<T> {
/**
* @param sequence: an *ordered* collection of Ts to be processed in order
*/
public void consume(Collection<T> sequence);
}
interface Producer<T> {
Collection<T> getSequence();
}
class Producer1<T> implements Producer<T> {
public List<T> getSequence() {
return new ArrayList<>();
}
}
class Producer2<T> implements Producer<T> {
public Deque<T> getSequence() {
return new LinkedList<>();
}
}
class Test {
void testMethod(Consumer<Long> consumer) {
consumer.consume(new Producer1<Long>().getSequence());
consumer.consume(new Producer2<Long>().getSequence());
}
}
通常,人们会将consume()
指定为接受List
;然而,一些生产商也公开了Deque
,以便于使用descendingIterator()
进行高效的反向迭代.然而,Deque
并没有扩展List
,并且有likely good reasons(在LinkedList
中访问索引元素的O(n)成本).
因此,"让编译器满意"的唯一方法似乎是将sequence
指定为Collection
;然而,根据Javadoc(我们都知道),一个"有些是有序的,有些是无序的",所以consume()
API在语义上是松散的.
另一个解决方法是让Producer2
公开LinkedList
而不是Deque
(并将consume()
还原为接受List
),但我们知道公开实现而不是接口并不理想.
对于Java来说,理想的解决方案似乎是为List
和Deque
(扩展Iterable
)提供Sequence
个超级接口.我可以想象没有做到这一点的一个原因是复杂性,但我认为这个例子证明了这一点.
我是缺少更好的策略,还是只需要等待API的修订?请记住,这是Java 17.