I was wondering why when does the constructor of a LinkedHashMap that the client code can specify if is access ordered expect a loadFactor
?
Is there any particular reason for this design instead of using a default factor?
Asked
Active
Viewed 155 times
0
-
1They maybe decided that adding yet another constructor (for the combinatorial explosion of all the possible ways to construct an instance) just didn't carry its weight. – Andy Turner Jul 05 '17 at 07:46
-
If you look at the [list of constructors](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html#constructor.summary), you'll notice that it starts with a `()` no-arg version and has a full version with `(int initialCapacity, float loadFactor, boolean accessOrder)`, and two convenience versions leading there. To have constructors for all combinations of those 3 arguments, there should be 4 more constructors, and they decided not to do that, probably because it would lead to confusion of which constructor would be called if all 8 combinations existed. – Andreas Jul 05 '17 at 08:04
-
@Andreas:That class is meant to be used as an LRU. And in order for that to work we need to be able to specify the eviction policy (insert vs access order). Taking into account that the default is insert without any config for load factor I find it very weird that they opted for specifiying something so important to the hashtable performance when we specify the order? How does this change based on the eviction policy? – Jim Jul 05 '17 at 08:15
-
@Jim You might as well ask, how does eviction policy change based of load factor? Why is eviction policy more or less important than load factor? If you look at constructors of [`HashMap`](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html#constructor.summary) and [`LinkedHashMap`](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html#constructor.summary), and the fact that `LinkedHashMap` is a subclass (extension) of `HashMap`, they likely decided to simply clone the constructors and then add one more for controlling the extra feature added by `LinkedHashMap`. – Andreas Jul 05 '17 at 10:17
-
@Andreas: Valid points and I would also add that a LinkedHashMap according to the javadoc is meant to be used as an LRU. An LRU I would say is a higher abstraction than a hashtable. So I originally thought it would make more sense to have constructors specific for LRU configuration. In any case I was trying to understand if there was a specific reason e.g. to be cautious of something concerning the load factor if used in access order mode – Jim Jul 05 '17 at 18:54
-
1@Jim `LinkedHashMap` is not *meant to be* used as LRU. It *can be*. [Javadoc](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html) says: *"A **special constructor** is provided to create a linked hash map whose order of iteration is the order in which its entries were last accessed, from least-recently accessed to most-recently (access-order). This kind of map is well-suited to building LRU caches."* The phasing makes it clear that it *can be* used as LRU, but that it is considered a **special** case, not the norm. – Andreas Jul 05 '17 at 20:43
-
I, personally, have used `LinkedHashMap` many times, but never as an LRU. – Andreas Jul 05 '17 at 20:45
1 Answers
0
Sometimes things "just happen". Beyond that:
When designing a library API, you have to balance simplicity and "feature count". Meaning: of course you could create a huge number of constructors, allowing to set all flags as you want them. But that would lead to a high number of constructors. And that is typically not what you want.
In that sense: if you are really willing to touch the insertion order flag for linked hash maps ... then you are already taking a "very special route". And then the creators of the API (probably) decided to give you one special constructor, instead of a higher number.

GhostCat
- 137,827
- 25
- 176
- 248
-
What you say is all sensible but they do state in the doc that the intented usage is an LRU. And an LRU is a higher level abstraction than a hash table. So I think having constructors specifically for LRU and leaving sensible defaults would make sense. Anyway I was wondering if I was missing something – Jim Jul 05 '17 at 18:52