简体   繁体   中英

Iterating over data structure and nested classes

I have some code below for an iterator but I am having trouble understanding how it works. What specifically confuses me is the public Node<T> front; and the for statement.

Front is a reference to the static nested class and in the for loop we have LinkedList.Node<String> ptr = list.front . The left side of that operation is just accessing the outer class to then access the static nested class which we make ptr reference to. The right side of that operation uses the object of our outer class to access the front reference which is the static nested class as well.

So aren't the left and right side the same thing? Why does the code set one side equal to the other? I know the code provided isn't full - I didn't write it. I'm just trying to understand it.

public class LinkedList<T> {
    public static class Node<E> {
        public E data;
        public Node<E> next;
    }
    public Node<T> front;

    ...code omitted...
}


LinkedList<String> list = new LinkedList<String>();

...code omitted...

for (LinkedList.Node<String> ptr = list.front; ptr != null; ptr = ptr.next) {
    System.out.println(ptr.data);
}

To start, "front" is not a reference to the static nested class. It's a reference to an "instance" of that class, which is an important distinction. Think of the class as a template for creating instances.

So at some point, someone would have created the object:

LinkedList<String> list = new LinkedList<String>();
list.front = new LinkedList.Node<String>();
list.front.data = "foo";

And then maybe prepends a node to the list (which is typically how you alter a LinkedList, as appending is expensive)

// Create the new node
LinkedList.Node<String> newNode = new LinkedList.Node<String>();
newNode.data = "bar";
// Since we're prepending, the existing front becomes the next for this node.
newNode.next = list.front;
// This node becomes the front of the list
list.front = newNode;

As for the for statement, think of it as a while loop, which reads a bit easier for people

LinkedList.Node<String> ptr = list.front;
while (ptr != null) {
  // do something
  ptr = ptr.next;
}

To answer your question about the "static" class:

An inner class is just like any other class. It is just namespaced within the outer class. There are however two flavors of inner classes. The static flavor:

  1. Can be instantiated on it's own
  2. Is not related to any particular instance of the outer class

Conversely, a non-static inner class:

  1. Must be instantiated via an instance of it's containing class
  2. Has access to all of the fields and methods of the instance of it's containing class.

Take this code example:

public class Outer {
    private int value = 10;

    public static class StaticInner {

    }

    public class Inner {
        public void foo() {
            System.out.println(value);
        }
    }

    public Inner createInner() {
        return new Inner();
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        StaticInner staticInner = new StaticInner();
        Inner inner = outer.new Inner();
        Inner inner2 = outer.createInner();
    }
}

In reality, the final two calls of the main method are doing the same thing. It's that you need a little different syntax to create the instance from outside the containing class. But you'll notice in both cases, you need have previously created an instance of Outer, whereas to get a StaticInner instance, you did not.

You'll also notice that in the non static one, you're able to access the private field "value" of it's containing instance.

You might want to look here:

http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM