I am using String object as the key to a linkedhashmap.
How can I get all the entries in the LinkedHashMap?
You have three options that depend on whether you need just keys, just values or both
Set<String> keys = yourMap.keySet();
Collection<YourValueClass> values = yourMap.values();
Set<Map.Entry<String,YourValueClass>> pairs = yourMap.entrySet();
then you can easily iterate over them if you need. Actually all of them allow iterating using a simple foreach loop:
for (Map.Entry<String,YourClassValue> e : yourMap.entrySet())
// do something
You can use the entrySet method, which returns a set containing the key-value pairs in your map.
Related
With a LinkedHashMap, when I try to reinsert same key with different value, it replaces the value and maintains the order of key i.e if I do this
Map<String,String> map = new LinkedHashMap<>();
map.put("a", "a");
map.put("b", "b");
map.put("c", "c");
map.put("d", "d");
map.values().stream().forEach(System.out::print);
Output: abcd
Now if I add in the map a different value with same key,the order remains the same i.e
map.put("b", "j");
map.values().stream().forEach(System.out::print);
Output: ajcd
Is there any other way? One is to remove and reinsert key with new value, which prints acdj as output. In my case I want to do it for multiple keys based on some property of object used as value?
Solution using streams would be preferable.
This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map
LinkedHashMap javadoc.
it keep track of the keys insertion, and if we add the Map.put javadoc :
If the map previously contained a mapping for the key, the old value is replaced by the specified value.
Map javadoc
The Entry is not replace, only the value is modified so the key remains the same.
You need to remove and then insert the value to update the ordering of the keys.
A HashMap is not sorted by either keys or values. What you are looking for is a TreeMap.
For a HashMap, the only guarantee is, that the keys are hashed and put in an array, based on their hash.
The LinkedHashMap, according to the Javadoc, creates an internal LinkedList, and tracks the original insertion order of entries. In other words, if you use LinkedHashMap, you won't, necessariely receive a 'sorted' list at all.
You have two options to work around this: Either use a TreeMap (or derivate thereof), or sort every time, you want to output the values. TreeMaps have an internal sorting, based on their keys. If the keys are compared to each other the way you'd expect (by comparing the Strings) then you get a properly ascending sorting, based on the keys. However this does not solve your problem, that you want to sort the values.
To solve your original problem, use a bidirectional TreeMap. Apache Commons4 implements such a map (https://commons.apache.org/proper/commons-collections/javadocs/api-4.3/org/apache/commons/collections4/bidimap/AbstractDualBidiMap.html#values--)
It allows you to access both a key and a value set. But be aware that this map will not work for you, if your values are not unique. Like keys, all values in a bidirectional map need to be unique, because they need to serve as keys themselves.
From the Javadoc:
This map enforces the restriction that there is a 1:1 relation between keys and values, meaning that multiple keys cannot map to the same value. This is required so that "inverting" the map results in a map without duplicate keys. See the put(K, V) method description for more information.
Hashmap insertion is based on hashcode only. For example a key of "b" has a hashcode as 98.
for map.put("b", "b");
you inserting as a key "b" which has hascode 98.
so it will look like. 98 ---> holds value 'b'.
again if you try to put on same key "b" which has a hashcode 98 only.
so hashmap try to link on same hashcode only which is 98 ---> holds "j" as a value.
for know working of hashmap hashcode check out below link
https://www.geeksforgeeks.org/internal-working-of-hashmap-java/
So, I have a Map (String, String) which I receive this map can have about 600-800 entries. My task is to retrieve only about 60-120 (based on some logic) of those pairs based on the keys (constant strings).
Right now I have created a List of the required Keys, I am iterating the Map I receive and pulling out required pairs into another Map and passing it on. This works, but the code looks horrible.
There surely has to be a better way of doing this. Any suggestions?
I thought of using contains instead of matching keys, but my requirement is for exact matches. Yes, I read about using RegEx for exact matches, so that can be used as a last resort.
What I need help with:
1. Better way to store required keys than having them in a List. This list of keys are going to be a constant. Having a list of 60-120 strings hardcoded into a List looks horrible.
2. Fastest (time) way to compare the said list and pull out required pairs.
My code:
List <String> keysToCheck = new ArrayList<String>();
keysToCheck.add("attrib1");
...
keysToCheck.add("attribN");
Map<String, String> newMap = new HashMap<String, String>();
for (String key : keysToCheck) {
if(mapRcvd.containsKey(key)) {
newMap.put(key, mapRcvd.get(key));
}
}
I am looking for solutions which would be quicker, as this would be a very small part of a larger application. I am good with having to write a lot of code to achieve that.
You can store all constant keys in a file, where each line contains one key. Then you can get all required keys like:
List<String> requiredKeys = Files.lines(Paths.get(PATH_TO_FILE_WITH_KEYS))
.collect(Collectors.toList());
Now get map with required keys using stream filter method:
Map<String, String> collect = mapRcvd.entrySet().stream() // get stream of map entries
.filter(entry -> requiredKeys.contains(entry.getKey())) // filter only such entries which has required key
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); // collect all filtered entries into new map
More about Collectors.toMap, javadoc
Update: while getting map with required keys may seem more compact, the for-loop with containsKey method in your example is faster than contains. You should probably use the advice #Holger left in the comments
I want to get the first value from my HashMap while I do not know the key for the value.
Is it possible? Are there are libraries to do this?
You could use a java.util.LinkedHashMap<K, V>. Then you can iterate through the map in insertion order.
To only get the first entry you can use an iterator:
Map<String, String > map = new LinkedHashMap<String, String >();
// ... fill the map
Entry<String, String > next = map.entrySet().iterator().next();
next.getKey();
next.getValue();
If you want the first key that you inserted into the map, then use LinkedHashMap. It's basically a HashMap that remembers the order in which things were inserted, so you can iterate them in the original order.
If you want to select the first key in the natural ordering of the key class; or if you want to select the first key under some ordering of your own, then use TreeMap. It's a type of map that sorts things as you insert them into the map. You can set up a TreeMap with its own Comparator, if you want to specify the order in which the keys are sorted. If you don't supply a Comparator when you create a TreeMap, then it will sort the keys by their natural order.
I recommend reading the Javadocs for both TreeMap and LinkedHashMap before you decide which of the two is appropriate for your application.
Use a LinkedHashMap or TreeMap to maintain insertion order in the first place, after that it is just a matter of using the Iterator.
You can do something like this.
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
//This will be your very first element
Map.Entry pairs = (Map.Entry)it.next();
System.out.println(pairs.getKey() + " = " + pairs.getValue());
}
I have the following entries in my HashMap
<key1,value1>
<key2,value2>
<key3,value2>
<key4,value4>
<key5,value2>
I would like to find all the Keys that contain the value "value2".
The answer would be a KeySet containing the following keys:
{key2,key3,key4}
Is it possible to accomplish that in a HashMap?
thanks
just Iterate entries of your map and check if the value of the current entry is equal to "value2" then add it to Set.
try this
Set<String> keySet = new HashSet<String>();
for (Map.Entry<String, String> entry : map.entrySet())
{
if(entry.getValue().equals("value2")
{
keySet.add(entry.getKey());
}
}
I guess there is no other option since you have duplicate values in your map.
I would like to find all the Keys that contain the value "value2". The answer would be a KeySet containing the following keys: {key2,key3,key4}
Two options:
new map where the values are the keys and the keys are the values (if every key and value are unique)
iterate through the entries of your map and check if the value of the current entry is equal to "value2", if yes add it a set with the results
Map is supposed to use in such way that access the values using the keys, but it seems you are doing it in reverse.
If you are sure about what you are doing, there is no good way to accomplish. Iterate over map and store the keys in separate list.
More over Look at Gauva's Multimap, that might suits for your requirment.
I have a text file which looks like this:
code appearance
----------------
j4t8 1
fj89 3
pf6n 1
j4t8 5
And I want to sort by the codes which appear the most. As you can see (and since I want to perform a group by) there are duplicate codes, so using HashMap would be a problem (duplicate keys). Any ideas?
don't know if this is the best solution but you could create a map of a list like this:
Map<String, List<Integer>> map = new HahsMap<String, List<Integer>>();
if(map.contains.(key))
{
map.get(key).add(new_appearance_value);
}
else
{
List<Integer> app = new ArrayList<Integer>();
app.add(new_appearance_value);
map.put(key, app);
}
Where the map key would be the code and the values of appearance would go into the list.
Note: to determine which code has more appearances just check for the size of the list of each code.
You can use
HashMap map = new HashMap<String, List<Integer>>();
The appearances will be stored in a list associated with every code.
Then given a code you just retrieve the list of integers and iterate over it.
You need a Collection of Pair objects. Each pair holds the code and the appearance. You then sort the collection using a Comparator, which only compares the appearance in each Pair object, and disregards the code.
The Commons Collections MultiValueMap can be used to decorate another map, allowing it to have more than one value for a key.