I need to expose an API - consume(sequence) below - which mandates that its argument sequence collection be ordered as in the below excerpt:
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());
}
}
Typically one would specify consume() as accepting a List; however, some producers also expose a Deque, so as to facilitate things like efficient reverse-iteration using descendingIterator(). However Deque doesn't extend List and there are likely good reasons for this (O(n) cost of accessing an indexed element in a LinkedList).
So it seems the only way to "keep the compiler happy" is to specify sequence as a Collection; however, according to the Javadoc (and as we all know), a "some are ordered and others unordered", so the consume() API looses in semantics.
Another workaround would be to have Producer2 expose a LinkedList rather than a Deque (and revert consume() to accept a List) but we know it's not ideal to expose implementations rather than interfaces.
It seems the ideal solution would be for Java to provide a Sequence super-interface to List and Deque (extending Iterable). I can imagine one reason this wasn't done is complexity but I think this example demonstrates the need.
Am I missing a better strategy here or do I just need to wait for a revision of the API? For the record, this is Java 17.
