Abstractions live longer than implementations

In general the more abstract your design the longer it is likely to remain useful. So, since Collection is more abstract that it's sub-interfaces then an API design based on Collection is more likely to remain useful than one based on List.

However, the overarching principle is to use the most appropriate abstraction. So if your collection must support ordered elements then mandate a List, if there are to be no duplicates then mandate a Set, and so on.

A note on generic interface design

Since you're interested in using the Collection interface with generics you may the following helpful. Effective Java by Joshua Bloch recommends the following approach when designing an interface that will rely on generics: Producers Extend, Consumers Super

This is also known as the PECS rule. Essentially, if generic collections that produce data are passed to your class the signature should look like this:

public void pushAll(Collection<? extends E> producerCollection) {}

Thus the input type can be E or any subclass of E (E is defined as both a super- and sub-class of itself in the Java language).

Conversely, a generic collection that is passed in to consume data should have a signature like this:

public void popAll(Collection<? super E> consumerCollection) {}

The method will correctly deal with any superclass of E. Overall, using this approach will make your interface less surprising to your users because you'll be able to pass in Collection<Number> and Collection<Integer> and have them treated correctly.

Answer from Gary on Stack Exchange
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › Collection.html
Collection (Java Platform SE 8 )
3 weeks ago - Bags or multisets (unordered collections that may contain duplicate elements) should implement this interface directly. All general-purpose Collection implementation classes (which typically implement Collection indirectly through one of its subinterfaces) should provide two "standard" constructors: a void (no arguments) constructor, which creates an empty collection, and a constructor with a single argument of type Collection, which creates a new collection with the same elements as its argument.
🌐
GeeksforGeeks
geeksforgeeks.org › java › collection-interface-in-java-with-examples
Collection Interface in Java - GeeksforGeeks
Instead, we create an object of the ArrayList class that implements the interface and assign it to the interface reference. The Collection interface is part of a hierarchy that extends Iterable, which means collections can be traversed.
Published   5 days ago
🌐
Oracle
docs.oracle.com › javase › tutorial › collections › interfaces › collection.html
The Collection Interface (The Java™ Tutorials > Collections > Interfaces)
In other words, it allows you to convert the collection's type. Suppose, for example, that you have a Collection<String> c, which may be a List, a Set, or another kind of Collection. This idiom creates a new ArrayList (an implementation of the List interface), initially containing all the elements in c.
🌐
Programiz
programiz.com › java-programming › collection-interface
Java Collection Interface
The Collection interface is the root interface of the Java collections framework. There is no direct implementation of this interface. However, it is implemented through its subinterfaces like List, Set, and Queue. For example, the ArrayList class implements the List interface which is a ...
🌐
Tutorialspoint
tutorialspoint.com › java › java_collection_interface.htm
Java - Collection Interface
Java Vs. C++ ... The Collection interface is the foundation upon which the collections framework is built. It declares the core methods that all collections will have. There are several methods in the Collection interface to perform basic operations ...
🌐
W3Schools
w3schools.com › java › java_collections.asp
Java Collections Framework
Before we explore ArrayList, HashSet, ... Framework. The Java Collections Framework provides a set of interfaces (like List, Set, and Map) and a set of classes (ArrayList, HashSet, HashMap, etc.) that implement those ...
🌐
Medium
rameshfadatare.medium.com › java-collection-interface-a78ddb3e9e1e
Java Collection Interface. Welcome to the Java Collections… | by Ramesh Fadatare | Medium
September 18, 2024 - The Collection interface is the cornerstone of the Java Collections Framework, providing a unified way to work with groups of objects. It defines several essential methods that all collections must implement, ensuring a consistent API across ...
🌐
Oracle
docs.oracle.com › javase › tutorial › collections › interfaces › index.html
Lesson: Interfaces (The Java™ Tutorials > Collections)
This collections Java tutorial describes interfaces, implementations, and algorithms in the Java Collections framework
Find elsewhere
Top answer
1 of 3
15

Abstractions live longer than implementations

In general the more abstract your design the longer it is likely to remain useful. So, since Collection is more abstract that it's sub-interfaces then an API design based on Collection is more likely to remain useful than one based on List.

However, the overarching principle is to use the most appropriate abstraction. So if your collection must support ordered elements then mandate a List, if there are to be no duplicates then mandate a Set, and so on.

