• Post Reply Bookmark Topic Watch Topic
  • New Topic

Dynamic Dispatch  RSS feed

 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I would like to understand when I would use the following line of code:

Queue q = new LinkedList();

I know how dynamic dispatch works in Java, but I am just not able to think of a situation where the above line will be useful. Maybe in some method that expects a queue?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The LHS says, "I need a Queue. I want something that gives me the behavior that Queue provides, because I am going to use those features. I will call my variable that points to that Queue, 'q'".

The RHS says, "I am creating a LinkedList object and giving you a reference to it."

It's legal to use a LinkedList where Queue is expected because a LinkedList IS-A Queue.

If I read that code, the fact that the LHS says Queue instead of LinkedList tells me that the person who wrote it doesn't particularly what which implementation of a Queue he gets. He doesn't need anything LinkedList-specific. He just needs a Queue. He ends up using a LinkedList because we have to use some concrete class, and apparently that one was the most convenient, or the best fit in some way, or simply an arbitrary default.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Jeff. I am not able to understand or imagine a situation where it would be useful to me. Why can't I just say LinkedList l = new LinkedList() and use whatever methods I need to use because LinkedList class implements all the methods/functionalities that a Queue has.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prasanna Raman wrote:Thank you, Jeff. I am not able to understand or imagine a situation where it would be useful to me. Why can't I just say LinkedList l = new LinkedList()


You can.

But it's about making your design as clear as possible. By declaring the variable as a Queue, you're telling whoever may read the code later (including you--believe me, it won't take long before you look back at old code you wrote and wonder why you did something a certain way), "I want the features of a Queue, such as FIFO behavior. I don't need anything else. I don't need it to be implemented as a LinkedList. I don't need constant-time inserts and removes at the current iteration point, etc."

A LinkedList and a Queue are conceptually two completely separate, independent concepts. It just so happens that Java's LinkedList class is also a passable implementation of a Queue, so you can use a LL either as a LL or as a Queue.

I could write a class that implements Queue and is backed by an array rather than a linked list. If you just need a Queue, you could use my class or LinkedList or java.util.concurrent.ArrayBlockingQueue (also backed by an array, not a linked list) and your code would still work with no other chagnes besides the new WhateverQueue(...) part.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, OK! So, I could use it just for readability purposes?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prasanna Raman wrote:Oh, OK! So, I could use it just for readability purposes?


Sort of, yes. When talking about strictly local variables, clear communication of design is the main benefit. Another major benefit is hiding of implementation details and the flexibility that brings. That doesn't come into play as much for strictly local variables, but it does in other cases.



If I'm implementing that method, say as the way for some work distribution framework to provide a queue of tasks to be performed, the caller of that method only cares about getting a Queue. He doesn't need to know or care what kind. So I'm free to give back whatever kind of queue is appropriate at the moment. It may be that in a later version of this method, I find that one particular kind of queue works better in general than what I've been returning. So I change to return that kind. The user of this method gets the new version of my class, and he never even knows the difference, and doesn't have to change any of his code.

 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, OK! Thank you, Jeff.

I got this question because I was actually writing an LRU implementation and I needed a queue like data structure to store the items. I initially thought I'd use a Priority Queue and declared

Queue q = new PriorityQueue();

but then I figured I couldn't use PriorityQueue for some reason and switched to Linked list instead. But I thought it just made sense to keep the L.H.S. the same and change the R.H.S. only because it just made more sense given the functionality I was trying to implement. So, I left it as

Queue q = new LinkedList();

First, is my thinking correct? Then, are there any performance issues here as opposed to using a linked list variable in the L.H.S.?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prasanna Raman wrote:I initially thought I'd use a Priority Queue and declared

Queue q = new PriorityQueue();

but then I figured I couldn't use PriorityQueue for some reason and switched to Linked list instead. But I thought it just made sense to keep the L.H.S. the same and change the R.H.S. only because it just made more sense given the functionality I was trying to implement. So, I left it as

Queue q = new LinkedList();


Yep, that's exact the kind of flexibility and localizing change I was talking about.

Like I said, it's not usually as big a deal for just local variables, because if your methods are fairly short, as they should be, there just won't be that many things to change if you change the type of a local. It's still good practice though, and even for locals it can make life a little bit simpler when you do need to change something.

Then, are there any performance issues here as opposed to using a linked list variable in the L.H.S.?


No, the type of the variable will not affect performance. Your choice of implementation on the RHS might, but your choice of variable type on the LHS won't.
 
Prasanna Raman
Ranch Hand
Posts: 410
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Jeff.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prasanna Raman wrote:I got this question because I was actually writing an LRU implementation and I needed a queue like data structure to store the items.

It might be worth mentioning that Java already has a structure that works very well for LRU queues: LinkedHashMap. Its only restriction is that you can't add duplicate items without some extra jiggery-pokery. So unless this is just an exercise, I'd have a look at it, and specifically, its removeEldestEntry() method. There is also some explanation in the class documentation itself.

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!