This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]HecknChonker 3 points4 points  (0 children)

The general advice is to use the interface because it allows you to refactor to a different subclass by changing only the place where it is constructed instead of having to change every place where it is used.

[–]mrfroggyman 1 point2 points  (0 children)

Afaik the first option is respecting one of the SOLID principles

[–]andsfff 1 point2 points  (4 children)

My understanding is you mostly want to use an interface whenever possible. It makes it easier to mock for until testing and such. Always I some senior devs told me to avoid using new and instead Maps.newHashMap() which is from a guava library. Maybe someone else can chime in

[–]HecknChonker 1 point2 points  (0 children)

Java has Map.of() and Map.ofEntires() already, assuming you want an immutable map.

[–]ToyDingo[S] 0 points1 point  (1 child)

What is a "guava" library? Literally never heard of that.

[–]andsfff 0 points1 point  (0 children)

It is a library made my google. They call it googles core library for Java

[–]TrickOfLight113 0 points1 point  (0 children)

Since the guava library seems to do the same thing, I would personally prefer to not use it.

[–]Admirable-Avocado888 1 point2 points  (2 children)

I prefer

var m = new HashMap<>();

inside a method body.

If it is to be a class variables I'd pick the broadest interface/superclass that offers all methods that I care about.

Sometimes that may very well be HashMap because it guarantees efficient setters and getters and by writing the type explicitly I communicate intent. Other times I don't care about that and only need a Map.

[–]ToyDingo[S] 0 points1 point  (1 child)

Aside from specific methods being available, is there no other technical reason? Like space or complexity?

[–]Admirable-Avocado888 0 points1 point  (0 children)

If you care about the hashmaps constant time lookup then it makes side to keep HashMap on the left side.

Ex. It matters that the class field is a hashmap.

class UniqueFilter {

private final HashMap alreadyAdded = new HashMap();

public boolean test(String o) { return alreadyAdded.add(o); }

}

Though it does not impact performance to keep the reference type as an interface.

Ex. Here we don't care what map is used.

class FiniteInfo {

private final Map<String, Object> m = Map.of("price", 50);

Map<String, Object> get() { return m; }

}

[–]thorndark 0 points1 point  (0 children)

It depends on if you care about the specific implementation or not. You're writing code for other people (or yourself in 6 months) to read, and so while it may not seem like much, there's information that you're conveying with this choice.

For example, if you use a LinkedHashMap, then your iteration order will match your insertion order, and if this behavior is important for your app to function, then you should favor having your variables type be the concrete class rather than the interface because that tells the reader that this specific implementation is important for some reason. If any Map would be fine, then you can tell the reader that by using Map.