Domanda

To implement a Queue, why do we use?

Queue<Integer> q = new LinkedList<Integer>();

I mean a Superclass reference, why don't we use a LinkedList reference?

È stato utile?

Soluzione

Avoid unnecessary restrictions

You should always try to declare your variables with the least unnecessary restriction; often that means to an interface like Queue or Collection. This allows you to more easily change your implementation. I will use two classes from the collections framework as my example but the principle is general.

Imagine the following objective:

I need 2 collections that can have objects added to it. And I also need to be able to find which objects are in both collections. So in other words I need the following methods

Collection#add
Collection#retainAll

These are both within Collection so any collection will do. Collection is an interface so I need to choose a concrete implementation. I choose ArrayList, on a whim. My code is the following:

public static void main(String[] args){
    Collection<Integer> a=new ArrayList<>();
    Collection<Integer> b=new ArrayList<>();
    
    initialise(a);
    initialise(b);
    testRetain(a,b);
}

public static void initialise(Collection<Integer> collection){
    Random rnd=new Random();
    
    
    for(int i=0;i<1000;i++){
        collection.add(rnd.nextInt());
    }
}

public static void testRetain(Collection<Integer> collection1, Collection<Integer> collection2){
    collection1.removeAll(collection2);
}

This code works fine and does exactly what I asked it to do. However; in profiling I find that it is a bottleneck. So I test out different implentations of the Collection class and profile the results.

enter image description here

As you can see, for the retainAll operation the HashSet turned out to be much better. So I can change my implementation by changing just new ArrayList<>(); to new HashSet<>(); in one place. No need to change every other method I've used to HashSet as well because they don't care, as long as they get some sort of Collection they are happy

public static void main(String[] args){
    Collection<Integer> a=new HashSet<>();
    Collection<Integer> b=new HashSet<>();

    initialise(a); //<--no need to alter this method
    initialise(b);
    testRetain(a,b); //<--no need to alter this method
}

Well that was easy. Now imagine a much larger application with dozens of methods; all of which could be hardcoded to use ArrayList even though they didn't need to, all of which you would now need to manually alter.

Altri suggerimenti

We have a design principle called Code to interfaces never with concrete implementations

Here Queue is an Interface which can hold implementation class

Advantages over above principle

1.Switching between multiple implementations become easy in future

 So it is always recommonded to code to interface instead of concrete implementations

2.If we won't use above principle we loose key Object oriented concept polymorphism.

To implement a Queue,why do we use?

No one can really assert that this is the patter that everyone must follow. You can very well use

LinkedListq=new LinkedList();

Reason above patter is used frequently because it offers the power of polymorphism. To explain it in short you now need a LinkedList but later you may need PriorityQueue. To use same reference for multiple concrete classes we use above pattern.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top