A note on generic interface design

Since you're interested in using the Collection interface with generics you may the following helpful. Effective Java by Joshua Bloch recommends the following approach when designing an interface that will rely on generics: Producers Extend, Consumers Super

This is also known as the PECS rule. Essentially, if generic collections that produce data are passed to your class the signature should look like this:

public void pushAll(Collection<? extends E> producerCollection) {}

Thus the input type can be E or any subclass of E (E is defined as both a super- and sub-class of itself in the Java language).

Conversely, a generic collection that is passed in to consume data should have a signature like this:

public void popAll(Collection<? super E> consumerCollection) {}

The method will correctly deal with any superclass of E. Overall, using this approach will make your interface less surprising to your users because you'll be able to pass in Collection<Number> and Collection<Integer> and have them treated correctly.

2 of 3
7

The Collection interface, and the most permissive form Collection<?>, is great for parameters that you accept. Based on use in the Java library itself it's more common as a parameter type than a return type.

For return types, I think your point is valid: If people are expected to access it, they should know the order (in the Big-O sense) of the operation being performed. I would iterate over a Collection returned and add it to another Collection, but it would seem a bit crazy to call contains on it, not knowing if it's a O(1), O(log n), or O(n) operation. Of course, just because you have a Set doesn't mean it's a hashset or a sorted set, but at some point you will make assumptions that the interface has been reasonably implemented (and then you'll need to go to plan B if your assumption is shown to be incorrect).

As Tom mentions, sometimes you need to return a Collection in order to maintain encapsulation: You don't want implementation details leaking out, even if you could return something more specific. Or, in the case Tom mentioned, you could return the more specific container, but then you'd have to construct it.

🌐
freeCodeCamp
freecodecamp.org › news › java-collections-framework-reference-guide
How to Use the Java Collections Framework – A Guide for Developers
January 28, 2025 - The Collection interface extends the Iterable interface. This means it inherits the properties and behavior of the Iterable interface and adds its own behavior for adding, removing, and retrieving elements.
Top answer
1 of 5
2

1) Yes.

Method parameters should be as general as possible. List<? extends A> is more general than List<A>, and can be used when you don't need to add things to the list. If you were only adding to the list (and not reading from it), the most general signature would probably be List<? super A>

Conversely, method return types should be as specific as possible. You rarely to never want to return a wildcard generic from a method.

Sometimes this can lead to generic signatures:

<T extends MyObject> List<T> filterMyObjects(List<T>)

This signature is both as specific and as general as possible

2) Yes, except possibly in some rare very specific cases (I'm thinking of BitSet, although that isn't technically a Collection).

2 of 5
1

If you declare your list as List<? extends A>, then you can pass in any object which static type is List<X>, where X extends A if A is a class, or X implements A id A is an interface. But you'll not be able to pass in a List or a List<Object> to it (unless A is Object) without force-casting it.

However, if you declare the parameter as a List<A>, you'll only be able to pass lists which static type is strictly equivalent to List<A>, so not List<X> for instance. And by "you are not able to do otherwise", I really mean "unless you force the compiler to shut up and accept it", which I believe one should not do unless dealing with legacy code.

Collections are really collections of references. The abstraction actually is that everything you can put in a variable is a reference to something, unless that variable is of a primitive type.

