How to check the content from a Map? - java

I have a Problem with a Map in Java.
The Code looks like this:
Map<Object, Object> test = myClass.getMap();
int value = (int) test.get(myID);
When I reach the second line I get a:
java.lang.NullPointerException
Now I'm asking myself how to debug this and find yout why this is not working? I'm quite sure that all keys and values are in this map.
How to print out the whole map so I can search if the key is available? (Its a very long map)
Or what is the right way to find the problem?

you can do map.containsKey(key) to check if the key exists
The reason for NPE, is that the value for myId in the map was null and you are trying to convert it to primitive int (which cannot hold non null values). Changing it to below statement will avoid the exception (unless the map test itself is null)
Integer value = (Integer ) test.get(myID);

Multiple problems here :
Map test could be null.
You cannot cast from Object to int. You need to cast it to Integer.
I believe the below line shouldn't compile:
int value = (int) test.get(myID);
as get() returns Object , and you are trying to cast it to primitive int. Even if you cast it to Integer :
int value = (Integer) test.get(myID); // assume auto-unwrapping here
The above code will throw NPE , if get(myID); is null.
You need to use :
Integer value = (Integer) test.get(myID);
You can use test.containsKey(myID) , to check for key. Finally do something like this :
if(test!=null && test.containsKey(myID))
Integer value = (Integer) test.get(myID);
You should use Generics in your Map though.

Use an IDE with an integrated debugger: put a breakpoint somewhere after the map was instantiated and after it was initialized and see effectively what's inside the map.

Well to answer you'r question if you want to print the map:
for (Entry<Object, Object> entry : test.entrySet()) {
System.out.println("Key:" + entry.getKey() + " Value:" + entry.getValue());
}
However the containsKey() method should be probably what you rather need.

Related

Difference between map.replace() and map.put() for updating a value in Map in Collection Framework [duplicate]

I want to make a histogram by using a HashMap, the key should be the delay, the value the amount of times this delay occurs. I am doubting to use the HashMap replace or the HashMap put function if an already existing delay has an new occurence. I did it by this way:
int delay = (int) (loopcount-packetServed.getArrivalTime());
if(histogramType1.containsKey(delay)) {
histogramType1.replace(delay, histogramType1.get(delay) + 1);
} else {
histogramType1.put(delay, 1);
}
Is this correct? or should I use two times the put function?
There is absolutely no difference in put and replace when there is a current mapping for the wanted key. From replace:
Replaces the entry for the specified key only if it is currently mapped to some value.
This means that if there is already a mapping for the given key, both put and replace will update the map in the same way. Both will also return the previous value associated with the key. However, if there is no mapping for that key, then replace will be a no-op (will do nothing) whereas put will still update the map.
Starting with Java 8, note that you can just use
histogramType1.merge(delay, 1, Integer::sum);
This will take care of every condition. From merge:
If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. Otherwise, replaces the associated value with the results of the given remapping function, or removes if the result is null.
In this case, we are creating the entry delay -> 1 if the entry didn't exist. If it did exist, it is updated by incrementing the value by 1.
In your case, since you first check if the value is contained in the map, using put or replace leads to the same result.
You can use either, based on what is more readable to you.
If you look at the sources you can see the following (this is from update 11 but probably hasn't changed much):
replace:
if ((e = getNode(hash(key), key)) != null) {
V oldValue = e.value;
e.value = value;
afterNodeAccess(e);
return oldValue;
}
put (internal method putVal):
//some code before this to find the node e (similar to getNode(hash(key)))
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null) //onlyIfAbsent is false here
e.value = value;
afterNodeAccess(e);
return oldValue;
}
As you can see, the relevant parts of the code do basically the same thing since onlyIfAbsent is false for put and thus always will replace the value.
You can verify the behavior the others have described, with this:
public class Main {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.replace("a", "1");
System.out.println(map.get("a"));
map.put("a", "1");
System.out.println(map.get("a"));
map.replace("a", "2");
System.out.println(map.get("a"));
}
}

What's the type of *the* element in a Set?

I have this code:
for(GlCapabs_e capName : capabs.keySet()){
x = capName.get();
}
where GlCapabs_e is an enum and capabs is an EnumMap<GlCapabs_e, Boolean>. But GlCapabs_e type up there is wrong, as I can't use get() on capName; it can't be a constant, it has to be a type to support get() so to return the value of the key.
I've read somewhere in Java documentation (I can't find it anymore) that a "special" type exists like elementOf, itemOf or something alike but googling them didn't return anything pertaining my matter. And above this I'm not sure whether it's this type that I'm supposed to use.
You're iterating over the keySet. If you want to get the value mapped to each key in the key set, use the EnumMap to retrieve the value
for(GlCapabs_e capName : capabs.keySet()){
x = capabs.get(capName);
}
Or iterate over the entrySet
for (Entry<GlCapabs_e, Boolean> entry : capabs.entrySet()) {
x = entry.getValue(); // the entry holds both the key and the mapped value
}
Remember, EnumMap is an implementation of Map, it therefore inherits/implements all of its methods.

Iterating over the map and calling another method

