I want to carry a HashMap over as a static member for each instance of a new class. Every time I try to .get or.put into my HashMap, however, I get a NullPointerException. Help!?
I'm doing: public class EmailAccount {
private static HashMap<String,Integer> name_list; and then name_list.put(last_name, occurences); Even name_list.containsKey(last_name); returns NullPointer.
This comes from an earlier question: Count occurrences of strings in Java
You need to instantiate it.
private static Map<String, Integer> name_list = new HashMap<String, Integer>();
See also:
Java tutorial - Creating objects
Java collections tutorial - The Map interface
Note that using "list" in variable name of a map is confusing. Don't you want it to be a name_map or name_occurences? That underscore does by the way also not really fit in Java naming conventions, but that aside.
You still need to initialize it, like
private static HashMap<String, Integer> name_list = new HashMap<String, Integer>();
When you leave a class-level object field with no initialization -- or any object reference, for that matter, it defaults to null.
While it may seem obvious to you that you want a HashMap, so it should just implicitly initialize it, Java doesn't know if you want in fact a HashMap, or maybe a HashMap subclass, like LinkedHashMap
Class-level primitives, like int can be left just like private static int someNumber; and won't throw a NullPointerException by accessing it--but that's because primitives can't be null. Java will assign it some default value (in int's case, 0).
You didn't instantiate the list. You declared it, but didn't instantiate.
You created a field that can hold a HashMap, but you didn't put anything inside of it
You need to put a new HashMap<String, Integer>() into your field.
Related
I know the basic that a HasMap is a Key-Value pair but I want to have a HashMap with keys only(No Values)
I want to put below java snippet in my complex method(i.e HashMap with only Keys and no value associated to those Keys). My requirement is that i am processing a List of Duplicate Records, and during comparisons, I am keeping only one identifier value(from group of duplicates) in a HasMap which I can later compare that whether the system has already processed it or not.
Here is the code snippet(gives Compile time error as Void class is uninstantiable).
Map<Integer,Void> map=new HashMap<Integer, Void>();
//Some Logic goes here
map.put("ss",new Void());
Any suggestion/help to have a HasMap only Keys with no value are welcome.
Normally you would use a Set for such an issue, because there is no need to have a Key-Value structure when not using the value at all.
Correct Solution
Set<String> uniqueValues = new HashSet<String>();
uniqueValues.add( "a" );
uniqueValues.add( "a" );
assert uniqueValues.size() == 1;
Note this is just for completeness I would always use a Set for your requirement and the rest is more for fun/learning/confuse people:
Since Void has a private constructor so you can not create an instance with the new Keyword.
However there are at least two possibilities to put something in your Map.
Solution one is to add null as value. Because you do not need it anyway. And the second one would use reflection to ignore the private constructor of the Void class.
HACK SOLUTION
Map<String, Void> map = new HashMap<String,Void>();
Constructor<Void> constructor= (Constructor<Void>) Void.class.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Void voidObj = constructor.newInstance();
map.put( "a", voidObj );
map.put( "a", voidObj );
assert map.size() == 1;
If I understand correctly you want a list where you can add keys but it should not allow to add duplicate keys. Then the solution is to use a Set(Oracle Documentation):
Set<Integer> mySet = new TreeSet<Integer>();
Java also provides a Hashset(Oracle Documentation)
Set<Integer> mySet = new HashSet<Integer>();
You may also need you own Comparator.
Why not just use another list? If you really need to use a HashMap for whatever reason, you can just add null values instead of void.
Map<Integer,Object> map=new HashMap<Integer, Object>();
map.put("ss", null);
Please do not do this. A HashMap is a Map which is a Key-Value-pair. A Map without values is not a Map.
If you want to store values without duplicates use a Set - a HashSet for example.
First of all the constructor of Void class is private, so the compiler will mark new Void() as error. Next, to prevent duplicates, you could just use a Set . Why not go with HashSet?.
Here's what javadoc says about Void -->
The Void class is an uninstantiable placeholder class to hold a
reference to the Class object representing the Java keyword void.
why we can change a hashMap which is declared as blank final, but we cannot change a primitive type?
for example
if I create a map
final Map<String, String> someMap;
and initialize it in constructor, and still I can put values in this. But same is not the case with primitive
final int a;
I cant change the value of a in this case. can somebody explain this ?
final means it cannot be changed once initialized. You are just declaring the variable but not initializing it, hence it is allowed.
So doing this is valid
final Map<String, String> someMap;
someMap = new HashMap<String, String>();
But if you try to assign another value to it post initialization then compiler should throw an error that final variable is already intialized:
final Map<String, String> someMap;
someMap = new HashMap<String, String>();
someMap = new TreeMap<String, String>(); //error here
Note: Also putting/removing values in hashmap does not change the reference of the final variable.
It is just the reference to the map (i.e. the variable someMap) which cannot be changed. The map itself can be changed. You can for example insert values. But you cannot assign a new map to someMap.
When using the final keyword on variables you are saying that the variable can be defined only once. In other words once a value has been assigned to the variable, it cannot be reassigned.
This yields obvious behavior with primitive types but is less obvious with objects. Importantly though when inserting values into a map, the object instance remains the same. This is important to remember when passing objects to methods, and really important when using get/set/clone methods as you may end up with multiple references to the same object, where a change in one place (insert entry into map) may have undefined effects in others.
If the Map in your question is important you can use java.util.Collections.unmodifiableMap(m); to stop people fiddling with it.
*emphasized text*When you write:
final Map<String, String> someMap;
it's important to realise that someMap is a reference, and you're declaring the reference to be final. The actual object is not immutable, but the reference is. Hence you can't change the reference i.e. you can't do:
someMap = anotherMap;
later on.
Within my java application I have a hashmap that holds a string and an Integer. I'm in a situation where I need to return an object where the key is a certain value. I'm not sure how I would go about doing this. Your support would be greatly appreciated.
public HashMap<String, Integer> loginArenaList = new HashMap();
You need Map#get(Object) method:
loginArenaList.get(key);
BTW, your declaration of map is wrong. You are missing generics type on RHS. And of course, you should declare the reference as private, unless you have strong reasons to use public. Should be:
private Map<String, Integer> loginArenaList = new HashMap<>(); // In Java 7
According to the declared map, your keys are of type String and the object to be retrieved is of type Integer. Assuming that you have the key in the variable "key", all you have to do is use the get method.
loginArenaList.get(key);
i want to create an LinkedList of couple that the key is a String and the value is an integer ?
LinkedList doesn't have a key. It's a list of elements, not a key/value mapping.
If you want a LinkedList where each element is a pair of Integer/String values, you'll need to pick one of:
Create a generic Pair class
(Ab)use an existing generic class (e.g. Map.Entry)
Create a custom class for your specific scenario
I would suggest the last option as the most sensible one - you'll be able to give it appropriate semantics and names according to the real meaning of the string and the integer. Heck, you'll also be able to avoid boxing the integer, as you can have:
public class WhateverYouCallIt {
private final int firstValue;
private final String secondValue;
// Constructor, properties
}
You can only use Object in a LinkedList., this means you cant use Java Primitives.
However, what you seem to need is a Map structure.
I recommend using java.util.HashMap, it allows you to create a Key, Value pairs.
Example:
HashMap<String,Integer> a = new HashMap<String,Integer>();
a.put("one",1);
a.put("two",2);
System.out.println(a.get("one"));
//prints 1
System.out.println(a.get("two"));
//prints 2
EDIT:
As per your comment, i see you required order, use the following example then:
LinkedHashMap<String, Integer> b = new LinkedHashMap<String,Integer>();
b.put("one",1);
b.put("two",2);
b.put("a",3);
for (String key:b.keySet())
{
System.out.println(b.get(key)); // print 1 then 2 finally 3
}
Hope this is what you were asking (if so, modify your question).
One error is you need Integer instead of int, but as others have pointed out LinkedList doesn't take Key/Value pairs.
I'd imagine a HashMap is what your after. As other have stated, you cannot use a primitive type such as "int" in a library storage class like LinkedList, or ArrayList, you must instead use an object such as "Integer".
HashMap hash = new HashMap();
Read this for more information: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html
I have a need to store a list of dynamically created objects in a way where they can all be retrieved and their methods called on demand.
As far as I can see for the list and creation, a HashMap fits my needs but i'm a bit puzzled on recalling the objects and calling their methods using the HashMap.
Just as a reference, let me give you a little code:
Here is the HashMap:
Map<String, Object> unitMap = new HashMap<String, Object>();
// here is how I put an object in the Map notice i'm passing coordinates to the constructor:
unitMap.put("1", new Worker(240, 240));
unitMap.put("2", new Worker(240, 240));
Now I need to create a method that retrieves every object in the hashmap and call a method from each object. is this possible or can the created objects only be referenced directly. If so, is there another way to call a method of all existing instances of a class dynamically (in other words, on user input)?
Sure. You can do this:
for (Object thing : unitMap.values()) {
// use "thing" here
}
If you need the keys too, you can either get just the keys:
for (String key : unitMap.keySet()) {
// use "key" here
}
or both the keys and values together:
for (Map.Entry<String, Object> entry : unitMap.entrySet()) {
// use "entry.getKey()" and "entry.getValue()"
}
In all the above cases, each entry in the map is traversed one by one. So at the end of the loop, you'll have processed all the entries in the map.
If all of the values in the Map are Worker objects, you should declare your map to be of type Map<String, Worker>. This way, when you pull a value out of the map, it will be typed as a Worker. This way you can call any method declared on Worker as opposed to having to check the type at runtime using instanceof.
If the map holds different values, and you need to keep the value type as Object, it may be advantageous to use an interface to define the method that you want to call for each different object type.
If you do not know what method you want to run on the values until runtime, and the map can hold different values, you will just have to do what you are currently doing, and use Map<String, Object>.
Finally, to get the values of the map, you do just as Chris Jester-Young mentioned before me. The biggest advantage, as I said previously, is that your objects will be typed, and you will have no need for casting/instanceof checking.
I use this to put all values from hashMap on a List, hope it helps.
private List<String> getValuesFromHashMap(HashMap<String, String> hashMap) {
List<String> values = new ArrayList<String>();
for (String item : hashMap.values()) {
values.add(item);
}
return values;
}