I have this hashmap of students which stores the id, name and last name.
So I created this :
Map<Interger, HashMap<String,String>> students = new HashMap<>();
where the second hashmap stores the name and lastname.
My goal is to look for a student in a swing application, I succeed in searching with id because it's the key of the first hashmap, but i'd like to use all of them like this:
So my question is : If I want to search by name or last name, how can i get the value of the first hashmap and put it in a new hashmap ?
You can iterate on the hashmap like this :
private int searchByName(String s) {
for(Map.Entry<Integer, HashMap<String, String>> entry : students.entrySet()) {
HashMap student = entry.getValue(); // Hashmap containing first and lastname
if (student.containsKey(s)) // If name match
return entry.getKey(); // Return the student ID
}
return 0; // Student not found
}
For the lastname just use containsValue(s) instead of containsKey(s)
You can use the Google Collections API Guava for that specifically a BiMap
A bimap (or "bidirectional map") is a map that preserves the
uniqueness of its values as well as that of its keys. This constraint
enables bimaps to support an "inverse view", which is another bimap
containing the same entries as this bimap but with reversed keys and
values.
With this you'will be able to search using first name and last name. This BiMap will be value to your first parent hashmap.
I am not sure if the data structure is the best for your use-case but answering to your question, you should try using values() method which would return you the collection of values of the Map
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#values()
Collection res = studensts.values();
Iterator<HashMap<String, String>> i = res.iterator();
Map<String,String> resM = null;
while(i.hasNext()){
resM = i.next();
}
Related
I'm checking to see if a key in my HashMap exists, if it does, I also want to check to see if any other keys have a value with the same name as that of the original key I checked for or not.
For example I have this.
System.out.println("What course do you want to search?");
String searchcourse = input.nextLine();
boolean coursefound = false;
if(hashmap.containsKey(searchcourse) == true){
coursefound = true;
}
This checks to see if the key exists in my hashmap, but now I need to check every single key's values for a specific value, in this case the string searchcourse.
Usually I would use a basic for loop to iterate through something like this, but it doesn't work with HashMaps. My values are also stored in a String ArrayList, if that helps.
You will want to look at each entry in the HashMap. This loop should check the contents of the ArrayList for your searchcourse and print out the key that contained the value.
for (Map.Entry<String,ArrayList> entries : hashmap.entrySet()) {
if (entries.getValue().contains(searchcourse)) {
System.out.println(entries.getKey() + " contains " + searchcourse);
}
}
Here are the relevant javadocs:
Map.Entry
HashMap entrySet method
ArrayList contains method
You can have a bi-directional map. E.g. you can have a Map<Value, Set<Key>> or MultiMap for the values to keys or you can use a bi-directional map which is planned to be added to Guava.
As I understand your question, the values in your Map are List<String>. That is, your Map is declares as Map<String, List<String>>. If so:
for (List<String> listOfStrings : myMap.values()) [
if (listOfStrings .contains(searchcourse) {
// do something
}
}
If the values are just Strings, i.e. the Map is a Map<String, String>, then #Matt has the simple answer.
I have a HashMap "stateCityMap" which is a Map>. the Keys are the States ie Goa,Kerala etc and the Values are the Cities ie Panjim,Margao etc. I want to Check if a particular city is present in the HashMap, eg.Margao and give the corresponding key of that value as the result..but everytime i ran the below code.it performs the else part(when the city is not present in the HashMAp).
city :- is the name of the city I pass to this function
Code:
public String getState(Map<String, List<String>> stateCityMap, String city) throws CityNotFoundException {
HashMap<String, List<String>> g = new HashMap<String, List<String>>(stateCityMap);
if(g.containsValue(city)){
System.out.println("State:- " +g.get(city));
}
else {
throw new CityNotFoundException("City Not Found");
}
return null;
}
Why is it doing that? why am I getting the wrong result?
It's not efficient, but you need to scan through each list in the map:
public String getState(Map<String, List<String>> stateCityMap, String city) throws CityNotFoundException {
for (Map.Entry<String, List<String>> entry : stateCityMap.entrySet()) {
if (entry.getValue().contains(city)) {
return entry.getKey();
}
}
throw new CityNotFoundException("City Not Found");
}
containsValue method returns true if the map maps one or more keys to the specified value.
In your case type of value is List, but you are calling containsValue method by passing String. So it will always returns false.
Since your value type is List, you will end up iterating all keys and all values to find if a city exists in any of the lists.
Better is to maintain two maps. Challenge will be to make sure that both maps always get updated (insert, delete, update) correctly.
Hope that helps.
I have below data structure like this
Country,StateID1 where StateID1 contains "City1","City2","City3" etc
Country,StateID2 where StateID2 contains "City1","City2","City3" etc
I know i can't use HashMap to implement above data structure because if i add StateID2 to same Country StateID1 will be replace with StateID2
for eg
map.put("1","1111");
map.put("1","2222");
output
key:value
1:2222`
i am facing hard time to figure out how to do this. I need some support from you guys
You need some wrapping object for storing your 'state' data. Then you can have a structure like this: Map<String, List<StateBean>>. This way you can handle a list of state for every country.
If data are just Strings use Map<String, List<String>>
You can have a Map<String, Set<String>>.
Store the StationIDs in an ArrayList object and add those object in a HashMap using key-value pair .. where key is the Country against the StationId ArrayList Object.
StateID1 = ["City1","City2"] // ArrayList
StateID2 = ["City1","City2"]
We could have the map as Country,ListOfStates
ListOfStates could be a list that contains StateIds
Or StateIds as a Map with StateId as key and list of cities as value
You could create a class for the same.
class YourClass
{
String country;
State state;
}
class State
{
Set<String> cities;
}
You can then use this class as a data structure. You don't really need to use Collections framework for the same.
OR
If you really want to do it using Collections, then you can use a combination of Country and StateId as the key, and the list of cities as the value in a Map. For ex:
String country = "1";
String state = "1";
String separator = "-" // You could use any separator
String key = country + separator + state;
Set<String> cities = new HashSet<String>();
cities.add("1");
cities.add("2");
Map<String, Set<String>> map = new HashMap<>();
map.put(key, cities);
So your key would be 1-1 and value would be 12.
Use can Data Structure map < String,vector < String >> , map < class T,vector < class U > >
I have:
public static HashMap<String, String> CHILD_NAME_DOB = new HashMap<>();
Suppose the values in CHILD_NAME_DOB are:
<adam,15121990>
<roy,01051995>
<neha,05091992>
<alisha,11051992>
I am trying to fetch the last key element from CHILD_NAME_DOB. That is, I want to fetch key alisha from the example above to temporary String name.
Also I want to know on how to fetch data by index.
Eg.: if int index = 2 , I want key "Neha" in String name
TIA.
Edit: DateOfBirth value (value data in CHILD_NAME_DOB) is dynamic and is unknown. So THIS LINK is not what I want.
Single line solution:
First note that the Java HashMap does not guarantee the order of entries. So each time you iterate over a HashMap, entries appear in different positions. You will need LinkedHashMap that guarantees the predictable iteration order.
Map<String, String> CHILD_NAME_DOB = new LinkedHashMap<>();
Get the key by index:
key = (new ArrayList<>(CHILD_NAME_DOB.keySet())).get(index)
Get the value by index:
CHILD_NAME_DOB.get(key)
Thanks to #Pentium10 for this answer.
And I little modified it according to my need.
String key="default";
Iterator myVeryOwnIterator = CHILD_NAME_DOB.keySet().iterator();
while(myVeryOwnIterator.hasNext()) {
key=(String)myVeryOwnIterator.next();
//String value=(String)meMap.get(key);
}
Toast.makeText(viewEnterChildExp.getContext(), "Key: "+key , Toast.LENGTH_LONG).show();
I'm getting the last key element by this.
I'll update as soon I also get to find an easy way to key by index.
This way to get key....
public static String getHashMapKeyFromIndex(HashMap hashMap, int index){
String key = null;
HashMap <String,Object> hs = hashMap;
int pos=0;
for(Map.Entry<String, Object> entry : hs.entrySet())
{
if(index==pos){
key=entry.getKey();
}
pos++;
}
return key;
}
You can also use an ArrayMap instead of a HashMap. To get the value by index use:
ArrayMap.valueAt(index);
To get the Key at an index use:
ArrayMap.keyAt(index);
Fetching the "last" key and fetch by index is not supported by HashMap. You can use a LinkedHashMap and lookup the element with index 2 (or the last element) by iterating over it. But this will be a O(n) operation.
I suggest you use a List<Pair<String, String>> if the order of the keys/values is important to you and you wish to do index based lookup.
If both key based and index based lookup is important to you, you could use a combined data structure that consists of both a List and a HashMap, but note that removal of elements will be O(n).
You can create a class Child
public class Child(){
private String name;
private String number;
....
}
and then put this object in a List
public static List<Child> CHILD_NAME_DOB = new ArrayList<Child>(); // using LinkedList would defeat the purpose
in this way you can invoke the method get(int index), that returns the element at the specified position in this list.
In your example
<adam,15121990>
<roy,01051995>
<neha,05091992>
<alisha,11051992>
invoking CHILD_NAME_DOB.get(2) you'll get <neha,05091992>(as Child object)
HashMap does not have a concept of ordering, so getting the n-th entry does not make sense. You could use a TreeMap instead, which is ordered on its keys.
However, you should reconsider your model as you seem to have conflicting interests. On the one hand, accessing by index is typical for Lists, whereas accessing by key is typical for Maps. I'm not sure in which situation you'd want to do both.
If you really want to do both index and key accessing, you could write your own data structure that stores the data in a list combined with a mapping from key to index and vice versa. I would recommend against this, but if that's really what you want, then I think that's the best solution.
I know it is not the best solution, but what about this solution (pseudocode!). Just combine List and Map in one class.
public class UserBirthday {
private List<String> names = new ArrayList<>();
private Map<String, String> CHILD_NAME_DOB = new HashMap<String, String>();
public void add(String name, String bd) {
if (!CHILD_NAME_DOB.containsKey(name)) {
names.add(name);
}
CHILD_NAME_DOB.put(name, bd);
}
public String getByName(String name) {
return CHILD_NAME_DOB.get(name);
}
public String getByIndex(int index) {
return getByName(names.get(index)); // TODO: range test
}
public static void main(String[] args) {
UserBirthday ub = new UserBirthday();
ub.add("dit", "12345678");
ub.add("lea", "234239423");
ub.add("alex", "43534534");
ub.add("ted", "099098790");
System.out.println(ub.getByIndex(2));
System.out.println(ub.getByName("alex"));
}
}
You may get some problems if you remove an entry, but it should be just a suggestion.
for (String key : hmList.keySet()) {
String value = hmList.get(key);
Log.e("HashMap values", "key=" + key + " ,value=" + value);
}
I want to write a program that prints out entries "0" and "4" of the HashMap (i.e. entry.getKey(0) and entry.getKey(4) but it won't let me do this) What would be another way using what I already have?
Basically I have this:
HashMap<String, Integer> hm = new HashMap<String, Integer>();
I can iterate over each entry using this code:
for (Map.Entry<String,Integer> entry : hm.entrySet())
{
System.out.println(entry.getKey() + "/" + entry.getValue());
}
Since people have asked for more contextual information, I am storing a set of strings in the HashMap. For example the 0th entry is "Bob", the 1st entry is "Mindy", the 2nd is "Yasser", the 3rd is "Greg" and the 4th is "Jacky." I want the program to print out the 0th and 4th entries of the populated HashMap.
If you are specific about the keys in the Map, you can directly use get() method.Like this,
Integer value = hm.get("0");
If you want to iterate then use something like the code below :
HashMap<String, Integer> hm = new HashMap<String, Integer>();
for (Entry<String, Integer> entry : hm.entrySet())
{
String key = entry.getKey();
if(key.equals("0") || key.equals("1"))
System.out.println(key + "/" + entry.getValue());
}
You cannot pass index to the getKey() method like getKey(0) etc. Refer the documentation.
HashMap class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time. So, if you are looking to fetch values from a HashMap based on index, probably it is not possible. Closest to your requirement will be something like LinkedHashMap, which maintains the order of keys for insertion/access order.
HashMap works on principle of hashing, we have put(key, value) and get(key) method for storing and retrieving Objects from HashMap. When we pass Key and Value object to put() method on Java HashMap, HashMap implementation calls hashCode() method on Key object and applies returned hashcode() into its own hashing function to find a bucket location for storing Entry object, important point to mention is that HashMap in Java stores both key and value object as Map.Entry in bucket which is essential to understand the retrieving logic.
The HashMap has no defined ordering of keys. You may use LinkedHashMap instead of HashMap It will always return keys in same order (as insertion) when calling keySet(). And then you pick the 0th or 4th key.Later you can retrieve the value for the keys you fetched at 0th and 4th location.
I would recommend simply using the get() method with the provided key. Iteration is not necessary in this case.
Since people have asked for more contextual information, I am storing a set of strings in the HashMap. For example the 0th entry is "Bob", the 1st entry is "Mindy", the 2nd is "Yasser", the 3rd is "Greg" and the 4th is "Jacky." I want the program to print out the 0th and 4th entries of the populated HashMap.
With how it is being used, an HashMap makes no sense. Use a String[] instead!
String[] names = {"Bob", "Mindy", "Yasser", "Greg", "Jacky" };
System.out.println("When " + names[0] + " met " + names[4]);
Why not a targeted approach:
String[] targets = {"0", "4"};
for (String target : targets) {
System.out.println(target + "/" + hm.get(target));
}
Way more efficient than the "big hammer" full iteration approach, and you get output order for free.
If you have a lot of entries in your Map you may considerate to use one of the navigable collections, like TreeMap.
NavigableMap<String,String> map = new TreeMap<>()
map.subMap("0", true, "4", true);
Visit: http://docs.oracle.com/javase/6/docs/api/java/util/NavigableMap.html