HashMap as Value in HashMap [duplicate] - java

This question already has answers here:
Java - Initialize a HashMap of HashMaps
(4 answers)
Closed 4 years ago.
How can I create a "multidimensional" HashMap with HashMaps as Value without initializing every HashMap like you see below?
HashMap<Integer, String> DenmarkBasic = new HashMap<Integer, String>();
DenmarkBasic.put(1, "http://website1.com/");
DenmarkBasic.put(2, "http://website2.com/");
HashMap<Integer, String> DenmarkMisc = new HashMap<Integer, String>();
DenmarkMisc.put(1, "http://website1.com/");
DenmarkMisc.put(2, "http://website2.com/");
HashMap<String, HashMap<Integer, String>> DenmarkPanel = new HashMap<String, HashMap<Integer, String>>();
DenmarkPanel.put("Basic", DenmarkBasic);
DenmarkPanel.put("Misc", DenmarkMisc);
HashMap<String, HashMap<String, HashMap<Integer, String>>> NordicCountry = new HashMap<String, HashMap<String, HashMap<Integer, String>>>();
NordicCountry.put("Denmark", DenmarkPanel);
NordicCountry.put("Sweden", SwedenPanel);
HashMap<String, HashMap<String, HashMap<String, HashMap<Integer, String>>>> Market = new HashMap<String, HashMap<String, HashMap<String, HashMap<Integer, String>>>>();
Market.put("Nordic", NordicCountry);
I just want to use a loop, because it would be too much Maps.

Don't do that!
Nesting hash maps makes your code very very complicated very very quickly. Just look at how long your type names are getting.
You should write the data in another format, like JSON, and then parse it.
Your JSON would look something like this:
{
"Market" : {
"Nordic": {
"Denmark": {
"Basic": ["website1.com", "website2.com"],
"Misc": ["website1.com", "website2.com"]
},
"Sweden": {
"Basic": ["website1.com", "website2.com"],
"Misc": ["website1.com", "website2.com"]
},
}
}
}
And then you use a JSON parser to parse it. For example, as shown in this answer, you can use org.json. To get the list of basic Denmark websites:
jsonObject
.getJSONObject("Market")
.getJSONObject("Nordic")
.getJSONObject("Denmark")
.getJSONArray("Basic")
There are also other libraries mentioned in that post. Find the one you like the most and use it!

It's generally a bad practice to create such nested structures (like map contains a map, or list containing maps, etc.), so Guava comes with new collections, you can find there things like multimap, multiset which will help you write better, safer and future-proof code. Try it out, such structures are availalbe in Guava and Apache Collections
https://github.com/google/guava/wiki/NewCollectionTypesExplained#multimap

Related

Convert ArrayList to HashMap<String, String>