I am getting an map as shown below inside a method
Map<Integer, Integer> result1 =jmxService.generateMabc(p1, p2,p3,p4);
now the map result 1 will consists oif key value pair as usal
now i want to iterate over the map one by one , fetch the value of the map
that is both key and value which will be of type integer and convert them into string
and store the string two string variables like shown below
string j = will store the key
string t = will store the value
amd then pass these two parameters to another method call which wil take string
j and string t as parameter once they pass i want j and t to be null so that in next iteration the same process and can be continued till the time map has value c an you please advise how to achieve this, what I have tried is..
for (Map.Entry<Integer, Integer> entry : result1.entrySet())
{
String j, t;
j=entry.getKey();
t= entry.getValue();
abc .callanothermethod(string p1,stringp2, stringj, string t)
j=null;
t=null;
}
please advise what will be the correct appoach to obtain the same.
An Integer is not a String. So j = entry.getKey() doesn't make sense.
You need to transform the Integer into a String (by calling toString() for example):
j = entry.getKey().toString();
You really need to learn to
read the error messages from the compiler, which tell you waht is wrong and where
read the javadoc of the classes you're using, to understand what you can do with them.

HashMap get(Object) always returns String instead of other Object

Having an issue that is just stumping me. I have a HashMap declared to use a String as the Key and my own KWIKattribute as the Value.
private HashMap<String, KWIKattribute> attributes = new HashMap<String, KWIKattribute>();
I put objects into it, where sgml_xml_tag is a String and kattr is an instance of KWIKattribute.
attributes.put(sgml_xml_tag, kattr);
When I try to get the value back out as a KWIKattribute
for (Map.Entry<String, KWIKattribute> e : attributes.entrySet()) {
String key = e.getKey();
KWIKattribute kattr = (KWIKattribute) attributes.get(e.getKey());
}
an exception is thrown
javax.faces.el.EvaluationException: java.lang.ClassCastException: java.lang.String cannot be cast to com.northgrum.adt.kwik.model.KWIKattribute
I know this is probably a simple stupid error on my part somewhere, but I'm not seeing what it is. Any suggestions?
Instead of
KWIKattribute kattr = (KWIKattribute) attributes.get(e.getKey());
use
KWIKattribute kattr = e.getValue();
You are iterating over the entry set of the map. Each entry contains a key and the value associated with that key in the map. You can get the value from the entry directly; it's not necessary to look it up in the map, as you are doing.
That said, it's strange that you get this error. First of all, the cast to KWIKattribute shouldn't be necessary at all. Second, if attributes is really a HashMap<String, KWIKattribute>, it's impossible that there are String objects stored in it as values.
The Map.Entry-class, which you use to iterate over the entry-set of your Map has a getValue()-method, which returns the value to the current key.
Otherwise, if you're only interested in the values from the Map, you can also iterate over the values-collection:
for (KWIKattribute attr : attributes.values()){
// Do your work with attr
}

What is inside an empty index of a Hashmap?

I have a hashmap that is 101 keys in size, but I know for sure about 6 of those have no data inside, and there may be more without data as well. What exactly is inside the empty indexes? Is it null? or is there a Hash(index).isEmpty() method that I can use to see if its empty?
I realize there is a isEmpty method inside hashmap, but I thought that only checked if the entire map was empty not just a single index.
I realize there is a isEmpty method
inside hashmap, but I thought that
only checked if the entire map was
empty not just a single index.
I think what you're looking for is the containsKey(Object) method. According to the documentation:
Returns true if this map contains a
mapping for the specified key. More
formally, returns true if and only if
this map contains a mapping for a key
k such that (key==null ? k==null :
key.equals(k)). (There can be at most
one such mapping.)
Parameters:
key - key whose presence in this map is to be tested
Returns:
true if this map contains a mapping for the specified key
Well, for the keys to arrive there with no data, you have to put them there.
If you did map.put(key, null) then yes the data for that key is null. You always have to give the second parameter to the method, you can't just map.put(key).
If you know for sure that a certain key should have no data you could try going into debug mode and putting a watch for myMap.get(myEmptyKey) and see what you get (in case that no data is an empty object or something else, you should be able to see that).
Edit: Some code would be useful to help you, but if I understand correctly you do something like this:
for (Object obj : list) {
if (matchesCriteriaX(obj)) {
map.put("X", obj);
else if (matchesCriteriaY(obj)) {
map.put("Y", obj);
}
}
Well, if you do that and try to do map.get("X"), but you never actually put anything for that key (becaus no object matched criteria X), you will most definitely get back a null.
On the other hand, if you did something like
Map<String, List<Object>> map = new HashMap<String, List<Object>>();
map.add("X", new ArrayList<Object>());
map.add("Y", new ArrayList<Object>());
for (Object obj : list) {
if (matchesCriteriaX(obj)) {
List<Object> list = map.get("X");
list.add(obj);
else if (matchesCriteriaY(obj)) {
List<Object> list = map.get("Y");
list.add(obj);
}
}
then you could check if a category is empty by doing map.get("x").isEmpty() since List has that method (and it would be empty if no object matched the key criteria).
Judging from what you said, I'm suspecting something like this:
Map<SomeKey, List<SomeValue>> yourMap;
If this is the case, what you can do is
if( yourMap.contains(someKey) ){
List<SomeValue> someList = yourMap.get(someKey);
if(someList.size() == 0){
// it's empty, do something?
}
}

Categories