I have a HashTable with the following {4:1, 3:56, 4:3, 4:5, 9:89, etc.}
I then make the keys of this Table into a keyset by calling map.keySet().
How can I loop through that set to only output the values associated with the key of 4? I want the output to be 1,3,5, therefore I only want the values associated with the key 4? Is this possible, and if so how.
That's not how maps work. Maps typically only associate one value with each unique key value. So if you have a Map<Integer,Integer> myMap, calling myMap.put(4, newValue), where newValue is some integer, will overwrite the value that was previously mapped to 4. You can have duplicate values though, and you can print all known keys that have been mapped to that value in a map using the following loop.
for (Entry<Integer, Integer> entry : myMap.entrySet()) {
if (entry.getValue().equals(4)) {
System.out.println(entry.getKey());
}
}
A HashMap or a HashTable only maps a key to a value.
Option 1:
If you want to have multiple values for key store it as a list
Map<Integer, List<Integer>> myMap = new HashMap<>();
//To add value for a key
if (!myMap.containsKey(key)) {
myMap.put(new ArrayList<>());
}
myMap.get(key).add(value);
//Get
myMap.get(key); //This will give you the list of value for a given key and null if the key is not present
Option 2:
You can use Google Guava's MultiMap
You can use Google Guava Collections' MultiMap as it allows each key to associate with multiple values.
ListMultimap<String, String> multimap = ArrayListMultimap.create();
multimap.put(key, value);
Documentation can be found here: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
Related
I am using a multimap like this
Multimap<String, MyObject> tasksMap = ArrayListMultimap.create();
Where there can be multiple items for the same key, get the List value for every key in the map?
.asMap() lets you get a map and you can then iterate over its .entrySet().
Something like
for (Entry<String, Collection<MyObject>> e : tasksMap.asMap().entrySet()) {
String key = e.getKey();
Collection<MyObject> values = e.getValue();
...
}
Just use get method to get all values for a key
List<MyObject> values = tasksMap.get(key);
or use values to get all values for every key in map
Collection<List<MyObject>> values = tasksMap.values();
or entries to get all entries
Collection<Map.Entry<String, List<MyObject>>> entries = tasksMap.entries()
I have an HashMap with names(key) and dates(value) and I need to show if a name that i enter again is a duplicate (I am doing socket programming with different states). Example, I put in the map 3 different names and at the forth time I put a duplicate name.
I tried these codes (they run) but with no success:
HashMap<String, String> map = new HashMap<String, String>();
if(stat.equals("RECEIVE_NAME")){
name = reader.readLine();
if(map.containsKey(name)){
System.out.println("duplicate");
}
}
or
for(Map.Entry<String, String> entry : map.entrySet()){
if(name.equals(entry.getKey())){
sendMessage("duplicate");
}
}
NB: I have a map.put(name) when is not a duplicate after this sequence of blocks. And i know that an hash map can not have duplicate keys :)
A HashMap cannot contain duplicate keys. If you put a key-value pair in a map which already contains the key, the old value will be replaced by the new value.
map.put() returns the previous value associated with key, or null if there was no mapping for key. So you can store that return value and check if is not null:
String check = map.put(name);
if(check != null){
System.out.println("dup: " + check);
}
Use map.putIfAbsent(name) to not overwrite the associated value.
I'm having problems on how to tackle this since I know a map has no specific order. I would think that you would iterate over the map's Keys and then check the value count by getting the size of the LinkedList since the Values to the Key are held in a LinkedList I can just call a size or length call for the LinkedList, but my main question is how to get inside the HashMap with an iterator first to do this?
An iterator over all the entries of a map can be done as follows in Java:
for (Map.Entry<Key, Value> entry : map.entrySet()) {
Key k = entry.getKey();
Value v = entry.getValue();
// do something with k,v
}
However, a map can only contain at most one value associated with a key. So, if using a map of lists to associate multiple values, the list would be accessed simply through get.
I suppose you have something like this :
Map<Integer,List<Integer>> map = new HashMap<>();
You can just iterate very simply through all the values you have.
for (List<Integer> values : map.values()){
System.out.println(values.size());
}
Hashtable<Integer,String> ht = new Hashtable<Integer,String>();
ht.put(1,"student1");
ht.put(1,"student2");
How can I iterate through all values of "a single key"?
key:1
values: student1, student2
You need to use:
Hashtable<Integer, List<String>> ht = new Hashtable<Integer, List<String>>();
and add the new String value for a particular key in the associated List.
Having said that, you should use a HashMap instead of Hashtable. The later one is legacy class, which has been replaced long back by the former.
Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
then before inserting a new entry, check whether the key already exists, using Map#containsKey() method. If the key is already there, fetch the corresponding list, and then add new value to it. Else, put a new key-value pair.
if (map.containsKey(2)) {
map.get(2).add("newValue");
} else {
map.put(2, new ArrayList<String>(Arrays.asList("newValue"));
}
Another option is to use Guava's Multimap, if you can use 3rd party library.
Multimap<Integer, String> myMultimap = ArrayListMultimap.create();
myMultimap.put(1,"student1");
myMultimap.put(1,"student2");
Collection<String> values = myMultimap.get(1);
A Hashtable doesn't store multiple values for a single key.
When you write ht.put(1, "student2"), it overwrites the value that goes with "1" and it is no longer available.
Hashtable doesn't allow multiple values for a key. When you add a second value to a key, you're replacing the original value.
If you want multiple values for a single key, consider using a HashTable of ArrayLists.
I have created a HashMap as per my code...
HashMap map=new HashMap();//HashMap key random order.
map.put("Amit","Java");
map.put("Saral","J2EE");
map.put("Saral","Andriod");//same key but different value
map.put("Nitin","PHP");
map.put("hj","Spring1");
System.out.println("There are "+map.size()+" elements in the map.");
System.out.println("Content of Map are...");
Set s=map.entrySet();
Iterator itr=s.iterator();
while(itr.hasNext()){
Map.Entry m=(Map.Entry)itr.next();
System.out.println(m.getKey()+"\t"+m.getValue()+"\t"+ m.hashCode());
}
When I execute this code, the value for key=Saral is Android. Is there any way that I can get the previous value for this key, which was J2EE?
No, you can't have that with a standard HashMap. The easiest solution would be to store a List as value in the map though, and then you can add multiple items to the list (Btw you should use generic collections too). To simplify, you could use a helper method like this:
void addToMap(Map<String, List<String>> map, String key, String value) {
List<String> list = map.get(key);
if (list == null) {
list = new ArrayList<String>();
map.put(key, list);
}
list.add(value);
}
Map<String, List<String>> map = new HashMap<String, List<String>>();
addToMap(map, "Amit", "Java");
addToMap(map, "Saral", "J2EE");
addToMap(map, "Saral", "Andriod");//same key but different value
addToMap(map, "Nitin", "PHP");
addToMap(map, "hj", "Spring1");
...
The helper method here is just an illustration - a full, robust implementation may need to include e.g. checks for duplicate values, depending on whether you allow them. If not, you may prefer using a Set instead of List.
Update
To print out the contents of this map, you need to use an embedded loop to iterate through the list of values for each map entry (btw you can use a foreach loop instead of an iterator):
for (Map.Entry<String, List<String>> m : map.entrySet())
{
for (String v : m.getValue())
{
System.out.println(m.getKey()+"\t"+v+"\t"+ m.hashCode());
}
}
A Map can contain at most one entry per key, so when you call map.put("Saral","Andriod"), the old "J2EE" value is removed. To support multiple values per key, you would need to maintain a Map<String, List<String>> or else a multi-map implementation such as Guava's Multimap.
As a side note I would recommend you start using generics, for example Map<String, String>, Iterator<String>, etc. for type safety at compile time.
The old value is overwritten (replaced). There will be only one mapping (entry) for one unique key. There fore it does not exist anymore so you can not retrieve it.
You cannot do this with standard implementations of Map that Java provides. However there are implementations of MultiMap (that's basically what you're after).
One example is this one from Google:
http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/Multimap.html
Note that you won't be able to just get this one interface, you'll need a few classes along with it.
As other have said, this won't work with a standard Map. However, Google's Guava provides a MultiMap interface, which you can use to store multiple values with a single key.
Example of use:
Multimap<String,String> multiMap = ArrayListMultimap.create();
multiMap.put("color", "red");
multiMap.put("color", "blue");
System.out.println(multiMap.get("color")); //returns a ["red', "blue"] list