🌐
University of Washington
courses.cs.washington.edu › courses › cse341 › 98au › java › jdk1.2beta4 › docs › api › java › util › Collection.html
Interface java.util.Collection
The collection hierarchy consists of six interfaces, the core collection intefaces. Three of these interfaces, Set, List, and SortedSet are descendants of the Collection interface; they add further constraints on the contracts imposed by the methods in this interface, as well as adding new methods.
🌐
Medium
medium.com › @storybydhanush › collection-interface-in-java-7df964e867aa
Collection Interface in Java. A Quick Overview | by Thanasekar K | Medium
June 3, 2025 - The Collection interface is a part of the Java Collection Framework, which provides a unified architecture for storing and manipulating collection of objects. Collection interface extends Iterable interface.
🌐
IIT Kanpur
iitk.ac.in › esc101 › 05Aug › tutorial › collections › interfaces › index.html
Interfaces
The Collection interface is the least common denominator that all collections implement, and is used to pass collections around and to manipulate them when maximum generality is desired. Some types of collections allow duplicate elements, and others do not. Some are ordered and others unordered.
🌐
DigitalOcean
digitalocean.com › community › tutorials › collections-in-java-tutorial
Java Collections Tutorial: List, Set, Map & Queue | DigitalOcean
August 3, 2022 - Note that all the core collection interfaces are generic; for example public interface Collection<E>. The <E> syntax is for Generics and when we declare Collection, we should use it to specify the type of Object it can contain. It helps in reducing run-time errors by type-checking the Objects at compile-time. To keep the number of core collection interfaces manageable, the Java platform doesn’t provide separate interfaces for each variant of each collection type.
🌐
GeeksforGeeks
geeksforgeeks.org › java › collection-vs-collections-in-java-with-example
Collection vs Collections in Java with Example - GeeksforGeeks
Collection: Collection is a interface present in java.util package. It is used to represent a group of individual objects as a single unit. It is similar to the container in the C++ language.
Published   July 15, 2025
🌐
Tpoint Tech
tpointtech.com › collections-in-java
Collections in Java - Tpoint Tech
February 12, 2026 - The Java Collections Framework is structured around key interfaces-Collection, List, Set, Queue, and Map. Each tailored for specific data management tasks. Implementations like ArrayList, HashSet, and HashMap offer practical solutions for working with these collections, giving Java developers ...
Top answer
1 of 5
77

The easy way to think of it is: Collections beat object arrays in basically every single way. Consider:

  • A collection can be mutable or immutable. A nonempty array must always be mutable.
  • A collection can allow or disallow null elements. An array must always permit null elements.
  • A collection can be thread-safe; even concurrent. An array is never safe to publish to multiple threads.
  • A list or set's equals, hashCode and toString methods do what users expect; on an array they are a common source of bugs.
  • A collection is type-safe; an array is not. Because arrays "fake" covariance, ArrayStoreException can result at runtime.
  • A collection can hold a non-reifiable type (e.g. List<Class<? extends E>> or List<Optional<T>>). An array will generate a warning for this.
  • A collection can have views (unmodifiable, subList...). No such luck for an array.
  • A collection has a full-fledged API; an array has only set-at-index, get-at-index, length and clone.
  • Type-use annotations like @Nullable are very confusing with arrays. I promise you can't guess what @A String @B [] @C [] means.
  • Because of all the reasons above, third-party utility libraries should not bother adding much additional support for arrays, focusing only on collections, so you also have a network effect.

Object arrays will never be first-class citizens in Java APIs.

A couple of the reasons above are covered -- but in much greater detail -- in Effective Java, Third Edition, Item 28, from page 126.

So, why would you ever use object arrays?

  • You're very tightly optimizing something
  • You have to interact with an API that uses them and you can't fix it
    • so convert to/from a List as close to that API as you can
  • Because varargs (but varargs is overused)
    • so ... same as previous
  • Obviously some collection implementations must be using them
  • I can't think of any other reasons, they suck bad
2 of 5
6

It's basically a question of the desired level of abstraction.

Most collections can be implemented in terms of arrays, but they provide many more methods on top of it for your convenience. Most collection implementations I know of for instance, can grow and shrink according to demand, or perform other "high-level" operations which basic arrays can't.

Suppose for instance that you're loading strings from a file. You don't know how many new-line characters the file contains, thus you don't know what size to use when allocating the array. Therefore an ArrayList is a better choice.

🌐
Coding Shuttle
codingshuttle.com › java-programming-handbook › understanding-collection-interface
Understanding Collection Interface in Java
April 9, 2025 - This blog offers a detailed explanation of the Collection interface in Java, covering its core methods like add, remove, contains, size, and iteration with practical examples. It highlights the role of Collection as the foundation for List, Set, and Queue, helping you understand how to use it effectively in real-world scenarios.
🌐
Java
download.java.net › java › early_access › panama › docs › api › java.base › java › util › doc-files › coll-overview.html
Collections Framework Overview (Java SE 19 & JDK 19 [build 1])
Interfaces that provide essential support for the collection interfaces. Array Utilities. Utility functions for arrays of primitive types and reference objects. Not, strictly speaking, a part of the collections framework, this feature was added to the Java platform at the same time as the collections framework and relies on some of the same infrastructure.