-1

OK, I rewrote my class,I rushed so the code is not clean yet anyway now it comipiles, and running mainMethod the problem is still there.

   import java.util.*;


   public class myClass {

            public Random myRandom;
            public HashMap<String, ArrayList<String>> myMap;
            public ArrayList<String> ar;
            public ArrayList<String> nexts;
        //     ArrayList<String> follows;
            public myClass(){
                myRandom = new Random();       
            }


            public void setRandom(int seed){
                myRandom = new Random(seed);

            }
            public HashMap<String, ArrayList<String>> buildHashMap(){
              HashMap<String, ArrayList<String>> myMap = new HashMap<String, ArrayList<String>>();
              ArrayList<String> ar = new ArrayList<String>();
              ar.add("2");
              ar.add("2");
             String test = "test";
             String anothertest = "anothertest";
              myMap.put(test, ar);
              myMap.put(anothertest, ar);

              return myMap;  
            }
            public ArrayList<String> arrayListGetter(String st){
                System.out.println("++++++++++++++++++++++++++++++++++");
                  System.out.println(myMap.size());
                ArrayList ar = myMap.get(st);

            return ar;  
        }

            public void mainMethod(){
                HashMap<String, ArrayList<String>> myMap = new HashMap<String, ArrayList<String>>();
                myMap = buildHashMap();
                System.out.println("\n\nNumber of keys found: " + myMap.size()); 
                for (String st : myMap.keySet()){
                System.out.println(st + ": ");
                ArrayList<String> al = myMap.get(st);

                    System.out.println(al.size());

                     }

                StringBuilder sb = new StringBuilder();
                String test = "test";
                System.out.println(myMap.get(test));

                System.out.println(sb);  
                System.out.println(myMap.get(test).size());
                System.out.println(myMap.get(test).size());
        //         ArrayList<String> follows = getFollows(key);
                System.out.println("something");
               int  index = myRandom.nextInt(myMap.get(test).size());
                System.out.println(index);
        //         index = myRandom.nextInt(follows.size());
                String next = myMap.get("test").get(index);
                sb.append(next);
                System.out.println(sb);  
                System.out.println(myMap.get("test").getClass());
                ArrayList<String> follows = new ArrayList<String>();<------new empty ArrayList
                System.out.println(follows.size() + " **********");
                ArrayList<String> nexts = new ArrayList<String>();
                nexts = arrayListGetter ("test");




            }
            }

Am I missing something obvious? Thanks in advance for your time and patience.

  • 2
    `"I think you can safely assume that this has been built and populated properly through a separate method called in the main function"` -- until you've debugged your error, you can't "safely assume" **anything**. Seriously. – Hovercraft Full Of Eels Jan 24 '16 at 22:04
  • 1
    "_I think you can safely assume_". Nope. Given the error, I would say that that is exactly _not_ the case... – Boris the Spider Jan 24 '16 at 22:06
  • 1
    You will want to show us a decent [mcve] because no one can or should safely assume anything until we can actually test the code. – Hovercraft Full Of Eels Jan 24 '16 at 22:06
  • 1
    Further, this code doesn't even **compile**. – Boris the Spider Jan 24 '16 at 22:07
  • Well, I said that you can almost safely assume that my HashMap has been built because I have tested it and printed out all the keys and values. Besides if I call System.out.println(myMap.get(key)) I have a value returned. Anyway generally I agree that one should always be wary of assuming anything. – Gianni Errera Jan 24 '16 at 22:10
  • 2
    Regardless, an [mcve] or it didn't happen. – Hovercraft Full Of Eels Jan 24 '16 at 22:13
  • Boris, I didn't include all the class as this is an assignment for a course, my class does compile but I wrote down some examples of the methods, how they work and what they are supposed to return. – Gianni Errera Jan 24 '16 at 22:15
  • 2
    The facts stand: 1) The question is completely unanswerable in its present state as no one can guess what is wrong in code not shown. 2) Many of us are showing extreme restraint by not closing this yet as "yet another NPE question", so many are assuming that there may be some value yet in the question. 3) But we won't know until we see your [mcve]. This is not a complete code dump or a link, but a new small program that you can post here in its entirety, that we can run unmodified and that shows us your error. It's either this or close I think. – Hovercraft Full Of Eels Jan 24 '16 at 22:17
  • @ Hovercraft Full Of Eels 2, I would be glad to copy and paste all my code, but it is part of an assignment for a Java course on Coursera and I don't know whether I would break any rules. I'm sorry but I am sure you'll understannd my concern, of course you can lock the thread if you think this is the case, and thank you for your replies all the same, sorry for my noobness. – Gianni Errera Jan 24 '16 at 22:18
  • Ok, I'll try and rework my code to get a minimal working method, but I will have to rewrite it as the custom obect is another class and implements an interface. – Gianni Errera Jan 24 '16 at 22:23
  • 1
    Prediction: once you successfully do this, create your [mcve], you will at that time see your error yourself and be able to fix it. – Hovercraft Full Of Eels Jan 24 '16 at 22:28
  • Here, I have rewritten my class in order to compile it and run it, in fact the problem is still there. – Gianni Errera Jan 24 '16 at 23:03
  • Sorry if my class is badly formatted, anyway I have tested it, it compiles and when I run mainMethod it prints the keys and values of myMap but I get still a null pointer exception after the line arrayListGetter("test"); – Gianni Errera Jan 24 '16 at 23:11
  • 1
    yep, you're shadowing the myMap variable. Don't do this. And the main lesson is -- don't assume anything until you've debugged your code since your assumption was completely off base. – Hovercraft Full Of Eels Jan 24 '16 at 23:16

