I am unable to trace through why null pointer exception is thrown here, I am sure it is pretty simple, but somehow I am missing it. It is thrown when the checkoutBook method is called. Any help here?
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class Library {
HashMap<String, List<String>> checkoutBooks;
Library() {
HashMap<String, List<String>> checkoutBooks = new HashMap<String, List<String>>();
}
public void checkoutBook(String isbn, String patron) {
if (checkoutBooks.containsKey(isbn)) {
checkoutBooks.get(isbn).add(patron);
} else {
List<String> patronlist = new ArrayList<String>();
patronlist.add(patron);
checkoutBooks.put(isbn, patronlist);
System.out.println("hello");
}
}
public static void main(String[] args){
Library library = new Library();
library.checkoutBook("000", "Cay Horstman");
library.checkoutBook("000", "Sharron Morrow");
}
}
Because you didn't assign any value to this variable:
HashMap<String, List<String>> checkoutBooks;
You just defined new one in constructor. So remove that instance checkoutBooks variable, or do this:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class Library {
HashMap<String, List<String>> checkoutBooks;
Library() {
checkoutBooks = new HashMap<String, List<String>>();
}
public void checkoutBook(String isbn, String patron) {
if (checkoutBooks.containsKey(isbn)) {
checkoutBooks.get(isbn).add(patron);
} else {
List<String> patronlist = new ArrayList<String>();
patronlist.add(patron);
checkoutBooks.put(isbn, patronlist);
System.out.println("hello");
}
}
public static void main(String[] args){
Library library = new Library();
library.checkoutBook("000", "Cay Horstman");
library.checkoutBook("000", "Sharron Morrow");
}
}
Because you didn't initialize the field checkoutBooks in the constructor. You initialized a local variable with the same name. Change your constructor to this:
HashMap<String, List<String>> checkoutBooks;
Sandbox() {
checkoutBooks = new HashMap<String, List<String>>();
}
In the Library constructor, you declare a local variable named checkoutBooks, and initialize it, but you don't initialize the same-named field at class level. Some suggestions:
At a minimum, to fix the error, change the constructor to do assignment only rather than declaring a new variable:
Library() {
checkoutBooks = new HashMap<String, List<String>>();
}
Since you're not reassigning the checkoutBooks field after construction, you can declare the field final. Then it will catch this sort of error immediately at compile time, because final fields are required to be initialized. It also prevents accidental reassignment of the field later, which enhances robustness.
class Library {
final HashMap<String, List<String>> checkoutBooks;
...
Since you don't do anything else in the constructor, you can inline the initialization directly into the field declaration:
class Library {
final HashMap<String, List<String>> checkoutBooks = new HashMap<String, List<String>>();
// no constructor
...
As of Java 7, you can avoid repeating the type arguments by using <>:
class Library {
final HashMap<String, List<String>> checkoutBooks = new HashMap<>();
checkoutBooks.containsKey
is null when you used HashMap<String, List<String>> checkoutBooks = new HashMap<String, List<String>>(); inside constructor, thats why getting Exception
class Library {
HashMap<String, List<String>> checkoutBooks;
Library() {
checkoutBooks = new HashMap<String, List<String>>(); // just change here
}
public void checkoutBook(String isbn, String patron) {
if (checkoutBooks.containsKey(isbn)) {
checkoutBooks.get(isbn).add(patron);
} else {
List<String> patronlist = new ArrayList<String>();
patronlist.add(patron);
checkoutBooks.put(isbn, patronlist);
System.out.println("hello");
}
}
public static void main(String[] args){
Library library = new Library();
library.checkoutBook("000", "Cay Horstman");
library.checkoutBook("000", "Sharron Morrow");
}
}
Related
public class First {
public final static Map<String, String> MAP = new HashMap<>();
static {
MAP.put("A", "1");
MAP.put("B", "2");
}
}
public class Second {
public static void main(String[] args) {
Class<?> clazz = Class.forName("First");
Field field = clazz.getField("MAP");
Map<String, String> newMap = (HashMap<String, String>) field.get(null); // Obviously doesn't work
}
}
Pretty much it. I have no trouble getting for example values of String variables, but I'm stuck with this one. Tryed to google it, failed. Also, if possible I'd like to get this Map without instantiating its class.
The only thing you are missing is to handle the exceptions for:
Class.forName("First");
clazz.getField("MAP");
field.get(null);
The code below get the static map field from First class. Here I'm just throwing/propagating the exceptions in the main method but you should handle the exceptions in a try/catch block accordingly.
class First {
public final static Map<String, String> MAP = new HashMap<>();
static {
MAP.put("A", "1");
MAP.put("B", "2");
}
}
public class Second {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException,
ClassNotFoundException, NoSuchFieldException, SecurityException {
Class<?> clazz = Class.forName("First");
Field field = clazz.getField("MAP");
Map<String, String> newMap = (HashMap<String, String>) field.get(null); // Obviously doesn't work
System.out.println(newMap); //Prints {A=1, B=2}
}
}
Here the same example with a non static class:
package at.noe.szb;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
public class ReflectionTest {
private class First {
public Map<String, String> MAP = new HashMap<>();
First(){
MAP.put("A", "1");
MAP.put("B", "2");
}
}
#Test
public void testMap() throws Exception {
Class<?> clazz = Class.forName("at.noe.szb.First");
Field field = clazz.getField("MAP");
Map<String, String> newMap = (HashMap<String, String>) field.get(clazz);
assertEquals("{A=1, B=2}", newMap.toString());
}
}
This question already has answers here:
Is Java really passing objects by value? [duplicate]
(6 answers)
Closed 3 years ago.
Main Class --
package test;
import java.util.Map;
public class Client {
private static ArrayList<Class1> allInstances = new ArrayList<Class1>();
private static Map <String, String> var1 = new HashMap<String, String>();
public static void main(String[] args)
{
var1.put("key1","value1");
Class1 instance1 = new Class1(var1);
allInstances.add(instance1);
var1.put("key2","value2");
Class1 instance2 = new Class1(var1);
allInstances.add(instance2);
getInstances();
}
public static void getInstances() {
for(Class1 c: allInstances) {
System.out.println(c.getClassDetails());
}
}
Class Class1 --
package test
import java.util.Map;
public class Class1 {
private Map <String, String> classDetails;
public Class1(Map <String, String> classDetails) {
this.classDetails = classDetails;
}
public Map <String, String> getClassDetails(){
return this.classDetails;
}
}
Output--
{key2=value2}
{key2=value2}
As we can see from the output above, both instances variable returns the same updated value. Should'nt instance1 return {key1=value1}
Also, if this is the expected behavior, what can be done to tackle this issue.
As it is appeared from your code, you referenced same HashMap to instacne1 and instance2 objects and in getClassDetails method the tostring method of same hashmap will invoked so the outputs is the same , use this code snippet :
import java.util.*;
public class Main {
private static ArrayList<Class1> allInstances = new ArrayList<Class1>();
public static void main(String[] args)
{
Map <String, String> var = new HashMap<String, String>();
var.put("key1","value1");
Class1 instance1 = new Class1(var);
allInstances.add(instance1);
var = new HashMap<String, String>();
var.put("key2","value2");
Class1 instance2 = new Class1(var);
allInstances.add(instance2);
getInstances();
}
public static void getInstances() {
for(Class1 c: allInstances)
System.out.println(c.getClassDetails());
}
}
This is my code. My intention is create a hashmap with 4 values, then export this class as a jar, add it to another project, and use the hashmap values there.
I'm getting error in all the "hmap.put". I'm unable to understand what I'm doing wrong. Please help.
import java.util.HashMap;
public class MyFirstClass {
private HashMap<Integer, String> hmap = new HashMap<Integer, String>();
hmap.put(2, "Jane");
hmap.put(4, "John");
hmap.put(3, "Klay");
hmap.put(1, "Deena");
public HashMap<Integer, String> gethmap()
{
return this.hmap;
}
public void sethmap(HashMap hmap)
{
this.hmap = hmap;
}
}
import java.util.HashMap;
public class MyFirstClass {
private HashMap<Integer, String> hmap = new HashMap<Integer, String>() {
{
hmap.put(4, "John");
hmap.put(3, "Klay");
hmap.put(1, "Deena");
}
};
public HashMap<Integer, String> gethmap() {
return this.hmap;
}
public void sethmap(HashMap<Integer, String> hmap) {
this.hmap = hmap;
}
}
Above code will help you to get the result which you desire. You should also note that you can not use instance variable directly inside class. you have to use that inside method only.
Java doesn't allow executing any statements outside of the scope of any method, field initialization or static block - that's why you get an error.
I suppose, your intent is to do some initialization with that four lines. And Java has support for such kind of initialization - it is the class constructor. So the proper code would look like the following:
import java.util.HashMap;
public class MyFirstClass {
private HashMap<Integer, String> hmap = new HashMap<Integer, String>();
// this is a constructor
public MyFirstClass() {
hmap.put(2, "Jane");
hmap.put(4, "John");
hmap.put(3, "Klay");
hmap.put(1, "Deena");
}
// here goes your other code
}
This way every object of MyFirstClass you create using new MyFirstClass() will contain the data you put in the constructor.
You can read more about the constructors in Java in the official documentation: https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
There are multiple ways to do this. Easiest one is to just add brackets to your put statements:
import java.util.HashMap;
public class MyFirstClass {
private HashMap<Integer, String> hmap = new HashMap<Integer, String>();
{
hmap.put(2, "Jane");
hmap.put(4, "John");
hmap.put(3, "Klay");
hmap.put(1, "Deena");
}
public HashMap<Integer, String> gethmap() {
return this.hmap;
}
public void sethmap(HashMap hmap) {
this.hmap = hmap;
}
}
You should add a constructor to your class:
public MyFirstClass() {
this.hmap = new HashMap<Integer,String>();
// you can do .put here if you wish
}
And change the hmap field to:
private HashMap<Integer, String> hmap;
You're using a method outside of a method. You cannot call Hashmap.put within the class but outside the method - as was mentioned you want to do that in the constructor of the class
public class MyFirstClass {
public MyFirstClass() { //put it here }
}
You can put it in a static block, just as:
private static final Map<Integer, String> NAME_MAP = new HashMap<Integer, String>() {
private static final long serialVersionUID = 1L;
{
NAME_MAP.put(2, "Jane");
NAME_MAP.put(4, "John");
NAME_MAP.put(3, "Klay");
NAME_MAP.put(1, "Deena");
}
};
This question already has answers here:
Why are my fields initialized to null or to the default value of zero when I've declared and initialized them in my class' constructor?
(4 answers)
Closed 6 years ago.
I am a beginner with Java .. & I keep getting this error .. java.lang.NullPointerException pointing to this line --> Double hOption = healthBenDesig.get("employeeOnly");
Can someone tell me if i am missing something or what exactly I am doing wrong please?
private HashMap<String, Double> healthBenDesig;
public VariableList()
{
HashMap<String, Double> healthBenDesig = new HashMap<String, Double>();
}
public VariableList()
{
HashMap<String, Double> healthBenDesig = new HashMap<String, Double>();
}
public void getHMP()
{
Double hOption = healthBenDesig.get("employeeOnly");
System.out.println("The health Option you chose is: " + hOption);
}
public HashMap setHealthOpt()
{
healthBenDesig.put("none", 0.00);
healthBenDesig.put("employeeOnly", 311.87);
healthBenDesig.put("spouse", 592.56);
healthBenDesig.put("children", 717.30);
healthBenDesig.put("kids", 882.60);
System.out.println(healthBenDesig);
return healthBenDesig;
}
You're shadowing the healthBenDesig by re-declaring it in your constructors leaving the class field null. Don't re-declare it.
Change
public VariableList() {
HashMap<String, Double> healthBenDesig = new HashMap<String, Double>();
}
to:
public VariableList() {
healthBenDesig = new HashMap<String, Double>();
}
You are not intializing your class member healthBenDesig instead you are shadowing it using the lcoal variable. This is causing healthBenDesig as un-initialized and leading to NullPointerException. your In your constructor, change it from
public VariableList()
{
// re-declaration or shadowing of memeber variable healthBenDesig
HashMap<String, Double> healthBenDesig = new HashMap<String, Double>();
}
to
public VariableList()
{
healthBenDesig = new HashMap<String, Double>();
}
You are able to initialize healthBenDesig at property declare
private HashMap<String, Double> healthBenDesig = new HashMap<String, Double>();
I have multiple classes in my program, and I'm trying to find a way to use some methods in one of my other classes. Normally I would just do:
Class obj = new Class();
but that creates a new Instance of it and since I'm using HashMaps, that doesn't work because it creates a new map. I want it to use the same HashMap with stuff already saved in it. What is the best way of doing this?
Edit: Heres an example of the code I'm talking about:
Class #1:
public class Foo{
HashMap<String,Integer> hashmap = new HashMap<String,Integer();
hashmap.put("something", 1);
}
Class #2:
public class Foo2{
Foo f = new Foo();
f.get("something");
}
and nothing shows up for f.get because I created a new version of it...could somebody correct this code for me so I can see what you guys are talking about?
You need to share object references
public class Main {
public static class Foo{
Map<String, Integer> map;
public Foo(Map<String, Integer> map) {
this.map = map; // don't create a new object,
// use one that already exists that can be passed as an argument
}
public void put(String key, Integer value) {
map.put(key, value);
}
public Integer get(String key) {
return map.get(key);
}
}
public static void main(String[] args) {
Map<String, Integer> someMap = new HashMap<>();
someMap.put("aKey", 42);
Foo foo = new Foo(someMap); // the Foo object now references the map you just created
System.out.println(foo.get("aKey")); // prints 42
}
}
Here, you create a Map and pass a copy of its reference as an argument to your class' constructor. Your class saves this reference and uses it to access the same object.
When sharing objects, it's important to know what you are doing so that updates aren't lost/overwritten.
This is also another possible way to do. Extend hashmap and make the class as singleton.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
class ExtHashMap<K,V> extends HashMap<Object,Object> {
private static HashMap<?, ?> map;
public static HashMap<?, ?> getInstance() {
if (map == null) {
map = new HashMap<Object,Object>();
}
return map;
}
private ExtHashMap() {
super();
}
}
public class SampleUtil {
/**
* #param args
*/
public static void main(String args[]) throws Exception {
HashMap map = ExtHashMap.getInstance();
map.put("1", "v1");
HashMap map1 = ExtHashMap.getInstance();
map1.put("2", "v2");
System.out.println(map1.values());
}
}