1

I have a method where I build a LinkedHashMap so I can preserve order. Here is my method:

public class MyClass {

    public Map<String,MyObj> buildMap() {
        Map<String,MyObj> myMap = new LinkedHashMap<>();
        //perform logic and add objects to myMap
        ...
        return myMap;
    }
}

When I'm calling my buildMap() function from another class, would I get a map that is in order still? Like:

MyClass myClass = new MyClass();
Map<String, MyObj> returnedMap = myClass.buildMap();

would my returnedMap still be a LinkedHashMap?

Or would I have to change my buildMap function to always return a LinkedHashMap?

Roman C
  • 49,761
  • 33
  • 66
  • 176
DanielD
  • 1,315
  • 4
  • 17
  • 25
  • You're returning the instance of `myMap`. This does not change until there is something like `myMap = new ...`. So yes, the calling class will get a `LinkedHashMap` – Stefan Warminski May 22 '17 at 11:00
  • the reason I'm asking is I would want to keep my buildMap() function generic and I know it is usually recommended to program against the interface (Map) rather than an implementation of that interface (LinkedHashMap). – DanielD May 22 '17 at 11:00

2 Answers2

3

It doesn't matter what type or interface is returned. The object instance type does matter however. If it is a LinkedHashMap then it will preserve the implementation, so the order in your case.

This implementation spares its clients from the unspecified, generally chaotic ordering provided by HashMap (and Hashtable), without incurring the increased cost associated with TreeMap. It can be used to produce a copy of a map that has the same order as the original, regardless of the original map's implementation:

 void foo(Map m) {
     Map copy = new LinkedHashMap(m);
     ...
 }
Roman C
  • 49,761
  • 33
  • 66
  • 176
  • so even though my returnedMap is just a generic map, it would still preserve order? If I add and remove elements from the returnedMap after it would still act as a LinkedHashMap? – DanielD May 22 '17 at 11:03
  • if you return `LinkedHashMap` then it will act like `LinkedHashMap` otherwise not. – Roman C May 22 '17 at 11:08
3

The other answer is correct - it doesn't matter what return type you use within your source code in order to express your thinking.

At runtime, the only thing that matters about the nature of an object is its concrete, specific class.

But the one aspect to consider: if "keeping insertion order" is a core element of the API you are providing to the user, you might change the signature of your method to:

public LinkedHashMap<String,MyObj> buildMap() {

to simply make it clear to all future users of this method what the method is doing.

You see, LinkedHashMap and HashMap have slightly different performance characteristics. Depending on your context, it could be important for future callers to understand that the method will in fact return this special Map implementation.

But in mos situations, that difference doesn't matter, and then it is "good practice" to return the more abstract interface type instead of the specific implementation class. See here for some further reading why to prefer interface types in general.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • It was not me but I argument to coding to interfaces rather than classes. – Roman C May 22 '17 at 11:16
  • Writing code is always about expressing intentions. When the intention is: "here linked hash map" then it might be better to make that explicit. – GhostCat May 22 '17 at 11:26
  • The code works exactly as it's written, and user prefer working with interfaces rather than classes implementing those interfaces. – Roman C May 22 '17 at 11:31
  • Why the absolute? I **prefer** understanding the *intention* of the code I am working with. As long as the reasons are valid, it is perfectly fine to *violate* rules at certain points. If programming would only following rules, computers could do it. – GhostCat May 22 '17 at 11:39
  • The intention of the code is its specification, that points to interfaces. If you need details about implementation that might be different then you should read javadoc or look at the source code. – Roman C May 22 '17 at 11:43
  • 1
    The **best** choice to express design decisions is by using **code**. Telling somebody "read the source / javadoc" means that you *failed* to express something essential within code. Most often that is because Java code isn't expressive enough. But again: in certain situations it can be important that everybody understands "we are using a XYMap" and not use just "any Map" implementation. That is all I am saying. And that is based on my **own** experience. There is no point in you declaring: in 100% of all cases you use the interface. Because I have seen.. – GhostCat May 22 '17 at 11:53
  • enough situations were deviating from that rule **helped**. – GhostCat May 22 '17 at 11:54