1 Answers1

1

You're shadowing the myMap variable by re-declaring it in a method and leaving the field null.

import java.util.*;

public class MyClass2 {
    public HashMap<String, ArrayList<String>> myMap;  // this guy is null

    // ArrayList<String> follows;
    public HashMap<String, ArrayList<String>> buildHashMap() {
        HashMap<String, ArrayList<String>> myMap = new HashMap<String, ArrayList<String>>();
        return myMap;
    }

    public ArrayList<String> arrayListGetter(String st) {
        System.out.println("++++++++++++++++++++++++++++++++++");
        System.out.println(myMap.size());
        ArrayList ar = myMap.get(st);
        return ar;
    }

    public void mainMethod() {
        // this myMap is a local variable, and assigning it anything
        // will leave the class field null
        HashMap<String, ArrayList<String>> myMap = new HashMap<String, ArrayList<String>>();
        myMap = buildHashMap();  // the field in the class is still null!!!
        System.out.println("\n\nNumber of keys found: " + myMap.size());
        for (String st : myMap.keySet()) {
            System.out.println(st + ": ");
            ArrayList<String> al = myMap.get(st);

            System.out.println(al.size());

        }

        // this throws a NPE
        ArrayList<String> someMap =  arrayListGetter("test");
    }
}

Meaning you're initializing a HashMap that you've declared local to some method. Yes you've given it the same name, myMap, as the field in the class, but by declaring it local to the method, the variable is visible in that method only, and the field in the class remains null.

Solution: don't do this, don't give local fields the same name as fields, and don't re-declare variables in a local scope if you mean to assign to a field in the class.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Thank you very much for your reply!!! In fact I see that myMap is local - to be honest I have tried too hard and right now I haven't digested yet everything of your post. PReviously I have tested a lot of similar classes using the same approach of declaring variables as "global" and then create new instances with the same name, and it has always worked. Now I think I'll try and call my HashMap builder in the constructor of the class, hopefully myMap will be visible from all the methods of the class. – Gianni Errera Jan 24 '16 at 23:33
  • Now I have read your message again with the commented code and now I see more clearly the problem, incidentally I have previously written similar methods with HashMaps initialized locally and I got away with my faulty code; the solution I can think of to fix this at the moment is to initialize my HashMap in the Constructor method, but now that I have changed the code it doesn't compile anymore, when it rains it pours....well, I suppose I should sleep on it and continue tomorrow instead of burning the midnight oil and trying too hard. Thank you again for your patience and support!!! – Gianni Errera Jan 25 '16 at 00:00
  • While I don't think this is the best and more efficient solution, I have found some way to work around the problem and for the time being it seems to do the trick. In my main method I just wrote something like HashMap map = buildHashMap(); and then myMap = map;, now main method doesn't throw the null pointer exception anymore! – Gianni Errera Jan 25 '16 at 00:26