I have a Hashmap HashMap <Integer, Integer> map
and I want to change the keyset()
type to a BinaryTreeNode, which was declared beforehand already, instead of an int, which I am able to do. However, I was wondering how could I add the appropriate map.values()
in the same order as it was in my original HashMap map
Here is my code
public static BinaryTreeNode parentMapToTree(Map<Integer, Integer> map) {
HashMap<BinaryTreeNode, Integer> l = new HashMap<>();
for (int i = 0; i < map.keySet().size(); i ){
BinaryTreeNode node = new BinaryTreeNode(i);
l.put(node, map.values());
}
What changes to my code should I make to ensure that this would compile and do as I want it o?
CodePudding user response:
If you need to maintain insertion order, you would need to create LinkedHashMap. HashMap doesn't gaurantee order.
LinkedHashMap<BinaryTreeNode, Integer> l = new LinkedHashMap<>();
It works like a HashMap but preserves order.
CodePudding user response:
First, some notes on what you have:
public static BinaryTreeNode parentMapToTree(Map<Integer, Integer> map) {
HashMap<BinaryTreeNode, Integer> l = new HashMap<>();
for (int i = 0; i < map.keySet().size(); i ){
BinaryTreeNode node = new BinaryTreeNode(i);
l.put(node, map.values());
}
BinaryTreeNode node = new BinaryTreeNode(i);
Is probably wrong - i
is just the index, which doesn't really mean anything as HashMaps aren't ordered in any defined way.
l.put(node, map.values());
Is also wrong - here the value you're inserting is the entire original map.
You could save your current code by converting the keyset to an indexible structure (like a list - it's currently a set), and then grabbing the key at that index, converting it to a BinaryTreeNode
, looking up the value associated with they key in the old map, and then adding both.
I probably have some syntax errors (I'm not in front of a compiler), but that would look something like:
public static BinaryTreeNode parentMapToTree(Map<Integer, Integer> map) {
List keyList = ArrayList(map.keySet());
HashMap<BinaryTreeNode, Integer> l = new HashMap<>();
for (int i = 0; i < keyList().size(); i ){
Integer key = keyList.get(i);
BinaryTreeNode node = new BinaryTreeNode(key);
l.put(node, map.get(key));
}
But personally I think that's a really bad way to go about it.
What you probably want to do is instead iterate over the entry set:
public static BinaryTreeNode parentMapToTree(Map<Integer, Integer> map) {
HashMap<BinaryTreeNode, Integer> l = new HashMap<>();
for(Map.Entry<Integer, Integer> entry: map.entrySet()){
BinaryTreeNode node = new BinaryTreeNode(entry.getKey());
l.put(node, entry.getValue());
}
This latter method is cleaner because it isn't manually mucking about with indices, which is generally a poor practice. Simpler still is to use a higher-order function, as in:
public static BinaryTreeNode parentMapToTree(Map<Integer, Integer> map) {
HashMap<BinaryTreeNode, Integer> l = new HashMap<>();
map.forEach((key,value) -> l.put(new BinaryTreeNode(key), value));
}
That last one is skipping manual iteration altogether, and just passing the structure a function to run on each of its entries.
You can actually do one better, and skip initializing the new hashmap at all by using a map
function (distinct from a HashMap data structure - totally different meaning.) See Java8: HashMap<X, Y> to HashMap<X, Z> using Stream / Map-Reduce / Collector for more on that.