I have this ArrayList
public ArrayList<HashMap<String, String>> xmlFileNames = new ArrayList<>();
and I want to convert this to:
HashMap<String, String> comparemap2 = new HashMap<>();
What I want is: I want all the Items inside the ArrayList and want to put them into the HashMap
My HashMap looks like:
KEY VALUE
job_id 032014091029309130921.xml
job_id 201302149014021492929.xml
job_id 203921904901920952099.xml
EDIT:
Later I want to compare this map with an existing map:
Properties properties = new Properties();
try {
properties.load(openFileInput("comparexml.kx_todo"));
} catch (IOException e) {
e.printStackTrace();
}
for (String key : properties.stringPropertyNames()) {
compareMap.put(key, properties.get(key).toString());
}
HashMap<String, String> oldCompareMap = new HashMap<>();
for (HashMap key : xmlFileNames) {
oldCompareMap.putAll(key);
}
isEqualMaps(oldCompareMap, compareMap);
I only want to compare, if the filename exists in the compareMap. If not, than add it to the xmlFileName Map
I've looked up in StackOverFlow, how I can convert ArrayList to HashMap. But the other Threads treat data types like Item or Product.
I hope you can help me!
Kind Regards
Given...
public ArrayList<HashMap<String, String>> xmlFileNames = new ArrayList<>();
then something like this should do it.
HashMap<String, String> nhm = new HashMap<>();
for (HashMap xmlFileHm : xmlFileNames ) {
nhm.putAll(xmlFileHm);
}
but be aware if you have duplicate keys in your hashmaps they will get overwritten.
You should also think about coding to interfaces. Take a look at Map and List rather than typing your collections to implementations (ArrayList and HashMap). Take a look at this thread which is quite interesting What does it mean to "program to an interface"?
Depending on what you are trying to do as well you might consider a MultiMap as this might server your purposes better
Edit After update to the question...
A multimap would be better here with one key and multiple values. Although arguably if the key never changes then you could just store the values in a list. For multiamps you can use Google's guava library or do one yourself. For example (not checked for compilation errors as Im doing this from my head)
Map<String, List<String>> m = new HashMap<>();
if (m.containsKey("key")) {
m.get("key").add("new value");
}
else {
List<String> l = new ArrayList<>();
l.add("new value");
m.put("key", l);
}
You can create a new HashMap, then iterate through the list and put all elements from the map from the list to the main map.
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> map = new HashMap<>();
for (Map<String, String> mapFromList : list) {
map.putAll(mapFromList);
}
You can try something like this..
ArrayList<HashMap<String, String>> xmlFileNames = new ArrayList<>();
HashMap<String, String> comparemap2 = new HashMap<>();
for(HashMap<String, String> i:xmlFileNames){
comparemap2.putAll(i);
}
You may need to consider the case of duplicate keys. else they will get override.
Create a new map and put All each element of arrayList to the map.
But in that case if you have same keys in two element of arrayList (hashmap) then it will override the previous one.

Java putting Hashmap into Treemap

I am currently reading 2 million lines from a textfile as asked in the previous question
Java Fastest way to read through text file with 2 million lines
Now I store these information into HashMap and I want to sort it via TreeMap because I want to use ceilingkey. Is the following method correct?
private HashMap<Integer, String> hMap = new HashMap();
private TreeMap<Integer, String> tMap = new TreeMap<Integer, String>(hMap);
HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
treeMap.putAll(hashMap);
Should work anyway.
This would work just fine:
HashMap<Integer, String> hashMap = new HashMap<>();
TreeMap<Integer, String> treeMap = new TreeMap<>(hashMap);
But I wouldn't advise using HashMap to store the input. You end up with two Maps holding the same huge data. Either do it on the fly and add directly into TreeMap or use List to TreeMap conversion.
Also, for even more efficiency consider primitive collections.
HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
hashMap.remove(null);
treeMap.putAll(hashMap);
HashMap will allow null but TreeMap not so before adding into Treemap, remove null from keyset

How merge list when combine two hashMap objects in Java [duplicate]

This question already has answers here:
How can I combine two HashMap objects containing the same types?
(17 answers)
Closed 9 years ago.
I have two HashMaps defined like so:
HashMap<String, List<Incident>> map1 = new HashMap<String, List<Incident>>();
HashMap<String, List<Incident>> map2 = new HashMap<String, List<Incident>>();
Also, I have a 3rd HashMap Object:
HashMap<String, List<Incident>> map3;
and the merge list when combine both.
In short, you can't. map3 doesn't have the correct types to merge map1 and map2 into it.
However if it was also a HashMap<String, List<Incident>>. You could use the putAll method.
map3 = new HashMap<String, List<Incident>>();
map3.putAll(map1);
map3.putAll(map2);
If you wanted to merge the lists inside the HashMap. You could instead do this.
map3 = new HashMap<String, List<Incident>>();
map3.putAll(map1);
for(String key : map2.keySet()) {
List<Incident> list2 = map2.get(key);
List<Incident> list3 = map3.get(key);
if(list3 != null) {
list3.addAll(list2);
} else {
map3.put(key,list2);
}
}
create third map and use putAll() method to add data from ma
HashMap<String, Integer> map1 = new HashMap<String, Integer>();
HashMap<String, Integer> map2 = new HashMap<String, Integer>();
HashMap<String, Integer> map3 = new HashMap<String, Integer>();
map3.putAll(map1);
map3.putAll(map2);
You have different type in question for map3 if that is not by mistake then you need to iterate through both map using EntrySet
Use commons collections:
Map<String, List<Incident>> combined = CollectionUtils.union(map1, map2);
If you want an Integer map, I suppose you could apply the .hashCode method to all values in your Map.
HashMap has a putAll method.
Refer this :
http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html

