Combining remove and put method in LinkedHashMap

#1

I’ve observed that if we update a key in LinkedHashMap, then the order of the keys does not get changed

e.g.

m is LinkedHashMap
m.put(1,1)
m.put(2,2)
m.put(3,3)
m.put(2,4)

Will be {1=1,2=4,3=3}

For the order to be changed, I have to manually always remove the key and then put it back. Considering LinkedHashMap is about keeping the order, wouldn’t it be good to have a method that does both of these steps?

#2

I guess both behaviors can make sense, depending on the application. Implementation-wise, the current put is the more atomic operation, since reinserting requires extra work.

I know this behavior was chosen intentionally by the Java counterpart to LinkedHashMap (https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html), which is at least better documented:

This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map. (A key k is reinserted into a map m if m.put(k, v) is invoked when m.containsKey(k) would return true immediately prior to the invocation.)

But yes, a utility method could probably be added—not before 2.13 though, because of compatibility policies. Or you can add it yourself via an “extension method” now.

#3

I think I may go with an extension method now.

But now when I think about it, usually it’s preferred that we code using interfaces (i.e. don’t use LinkedHashMap m = new LinkedHashMap but rather Map m = new LinkedHashMap) Surely having a method of this sort in the interface doesnt make sense because this is only specific to LinkedHashMap.

Or I think its reasonable that I dont work through interfaces as this is really use case specific.

Also is it possible in scala to have an implicit class that takes an interface but only if the underlying instance is of specific type. I know its a horrible idea to have a feature like that which is prone to a runtime error

#4

The preference for using interfaces is mostly a Java thing. It has big downsides–such as not being able to predict performance or sometimes even behavior–and as such there’s a reasonable argument to use leaf types and just deal with the refactor if you need it. (It’s a little more complicated when building libraries because generality in input arguments is an advantage, as is maintaining specificity in output types.)

#5

“sometimes even behavior” - I always wondered if this was an issue and yes it is !!

“because generality in input arguments is an advantage, as is maintaining specificity in output types” - any instances where not adhering to this caused an issue ? I’m getting myself into framework development, so wanted to understand the pain points