I am supposed to created a HashMap
inside another HashMap
as shown below which can store the value inside the inner HashMap
based on the key of the outer HashMap
at the runtime
i.e. required output for program should be of the format
{ 1 = {11 = "aaa",15 = "bbb"}, 2 = {13 = "ccc", 14 = "ddd"} }
where 1,2 are Key values for Outer HashMap.
Below is the Code provided for it Is there any better approach to improve performance
HashMap<Integer, HashMap<Integer, String>>Outer
= new HashMap<Integer, HashMap<Integer,String>>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int count = Integer.parseInt(br.readLine());
for(int i =0;i<count;i++)
{
String input[] = br.readLine().split("\\s");
//HashMap<Integer,String>inner = new HashMap<Integer, String>();
int key = Integer.parseInt(input[0]);
if(Outer.isEmpty() || !Outer.containsKey(key))
{
HashMap<Integer, String> inner = new HashMap<Integer, String>();
inner.put(Integer.parseInt(input[1]),input[2]);
Outer.put(key, inner);
}
else if(Outer.containsKey(key))
{
HashMap<Integer, String> inner = (HashMap<Integer, String>) Outer.get(key).clone();
inner.put(Integer.parseInt(input[1]), input[2]);
Outer.put(key, inner);
}
}
@Vangel Yes that could help. But likely the default hashCode and equals were sufficient. Be careful if you can't make it immutable and make sure you never modify any key objects after you insert them in the map.
Use wrappers for composite HashMap keys Whenever a HashMap has composite String keys, use a wrapper instead of concatenating the strings to make a key. Doing so will make the lookup much faster and reduce allocation rate, as the benchmark below demonstrates.
An instance of HashMap has two parameters that affect its performance: initial capacity and load factor. The capacity is the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created.
Similar to Vadim's answer, but further improved - as it doesn't require a call to both containsKey
as well as get
:
Map<Integer, Map<Integer, String>> outer = new HashMap<Integer, Map<Integer, String>>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int count = Integer.parseInt(br.readLine());
Pattern splitter = Pattern.compile("\\s");
for(int i = 0; i < count; i++){
String input[] = splitter.split(br.readLine());
int key = Integer.parseInt(input[0]);
Map<Integer, String> inner = outer.get(key);
if(inner == null){
inner = new HashMap<Integer, String>();
outer.put(key, inner);
}
inner.put(Integer.parseInt(input[1]), input[2]);
}
It also has some minor improvements for naming conventions, and use of the Collections interfaces instead of concrete types.
I also removed the call to clone
. This could be a slight savings - and I don't think it would have given you your expected results.
Finally - one other thing that I changed that could be a slight improvement is using a pre-compiled Pattern for the splitting of your String into fields.
Optimizing is nearly always a bad idea. Especially in Java where the JVM is quite good at doing that by itself.
Do you really need a Map<Integer, Map<Integer, String>>
, it seems to me that you really just need a Map<Pair, String>
where
public final class Pair {
private final int x;
private final int y;
public Pair(int x, int y) { this.x = x; this.y = y;}
}
I am not claiming at all that this will improve performance, but it might be better design. I don't quite know what you are doing, so maybe it's not better design.
Your code is good enough from performance point of view. Only few things came to my mind. If/else condition can be simplified and you don't need to clone map in else part (work with pointer)
HashMap<Integer, HashMap<Integer, String>>Outer = new HashMap<Integer, HashMap<Integer,String>>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int count = Integer.parseInt(br.readLine());
for(int i =0;i<count;i++)
{
String input[] = br.readLine().split("\\s");
//HashMap<Integer,String>inner = new HashMap<Integer, String>();
int key = Integer.parseInt(input[0]);
if(!Outer.containsKey(key))
{
HashMap<Integer, String> inner = new HashMap<Integer, String>();
inner.put(Integer.parseInt(input[1]),input[2]);
Outer.put(key, inner);
}
else
{
HashMap<Integer, String> inner = Outer.get(key);
inner.put(Integer.parseInt(input[1]), input[2]);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With