Recursively Create Hasmaps in Java

I'm trying to create a new HashMap for each document I have as input. In pseudeocode I can think of something like:
For(eachInputDoc)
{
Map<String, String> mapInputNumber = new HashMap<String, String>;
}
So that for 4 documents you would have:
mapInput1
mapInput2
mapInput3
mapInput4
How can I accomplish this?
It looks like you're trying to declare variables dynamically. You can't do that in Java - the variables themselves are determined at compile time. However, you could create a list:
List<Map<String, String>> maps = new ArrayList<Map<String, String>>();
for (Document doc : docs)
{
Map<String, String> map = new HashMap<String, String>();
// Populate map from doc
maps.add(map);
}
I suggest you make an ArrayList of HashMaps.
You cannot dynamically generate names like mapInput1, mapInput2, etc in Java. You need to think of array or List. Also your problem is not recursive.
I'd do something like this:
Map<MyDocClass, Map<String, String>> myDocData = new HashMapMap<MyDocClass, Map<String, String>>();
for(MyDocClass doc : myDocs) {
Map<String, String> data = new HashMap<String, String>();
// populate the data
myDocData.put(doc, data);
}
Then you can easily access the data for each doc by doing
Map<String, String> data = myDocData.get(doc);
If you know/want to reference the name of the document, you could even use a HashMap of HashMaps.
I would have another map to hold the mapInputs something like this:
Map<Integer,Map<String,String>> context = new HashMap<Integer,Map<String,String>>();
for each(inputDoc)
{
Map<String, String> mapInput = new HashMap<String, String>();
context.put(index,mapInput);
}
U have the aproach of having a List(array,linked) instead of MAP, but this depends of how you`re gonna access that inputMaps! I would say that using a ArrayList is a good one too!
You need to put your hash maps into another (dynamic) container like ArrayList or other HashMap.

replace values in a String from a Hashtable in Java

My string looks like;
String values = "I am from UK, and you are from FR";
and my hashtable;
Hashtable countries = new Hashtable();
countries.put("United Kingdom", new String("UK"));
countries.put("France", new String("FR"));
What would be the most effective way to change the values in my string with the values from the hashtable accordingly. These are just 2 values to change, but in my case I will have 100+
I'm not sure there's a whole lot you can do to optimize this in a way which is worthwhile. Actually you can construct an FSM for custom replacements like that but it's probably more than you want to really do.
Map<String, String> countries = new HashMap<String, String>();
countries.put("United Kingdom", "UK");
countries.put("France", "FR");
for (Map.Entry<String, String> entry : countries.entrySet()) {
values.replace(entry.getKey(), entry.getValue());
}
A couple of notes:
Don't use Hashtable. Use a Map (interface) and HashMap (class) instead;
Declare your variable, parameter and return types, where applicable, as interfaces not concrete classes;
Assuming you're using Java 5, use generic type arguments for more readable code. In this case, Map<String, String>, etc; and
Don't use new String("UK"). There is no need.
Several thoughts. First of all: why use hashtable? hashmap is usually faster as hashtable is synchronized.
Then: why not use generics?
HashMap<String, String>
is much more expressive than just HashMap
Third: don't use new String("UK"), "UK" will do fine, you're creating the same string twice.
But to solve your problem, you probably want to turn the map around:
Map<String,String> countries = new HashMap<String, String>();
countries.put("UK", "United Kingdom");
countries.put("FR", "France");
Now if I understand you right you want to do something like this:
String values = "I am from UK, and you are from FR";
for(Map.Entry<String, String> entry : countries.entrySet()){
values = values.replace(entry.getKey(), entry.getValue());
}

Categories

Resources