I'm new to Java. I implemented a Hash Map as shown below.
In a particular scenario I wanted to retrieve the key using values of the key.
For Eg: If user enters "Dravid", then I need to retrieve "2" from the Hash Map.
And I want to use only one hash map to implement this.
Can anyone help me with this?
HashMap<String,String> streetno=new HashMap<String,String>();
streetno.put("1", "Sachin");
streetno.put("2", "Dravid");
streetno.put("3","Sehwag");
streetno.put("4", "Laxman");
streetno.put("5", "Kohli");
Short version, so there is something to implement left for you:
Iterate over all entries of the map and compare your search string to the value of the entry. If it matches, return the key.
With a standard HashMap, the only thing you can do is iterate over the entries of the map until you find one that has the value that you are looking for and then return the key for that.
HashMap is made to quickly and efficiently lookup a value if you know the key, but not the other way around. There are some libraries that have maps that allow you to lookup the value by key as well as the other way around. Google Guava for example has a BiMap that supports this.
Using Guava's HashBiMap, you could do this:
BiMap<String, String> map = HashBiMap.create();
map.put("1", "Sachin");
map.put("2", "Dravid");
map.put("3", "Sehwag");
map.put("4", "Laxman");
map.put("5", "Kohli");
String key = map.inverse().get("Dravid");
To do this, you would need to use a bi-directional hashmap. Consider using the Apache Commons implementation.
Without it, you'd need to iterate over all the key / value pairs in the map and test for when the value equals "Dravid", then return the key. Like so:
for (Entry<String, String> pair : streetno.entrySet()) {
if (pair.getValue().equals("Dravid")) {
System.out.println("Found Dravid at key: " + pair.getKey());
}
}
You can do any of the above said answers, its also better to add this check before proceeding to the actual logic.
if(streetno.containsValue("Dravid")){
// do logic
}
else
System.out.println("Not found");
Related
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 am having map this way,
Map<String, Map<String, Set<String>>> sampleMap = new Map<String, Map<String, Set<String>>>();
and the data in this map would be this way,
sampleMap={2014={A=[1, 2], B=[3], 2015={A=[1,2], B=[1,2], 2016={A=[1,2], B=[3,4]}};
I want to remove the key's from the map based on this input: List<String> filter; with values this way,
filterArray : [2014, 2015]
i.e, first iterate through arraylist values one by one, verify if the arraylist value matches with any of the key in Hashmap.
if key is matched ignore it.
if key is not matched, I just want to remove that key from the map.
i.e, I always want to keep only matched keys in map, comparing with the input value passed.
In this case, as I have arraylist values this way,[2014,2015],
2014,2015 keys only to be in my map. So,
Data to be before removal:
sampleMap={2014={A=[1, 2], B=[3], 2015={A=[1,2], B=[1,2], 2016={A=[1,2], B=[3,4]}};
Data to be after removel:
sampleMap={2014={A=[1, 2], B=[3], 2015={A=[1,2], B=[1,2]}};
I tried this way, However I just want to know is this is the correct approch, or is it is prone to any of the exceptions?
Iterator<Map.Entry<String , Map<String, Set<String>>>> iter = sampleMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String , Map<String, Set<String>>> entry = iter.next();
logger.info("Keys : " + entry.getKey());
if (filterArray.equalsIgnoreCase(entry.getKey())) {
iter.remove();
}
}
Use retainAll() on the keySet:
map.keySet().retainAll(list);
Seems reasonable. I might have a couple pieces of advice.
First of all, whenever I see nested collections I always wonder if there should be a class or two in there. If this is a one-time task then don't worry about it, but if you want to reuse this code you might want to think about creating a class for your inner map/set... but if it's really this simple then it's no big deal.
Secondly if you are using Java 8, using a list comprehension for filtering would perform better (Because it would automatically thread your compares) and would be cleaner. I can give you the groovy solution for what you are trying to do, but I'm not familiar enough with java 8 list comprehensions to do it correctly.
def filteredStructure=structure.findAll{entry->entry.key.equalsIgnoreCase("2014") || entry.key.equalsIgnoreCase("2015"))
The java version should be really similar.
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.
I am have the Hashmap like this,
HashMap<String,String> epnSource = new HashMap<String, String>();
Now I have added the keys/values like this,
epnSource.put("10.3.2.227","EPN1");
epnSource.put("10.3.2.227","EPN2");
epnSource.put("10.3.2.166","EPN3");
epnSource.put("10.3.2.166","EPN4");
epnSource.put("10.3.2.161","EPN5");
I am trying to do every time before adding a value, I want to check number of occurrences of a key present in the HashMap. Suppose if key 10.3.2.227 has more than two occurrences I shouldn't added it and go for new one. Any suggestions will be helpful.
Suppose if value 10.3.2.227 has more than two occurrences ...
It won't. The way that you have implemented it, the "10.3.2.227" is a key of the Map, and a given key cannot appear more than once in a Map.
If you want a given key (e.g. "10.3.2.227") to map to multiple values (e.g. "EPN1" and "EPN1"), you need to use either a Map<String,Set<String>> or a MultiMap class from the Apache or Google/Guava collections libraries.
If the map previously contained a mapping for the key, the old value is replaced.
It is not possible duplicate key in HashMap.