8

Why is Queue an interface, but others like Stack and ArrayList are classes?

I understand that interfaces are made so that clients can implement them and add on their own methods, whereas with classes if every client needs their methods in there it will become huge and bloated..

...or am I missing something here?

jahroy
  • 22,322
  • 9
  • 59
  • 108
Siddhartha
  • 4,296
  • 6
  • 44
  • 65
  • 2
    You've correctly spotted a mild inconsistency. Java is pretty good, overall, but alas out here in The World nothing is exactly right. :-) Veer's answer below mentions that Stack is from an older version, but sometimes everything has to stick around. – david van brink Sep 02 '12 at 18:49
  • It's interesting that if you click on "use" of the `Queue` API docs, you'll see implementations but nothing that actually uses it. In normal usage it's used privately within a class. There would be no significant impact if the interface did not exist. – Tom Hawtin - tackline Sep 02 '12 at 19:55

5 Answers5

7

A Queue can be implemented in a number of fashions, as can a List or a Set. They all merely specify a contract for different kinds of collections.

An ArrayList, however, is a particular implementation of a List, made to internally use an array for storing elements. LinkedList is also an implementation of a List, which uses a series of interconnected nodes, i.e. a doubly linked list. Similarly, TreeSet and HashMap are particular implementations of sets and maps, respectively.

Now, Stack is a odd case here, particularly because it is a legacy class from older versions of Java. You really shouldn't use a Stack anymore; instead, you should use its modern equivalent, the ArrayDeque. ArrayDeque is an implementation of a Deque (a double-ended queue), that internally uses an array for storage (which is just what Stack does). A Deque supports all of the operations of a Stack, like pop, push, etc. Other implementations of Deque include LinkedList, as mentioned by someone else, although this deviates from Stack in that underlying it is not an array, but a doubly-linked list :-p

Now, there are plenty of implementations of Queue, and many different types of Queues. You not only have BlockingQueues (often used for producer-consumer), whose common implementations include LinkedBlockingQueue and ArrayBlockingQueue, but also TransferQueues, and so on. I digress... you can read more on the collections API in the relevant Java Tutorial.

obataku
  • 29,212
  • 3
  • 44
  • 57
  • Thanks for your answer. Apologies for the late thank you note. I remember reading this and it making sense but completely forgot to reply. – Siddhartha Jan 08 '15 at 23:14
3

You get the idea of interfaces correctly. In this case Java standard library already provides both implementations and interfaces. You are better of using an interface so you can switch the implementation any time.

Hope it makes sense.

Drakosha
  • 11,925
  • 4
  • 39
  • 52
0

I think Stack is well-renowned for being a class that should be an interface. The Java libraries are a bit hit-and-miss when it comes to correctly choosing to provide an interface.

ArrayList is just an implementation of the List interface, so Sun got it correct there! Another classic miss (in my opinion) is the Observable class, which very much needs to be the default implementation of an interface, rather than just a class.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
0

Interesting question. My thought about this that Queue is a basis for a lot of data structures like BlockingQueue, PriorityQueue, Deque, etc. This bunch of classes need specific implementation for various operations so it's much simpler to made Queue as interface.

mishadoff
  • 10,719
  • 2
  • 33
  • 55
0

The reason interfaces are used for List and Queue is NOT to reduce excessive code.

The main advantage of interfaces is they allow you to write flexible, loosely coupled code.

(Here's an awesome answer that describes this concept perfectly)

An interface simply defines a list of methods that will be implemented by a class.

This allows us to do a wonderfully powerful thing:

  • We can treat all classes that implement an interface the same.

This is a HUGE advantage.

Here's a very simple example:

We want to write a debug method that prints every element in a Collection.

Collection is an interface. It defines a list of operations and does not implement them.

You cannot instantiate a Collection. You can instantiate a class that implements Collection.

There are many classes that implement Collection: ArrayList, Vector, TreeSet, LinkedList, etc... They all have different snazzy features, but they also have certain things in common: Because each class implements Collection, they all implement each method found here.

This allows us to do a very powerful thing:

  • We can write a method that operates on ANY class that implements Collection.

It would look just like this:

public void printCollection(Collection semeCollection) {
    for (Object o : someCollection) {
       String s = (o == null) ? "null" : o.toString(); 
       System.out.println(s);
    }
}

Because of the magic of interfaces, we can now do the following:

public void testStuff() {

    Collection s = new TreeSet();
    Collection a = new ArrayList();
    Collection v = new Vector();

    s.add("I am a set");
    a.add("I am an array list");
    v.add("I am a vector");

    printCollection(s);
    printCollection(a);
    printCollection(v);
}
Community
  • 1
  • 1
jahroy
  • 22,322
  • 9
  • 59
  • 108