For example, I often see this:
Set<Integer> s = new TreeSet<Integer>();
Set<Integer> s = new HashSet<Integer>();
Map<Integer, String> m = new HashMap<Integer, String>();
over
TreeSet<Integer> ts = new TreeSet<Integer>();
HashSet<Integer> hs = new HashSet<Integer>();
HashMap<Integer, String> hm = new HashMap<Integer, String>();
What are the advantages/disadvanges of the former vs the latter?
For me it comes down to a number of points.
Do you care about the implementation? Does your code need to know that the
Mapis aHashMapor aTreeMap? Or does it just care that it’s got a key/value structure of some kindIt also means that when I’m building my implementation code, if I expose a method that returns Map, I can change the implementation over time without effecting any code that relies on it (hence the reason why it’s a bad idea to try and cast these types of values)
The other is that it becomes easier to move these structures around the code, such that any method that can accept a
Mapis going to be easier to deal with then one that relies on aHashMapfor instanceThe convention (that I follow) is basically to use the lowest functional interface that meets the need of the API. No point using an interface that does not provide the functionality your API needs (for example, if you need a
SortedMap, no point using aMapthen)IMHO