• Post Reply Bookmark Topic Watch Topic
  • New Topic

advantage to using List/Map/Set variable for ArrayList/HashMap/HashSet objects  RSS feed

 
Ted Schrey
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I heard that it is often advantageous to create your object variables for such things as HashMaps, ArrayLists and HashSets using the parent class type for the variable.
ex: instead of

HashMap<String, Integer> map = new HashMap<String, Integer>();, the following is used
Map<String, Integer> map = new HashMap<String, Integer>();

What would be the advantage?
 
Carey Brown
Saloon Keeper
Posts: 3328
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you assign it to a type of 'Map' then you are not dependent on the specific implementation of the Map interface. This allows you to substitute a different type of Map at a later date if you wish without breaking anything.


All Known Implementing Classes of the Map interface:
AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, nderingHints, SimpleBindings, TabularDataSupport, TreeMap, UIDefaults, WeakHashMap
 
Campbell Ritchie
Marshal
Posts: 56578
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And what about the methods which return a Map? For example, Stream.collect(Collectors.groupingBy(...))
Their return type turns out to be Map<X, Y> so you cannot apply them to a particular implementation.
 
Gordon Brown
Ranch Hand
Posts: 58
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The principle at work here is coding to an interface rather than an implementation. As Carey explained, the advantage is that you decouple the specific implementation from the interface (API), giving you greater flexibility.

Let's say you have a method that accepts objects of type List and performs some processing on those objects. It doesn't matter whether the actual object type of the processed lists is e.g. LinkedList, or ArrayList; you can process either, using identical code, because you are coding against the interface of their common supertype (List). Naturally, LinkedList and ArrayList implement their add methods very differently, but since you are coding against the interface, you simply call the add method that's defined on the List type. At runtime, if you pass in an object of type LinkedList, then LinkedList's add method will be called via a process called dynamic dispatch.

This is the essence of polymorphism: encapsulating different implementations behind the same interface, and choosing between them dynamically at runtime (based on actual object type). Note that, had you not used the supertype as a reference type, your code would have had to perform type-checking on the object in order to be able to process different implementations.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!