2

I have been working with java just a little, but there is these small logic things that I seem to never understand and I'll give an example right away. I currently have this code:

class test {

public static void main(String[] args) {
    ST<String, Integer> st;
    st = new ST<String, Integer>();

    for (int i = 0; !StdIn.isEmpty(); i++) {
        String key = StdIn.readString();
        st.put(key, i);
    }

    st.put("P", 5); // Put method

    for (String s : st.keys()) {
        StdOut.println(s + " " + st.get(s));
    }

  }
}

So what it does is that it creates a Symbol Table and inserts some data to it from a file provided. As you can see, I have a put method which inserts the value 5 on key "P". I want to create a method for this just for the sake of practice. So what I do is:

public static void addValue() {
    st.put("P", 5);
}

and call that method instead of the "put" method in my code. However I can't compile this, since the method "addValue" doesn't know the variable st.

I then thought to put these two lines:

ST<String, Integer> st;
st = new ST<String, Integer>();

into the class constructor, but that didn't make it. Can someone please explain some logic behind this because theres clearly something I'm missing. How can I split this code into methods in a nice way just for the sake of practice? + If anyone knows of a good place to just read about logic like this, I'll be enourmously appreciated.

Thanks in advance.

6
  • Start by reading about variable scope: java-made-easy.com/variable-scope.html Commented Jul 11, 2014 at 22:49
  • you need to add the method addValue() to the ST class. Then, you can simply call this.put("P", 5); inside addValue(..) instead of st.put(..); - also, in the main method, you can do ST.addValue(); to invoke it - OR pass it as a variable like @DavidZhou indicates below :) Commented Jul 11, 2014 at 22:50
  • You need a static field. Currently you only have variables within methods Commented Jul 11, 2014 at 22:50
  • 2
    Just pass it via parameters public static void addValue(ST st), and call it like addValue(st) Commented Jul 11, 2014 at 22:50
  • Thanks all, the ST class is from a library that I have no control over btw Commented Jul 11, 2014 at 22:53

3 Answers 3

2

The variable st is only known to the main method because you declared it there. To allow access from other methods you should create a class member. Here is the class that should do what you want:

class test {

    private static ST<String, Integer> st;

    public static void main(String[] args) {
        st = new ST<String, Integer>();

        for (int i = 0; !StdIn.isEmpty(); i++) {
            String key = StdIn.readString();
            st.put(key, i);
        }

        addValue();

        for (String s : st.keys()) {
            StdOut.println(s + " " + st.get(s));
        }

    }

    public static void addValue() {
        st.put("P", 5);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

That is a really good point, this is something I am looking for as well. I have now tried different kind of way to achieve what I want and it's a really great way to learn the logic. Thanks!
oh and btw, in order for this to help, the private field "ST" has to be static. I am not sure why though?
In order to access a class variable inside a static method, this variable has to be static as well. This means there is only one "version" of this variable for all instances of this class. If for example object A adds an entry into st then object B can "see" this. To avoid a static variable you should pass necessary variables as a method argument like David Zhou suggested.
2

You can either add it as a class member

class test {

    private static ST<String, Integer> st;

    public static void main(String[] args) {
         st = new ST<String, Integer>();

        for (int i = 0; !StdIn.isEmpty(); i++) {
            String key = StdIn.readString();
            st.put(key, i);
        }

        addValue();

        for (String s : st.keys()) {
            StdOut.println(s + " " + st.get(s));
        }

    }

    public static void addValue() {
        st.put("P", 5);
    }
}

or pass it in as a variable

public static void addValue(ST<String, Integer> st) {
    st.put("P", 5);
}

Then from your main method you can just call

addValue(st);

Comments

1

There are a couple of issues here.

  1. Class names should be upper case, in this case Test (convention)
  2. The class with the main method should be public (convention)
  3. ST is not part of Java (in your comments you write its part of a library, this information should be part of the question), same for StdIn and StdOut.
  4. Your class is in the default package, thats ok for a test though.

To actually solve your question, there are a couple of solutions. BlithE already showed you one, the other is mentioned by David Zhou in a comment:

// missing ST StdIn and StdOut, they probably need too be imported
public class Test {

    public static void main(String[] args) {
        ST<String, Integer> st;
        st = new ST<String, Integer>();

        for (int i = 0; !StdIn.isEmpty(); i++) {
            String key = StdIn.readString();
            st.put(key, i);
        }

        addValue(st);

        for (String s : st.keys()) {
            StdOut.println(s + " " + st.get(s));
        }

    }

    public static void addValue(ST<String, Integer> st) {
        st.put("P", 5);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.