Arrays with outer and inner classes

4.3k views Asked by At

I am relatively new to Java. I wanted to create an arraylist of an outer class and for each index of the outer class of the arraylist I want an arraylist of inner classes.

public Outerclass{

    //Code Here

    public InnerClass{
    //Code Here
    }
}

//My attempt at setting up the arrays
public ArrayList <Outerclass> olist;
public ArrayList <InnerClass> ilist;


 olist= new ArrayList<Outerclass>();
 for (int i = 0; i < 3; i++) {
      Outerclass c = new Outerclass ();
      ilist = new ArrayList<InnerClass>();
      for(int j = 0 ; j < 4; j++){
          InnerClass e = new InnerClass();
          ilist.add(e);
      }
      olist.add(c);
 }

Will this work?

5

There are 5 answers

0
Stephen C On

Here are the key lines of your code:

 Outerclass c = new Outerclass ();

     InnerClass e = new InnerClass();

That won't work. You will get a compilation error.

Since InnerClass is an inner class, it needs to be instantiated in the context of an instance of its enclosing class (i.e. OuterClass). Like this:

 Outerclass c = new Outerclass ();

     InnerClass e = c.new InnerClass();

The c.new ... form is called a qualified class instance creation expression; see JLS 15.9.

Notes:

  1. If the code that creates the inner class is in the context of an instance of the outer class (e.g. it is in an instance method of the outer class) then you don't need to qualify the new like that.

  2. If the InnerClass is static this isn't necessary either. But then InnerClass is a nested class not an inner class ... according to the standard Java terminology.

0
keyser On

An instance of an inner class can only exist within an instance of an outer class. (For a distinction between static and non-static inner classes, see this answer for more info).

What this means is that you create inner objects within outer objects. You can think of it as the outer objects creating and containing the inner objects (hence the name inner)

Here's an example:

import java.util.ArrayList;

public class OuterClass {
    static ArrayList<InnerClass> innerClasses = new ArrayList<InnerClass>();

    public static void main(String[] args) {
        OuterClass oc1 = new OuterClass();
        OuterClass.InnerClass ic1 =  oc1.new InnerClass();
        OuterClass.InnerClass ic2 =  oc1.new InnerClass();
        innerClasses.add(ic1);
        innerClasses.add(ic2);      
        System.out.println(innerClasses.size());
    }
    class InnerClass {

    }
}
1
Nir Alfasi On

First, I think that you should learn how to walk before you start running:

public Outerclass

should be

public class Outerclass

same with inner!

Second, all the last portion of your code should be in a main() method INSIDE Ourclass.

And third, no, you cannot use inner class like that, that's why these classes are inner. If you want to use inner classes from inside main() or from outside the outer class you have to use an instance of outer in order to access them, same like accessing any other instance member - you can't access it directly:

        Outerclass oc = new Outerclass();
        Outerclass.InnerClass in = oc.new InnerClass();
0
jbx On

Given that the InnerClass needs to maintain reference to the members of the OuterClass, I wonder why aren't you putting the ArrayList<InnerClass> inside OuterClass. If they're composed in that way it makes much more sense to have the list 'managed' by the OuterClass and just give it access methods to return the list of InnerClass instances etc.

So something like this:

public class OuterClass
{
   private List<InnerClass> innerClassInstances = new ArrayList<>;

   public void addInnerInstances(int count)
   {
      for(int j = 0 ; j < count; j++)
      {
         InnerClass e = new InnerClass();
         innerClassInstances.add(e);
      }
   }

   public List<InnerClass> getInnerClassInstances()
   {
       return innerClassInstances;
   }

   public class InnerClass
   {
     //...
   }
}

   //in your main class or wherever
   List<Outerclass> olist;

   olist= new ArrayList<Outerclass>();
   for (int i = 0; i < 3; i++) 
   {
      Outerclass c = new Outerclass ();
      c.addInnerInstances(4);
      olist.add(c);
   }

You cannot create the InnerClass on its own with new as you're doing, you are saying that it needs to access the members of its OuterClass instance, and as you can see in your code, for each new InnerClass() you are never specifying in any way what is the OuterClass instance for it.

0
Stephan Brunker On

A litte refinement for answer #2, if you have nested classes for data storage, means that you have an constructor for the outer class that automatically generates a variable number of array members for the inner class like a tree structure. This solution is practically a workaround which uses one defined member - an ArrayList - which can be expanded later instead of a direct definition of an InnerClass[] array inside the OuterClass, which won't work if its not static.

public class OuterClass
{
    private int NumberInnerClassInstances;       
    // ... other members of OuterClass
    ArrayList<InnerClass> innerClassInstances = new ArrayList<>();

    OuterClass( input vars ...)  {
        // calculate the NumberInnerClassInstances needed
        for(int i = 0 ; j < NumberInnerClassInstances; i++) {
            OuterClass.InnerClass in = this.new InnerClass(i);
            innerClassInstances.add(in);
        }
    }

    public class InnerClass
    {
        int icvar;
        InnerClass(int i) {
            //...construct the Inner Class Member #i
            // can access the members of OuterClass
        }
    }
}

from outside, you can then access the InnerClass Instances with get:

oc = new OuterClass( vars ...)
var = oc.InnerClassInstances.get(i).icvar