This question seems to be very popular and yet I couldn't get correct results for my implementation. I had this thread as an example but so far no luck.
Here I have HashMap that I need to convert to TreeMap in order to have key values sorted:
HasMap<String, HashMap<String, SomeBean>> hashMap = (HashMap<String, HashMap<String, SomeBean>>)request.getAttribute("HASHMAP");
After applying iterator I could see results in unsorted order.
Now I want to convert it to TreeMap:
TreeMap<String, TreeMap<String, SomeBean>> treeMap = new TreeMap<String, TreeMap<String, SomeBean>>(hashMap);
Result:
The constructor TreeMap<String,TreeMap<String,SomeBean>>(HashMap<String,HashMap<String,SomeBean>>) is undefined
Well, it seems because i have nested map with my bean class it is not allowing me to create new tree map. It is understandable as I don't expect TreeMap to have constructor that suits my criteria but the question is how do I find workaround for this problem?
Since your maps have incompatible value types, you'll need to convert them manually:
Map<String, Map<String, SomeBean>> treeMap = new TreeMap<>();
for (Map.Entry<String, HashMap<String, Integer>> e : hashMap.entrySet())
treeMap.put(e.getKey(), new TreeMap<>(e.getValue()));
If your code uses the nested map as a regular Map, i.e. it doesn't use any specific method defined in HashMap or TreeMap, you can define the type parameter of your variables using Map instead:
HashMap<String, Map<String, SomeBean>> hashMap =
(HashMap<String, Map<String, SomeBean>>) request.getAttribute("HASHMAP");
TreeMap<String, Map<String, SomeBean>> treeMap =
new TreeMap<String, Map<String, SomeBean>>(hashMap);
Or else, you won't be able to use constructor(Map) or putAll(Map), and you will have to fill in the treeMap manually.
Related
So I know how to create a List of Map values
new ArrayList<String, Integer>(map.getValues());
Or from entry set map.entrySet()
However there doesn't seem to be a similar way to add a list of Map.Entry<String, Integer>
Is there a way to do this so I can write it all in just a return statement?
Map<String, Integer> map = new TreeMap<String, Integer>();
public List<Map.Entry<String, Integer>> getWordList(){
return new ArrayList<Map.Entry<String, Integer>>(map);
}
This doesn't work. But what does?
entrySet returns a Set and not a List, which means that the map's keys may or may not be in order.
However, in the case of TreeMap the JavaDoc says the following about it:
Returns a Set view of the mappings contained in this map.
The set's iterator returns the entries in ascending key order.
Apparently, entrySet() guarantees the mappings to be in the same order as the TreeMap. In short, you could just use it anywhere where a Collection is required. Creating a List is then trivial:
new ArrayList<>(map.entrySet())
or
List.copyOf(map.entrySet())
I have two HashMap in Java.
First one contains a key and its value. Where second contains an evaluation index (order) of that keys. I want to sort the first map by referring to the second map.
First HashMap <key, value>
<"C","ccc">
<"D","ddd">
<"A","aaa">
<"B","bbb">
Second HashMap <key, value>
<"0","A">
<"1","B">
<"2","C">
<"3","D">
Result should be
<"A","aaa">
<"B","bbb">
<"C","ccc">
<"D","ddd">
Looping this two map and checking comparing keys is simple but not efficient. Any efficient idea?
You can use Java Stream API. First, sort the second map entrySet by key then map second map's value as key and get first map's value by value of the second map and then collect as LinkedHashMap using Collectors.toMap
secondMap.entrySet().stream()
.sorted(Comparator.comparing(Map.Entry::getKey))
.collect(Collectors.toMap(Map.Entry::getValue, k -> firstMap.get(k.getValue()),
(x, y) -> y, LinkedHashMap::new));
If you use LinkedHashMap/TreeMap ordered by key for the second map then you don't need to sort the keys. See demo here
First of all HashMap is not ordered collections. The key-value pairs in HashMap are ordered based on the value of hashCode() result of keys. So I would say you can't keep sorted values in HashMap.
Instead, you can use LinkedHashMap - it will be ordered with order of insertion.
And for your solution, i would do:
HashMap<String, String> firstMap = ...
HashMap<String, String> secondMap = ...
LinkedHashMap<String, String> orderedMap = new LinkedHashMap<>();
for (int i = 0; i < secondMap.size(); ++i) {
String key = secondMap.get(String.valueOf(i));
orderedMap.put(key, firstMap.get(key));
}
Did not run this code, but it should work.
Alternatively, you can use TreeMap that is ordered based on Comparable interface of the keys.
And to answer what is better to use - TreeMap or LinkedHashMap - depends on how actually you are using this map later. In most cases LinkedHashMap is enough, although if you need to, for example, get the closest greater element to some key, then TreeMap is a choice.
There are some comparison between HashMap and TreeMap
What is the difference between a HashMap and a TreeMap?
Traverse the values of secondMap and collect the related key, value set in the map:
Map<String, String> result = secondMap.values().stream()
.collect(Collectors.toMap(Function.identity(), firstMap::get, (x,y)-> x, LinkedHashMap::new));
Try this:
Map<String, String> firstMap = new HashMap<>();
firstMap.put("C", "ccc");
firstMap.put("D", "ddd");
firstMap.put("A", "aaa");
firstMap.put("B", "bbb");
Map<String, String> secondMap = new HashMap<>();
secondMap.put("0", "A");
secondMap.put("1", "B");
secondMap.put("2", "C");
secondMap.put("3", "D");
Map<String, String> result = secondMap.values().stream()
.collect(Collectors.toMap(Function.identity(), firstMap::get, (x,y)-> x, LinkedHashMap::new));
System.out.println(result);
I defined a hashmap as follows:
HashMap<String, List<String>> hashmap = new HashMap<String, List<String>>();
And I would like to retrieve the complete list of keys and print them. However, keySet() does not work for maps defined as <String, List<String>>
Set<String, List<String>> keys = hashmap.keySet();
How could I solve this problem?
What you need is not the .keySet(), but rather the .entrySet():
Set<Map.Entry<String, List<String>>> keys = hashmap.entrySet();
More info:
How to efficiently iterate over each entry in a Map?
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
I am trying to run a very simple program, and I'm stuck on the basics of declaring the nested lists and maps.
I'm working on a project which requires me to store polynomials into an ArrayList.
Each polynomial is named, so I want a key/value map to pull the name of the polynomial (1, 2, 3 etc.) as the key, and the actual polynomial as the value.
NOW the actual polynomial requires key values as well because the nature of this program requires that the exponent be associated with the coefficient.
So for example I need an ArrayList of polynomials, say the first one is a simple:
polynomial 1: 2x^3
the array list contains the whole thing as a map, and the map contains key: polynomial 1 and value: is a Map... with the 2 and 3 being key/values.
The code I have is below but I'm not 100% on how to format such nested logic.
public static void main(String[] args) throws IOException{
ArrayList<Map> polynomialArray = new ArrayList<Map>();
Map<String, Map<Integer, Integer>> polynomialIndex = new Map<String, Map<Integer, Integer>>();
String filename = "polynomials.txt";
Scanner file = new Scanner(new File(filename));
for(int i = 0; file.hasNextLine(); i++){
//this will eventually scan polynomials out of a file and do stuff
}
EDIT:
Updated the key/value in Map, still having issues.
The code above is giving me the following error:
Cannot instantiate the type Map<String,Map<Integer,Integer>>
So how then do I go about doing this or am I just going about this all the wrong way?
You can't instantiate new Map<String, Map<Integer, Integer>>() because java.util.Map is an interface (it doesn't have a constructor). You need to use a concrete type like java.util.HashMap:
Map<String, Map<Integer, Integer>> polynomialIndex = new HashMap<String, Map<Integer, Integer>>();
Also, if you're using Java 7 or above, you can use generic type inference to save some typing:
Map<String, Map<Integer, Integer>> polynomialIndex = new HashMap<>();
This is incorrect:
Map<String, Map<Integer>> polynomialIndex = new Map<String, Map<Integer>>();
Maps need to have two parameters and your nested map Map<Integer> only has one. I think you're looking for something like:
Map<String, Map<Integer, Integer>> polynomialIndex = new Map<String, Map<Integer, Integer>>();
Or it may be best done separate.
Map<String, Map> polynomialIndex = new Map<String, Map>();
Map<Integer, Integer> polynomialNumbers = new Map<Integer, Integer>();
With this you can just put the numbers in the polynomailNumbers Map then use that in polynomialIndex.