I am trying to implement HashMap in JAVA, in my algorithm, i have to find if any of the keys contain values other than a specific value....for instance, lets say, all the keys in the map should have value 0 stored in them.
How can i check if, the map contains value which is not equal to 0.
I tried this but logically it isn't correct i know :
if(!hm.containsValue(0)) /* where hm is hashmap object*/
You have to iterate over all the values and check each one to see if it's not equal to zero, and that's O(n). There's no alternative using a Map, a Map is efficient for finding keys, not for finding something in the values. For example, using the standard Map implementation in Java:
Integer zero = new Integer(0);
for (Integer i : hm.values()) {
if (!zero.equals(i)) {
System.out.println("found one non-zero value");
break;
}
}
you can define the map as follows:
Map<String, Integer> map = new HashMap<String, Integer>();
And check if it contains a non-zero value as follows :
for ( Integer value: map.values()) {
if ( value != 0) {
// non-zero value found in the map
}
}
Related
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());
}
I have Map in Java
Map<String, List<String>> Collections;
String - a parents to ExpandtableList
List -a children to Expandtable List
Example Values
<"12" , "5,6,7,8">
<"15" , "4,6,2,8">
<"17" , "1,6,7,8">
<"8" , "5,6,6,8">
I'd like to get second parent and atribute to temporary String variable.(it is a "17") How can i refer to 2-nd parent and return value ?
There is no ordering in HashMap. If you want to focused on Order with Map you should use LinkedHashMap.
Use LinkedHashMap instead of HashSet. LinkedHashMap will maintain the insertion order.
Well, if you want "17" then you can just write map.get("17") to get the List.
Java doesnt keep track of the order here as it uses a Set to store the data. map.keySet() will return you a set you can iterate through.
You can HOPE that 17 falls under the natural ordering that Java does and do something like this.
HashMap<String, List<String>> map = new HashMap<>();
int count = 0;
for (String key : map.keySet()) {
count++;
if (count == 2)
return map.get(key);
}
If you want to retain an order in a Map, your usual choice would be a LinkedHashMap. With a linked hash map, you do however still not have direct access to an entry by its index. You would need to write a helper function:
static List<String> indexList(LinkedHashMap<String, List<String>> map, int index) {
int i = 0;
for(Map.Entry<String, List<String>> entry : map.entrySet()) {
if(i++ == index) {
return entry.getValue();
}
}
throw new IndexOutOfBoundException();
}
When using maps that point to a list, you might also be interested in using Guava's Multimap.
how would i iterate over the list "values" that one string "key" has.
Map<String, List<wordsStreamed>> hm = new HashMap<String, List<wordsStreamed>>();
hm.put(wordChoosen, sw.streamMethod());
hm has one key and over 10,000 values. i want to iterate over the values so i can compare my key with all the values. also i would like to know if this code is the best way to get my String values from the list of classes.
hm.values().iterator().next().get(i).toString()
To iterate over your HashMap's values, you can use fast-enumeration.
What you probably need here is to iterate over the key set, then access the List for each value and iterate over each of the List's items to compare it to the key.
For instance:
Map<String, List<Object>> hm = new HashMap<String, List<Object>>();
for (String key : hm.keySet()) {
// gets the value
List<Object> value = hm.get(key);
// checks for null value
if (value != null) {
// iterates over String elements of value
for (Object element : value) {
// checks for null
if (element != null) {
// prints whether the key is equal to the String
// representation of that List's element
System.out.println(key.equals(element.toString()));
}
}
}
}
Note I've replaced your WordsStreamed class here with the Object class.
i want to iterate over the values so i can compare my key with all the value
looks like misuse of data structure , generally you should not have to iterate in such scenario and values should be mapped with key
you should enter the values those are logically mapped with keys so while retrieving you won't have to iterate through all they keys and associated values
A more efficient way
for(List<String> valueList : map.values()) {
for(String value : valueList) {
...
}
}
for details click
I have a list gotitems.
ArrayList<String> gotitems = new ArrayList<String>();
i need to put that list in a hashmap called map.
Map<String,String> map = new HashMap<String,String>();
i had tried this :
for(String s:gotitems){
map.put("a",s);
}
gotitems contains :
First
Second
Third
But the output of :
System.out.println(map.values());
gives :
Third
Third
Third
i had even tried this :
for(String s:gotitems){
for(int j=0;j<gotitems.size();j++){
map.put("a"+j,s);
}
}
but this is also not working.
What am i doing wrong here ?
As per Map put(K,V) method docs
Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value.
You are ovverriding the key each time here .
for(String s:gotitems){
map.put("a",s);
}
change the key each time and try like
for(String s:gotitems){
map.put(s,s);
}
This is because you are putting all the items in the map against the same key "a"
map.put("a");
You need to store each element against a unique key so add something like this:
int count = 0;
for(String s:gotitems){
map.put("a" + count,s);
count++;
}
You are trying to put three Strings in the map under the same key "a". Try to use unique keys for your values.
You're putting all your items in the Map with the same key: "a".
You should have a unique String key for each value.
For instance:
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
Map<String, String> map = new LinkedHashMap<String, String>();
for (String s: list) {
map.put(s, s);
}
System.out.println(map);
Output:
{one=one, two=two, three=three}
Note the LinkedHashMap here: it maintains the order in which you put your key/value pairs.
Edit Of course if your List does not have unique values, moving its values as keys to a Map will overwrite some of the Map's values. In that case you want to ensure your List has unique keys first, or maybe use a Map<Integer, String> with the index of the List's value as key to the Map, and the actual List value as value to the Map.
When you write
for(String s:gotitems){
map.put("a",s);
}
you will trash any existing entry in the map held against the key "a". So after your iteration, your map will contain just one entry corresponding to the last iterated value in gotitems.
To use a map effectively you need to consider what your keys will be. Then use map.put(myKeyForThisItem, s) instead. If you don't have an effective scheme for the keys then using a map is pointless as one tends to use the keys to extract the corresponding values.
As for your second approach, it would be helpful if you could define "it is not working" a little clearer: perhaps iterate through the map and print the keys and values.
Please note that in a map, a key can point to at most one value. In your case, you are doing the following mappings:
"a" -> "one"
then you overwrite it as
"a" -> "two"
then you overwrite it as
"a" -> "three"
remember: a key can point to at most one value. However, a value can be pointed at by multiple keys.
This is wrong:
for(String s:gotitems){
map.put("a",s);
}
Since you are using "a" common key for all values, last inserted key-value pair would be preserved, all previous ones would be overridden.
This is also not correct:
for(String s:gotitems){
for(int j=0;j<gotitems.size();j++){
map.put("a"+j,s);
}
}
you are putting n*n times into map, though you want only n (gotitems.size()) items into map.
First decide on key which you want to use in map, copying List into Map one approach could be use index as key:
for(int j=0;j<gotitems.size();j++){
map.put("KEY-"+j,gotitems.get(j));
}
Output should be:
KEY-0 First
KEY-1 Second
KEY-2 Third
I have reproduce your codes. The problem is that you are assigning the same key to different value. This should work.
import java.util.*;
public class testCollection{
public static void main(String[] args){
ArrayList<String> gotitems = new ArrayList<String>();
gotitems.add("First");
gotitems.add("Second");
gotitems.add("Third");
Map<String,String> map = new HashMap<String,String>();
String x = "a";
int i = 1;
for(String s:gotitems){
map.put(x+i,s);
i++;
}
System.out.println(map);
}
}
I'm using Guava's ArrayListMultimap<K,V> collection to map Integers to Strings. The class provides a method called containsValue(Object value) which checks if the Multimap contains the specified value for any key. Once I determine that is true, what's the best way to retrieve said key?
ArrayListMultimap<String, Integer> myMap = ArrayListMultimap.create();
if (myMap.containsValue(new Integer(1))
{
// retrieve the key?
}
Instead of using containsValue you could iterate over myMap.entries() which returns a collection of all key-value pairs. The iterator generated by the returned collection traverses the values for one key, followed by the values of a second key, and so on:
Integer toFind = new Integer(1);
for (Map.Entry<String, Integer> entry: myMap.entries()) {
if (toFind.equals(entry.getValue())) {
// entry.getKey() is the first match
}
}
// handle not found case
If you look at the implementation of containsValue it just iterates over the map's values so the performance of doing this with map.entries() instead of map.values() should be about the same.
public boolean containsValue(#Nullable Object value) {
for (Collection<V> collection : map.values()) {
if (collection.contains(value)) {
return true;
}
}
return false;
}
In the general case of course there isn't necessarily a unique key for a given value so unless you know that in your map each value only occurs against a single key you would need to specify the behaviour e.g. if you wanted the first key or last key.