Reputation: 19283
I am implementing a tree-like structure using the Map
interface like the following declaration:
Map<String, Map<String, Map<Integer, Double>>>
Currently I am using the HashMap
implementation.
After loading a huge amount of data, I am seeing the program consume 4GB of RAM.
On persisting the whole entity using the Serializable
interface, the resulting file's size is just 1GB.
What is the most memory-efficient Map
implementation that I could use here?
Upvotes: 4
Views: 4846
Reputation: 692231
If you want to map a (String,String,Integer) to a Float, then the best thing to do is to use a Map<MyKey, Float>
, where MyKey
would be defined like this:
public final class MyKey {
private final String a;
private final String b;
private final Integer c;
public MyKey(String a, String b, Integer c) {
this.a = a;
this.b = b;
this.c = c;
}
// getters, if needed
@Override
public int hashCode() {
return Objects.hash(a, b, c);
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof MyKey)) {
return false;
}
MyKey other = (MyKey) o;
return Objects.equal(a, o.a)
&& Objects.equal(b, o.b)
&& Objects.equal(c, o.c);
}
}
Upvotes: 4
Reputation: 18562
You have two kinds of maps here. One which has String keys and Map values. For that I'd probably use Google Guava's ImmutableMap if immutability is ok for you. It will probably not save you a lot of memory, but it might save you some, and perform a bit better than a normal HashMap.
For the other Map with Integer keys and Double values, you should use a specialized Map implementation which stores primitives instead of objects. Take for instance a look at Trove4j's TIntDoubleHashMap. This will save you a lot of memory, as the primitives are stored as primitives instead of Objects.
Upvotes: 3