Use variable inside the visit function - java

In the code below, I am trying to access the 'singleBuilding' variable inside the 'GMLWalker' visit function. I am getting the error "Cannot refer to the non-final local variable singleBuilding defined in an enclosing scope". Any clues on how I can achieve this.
private FeatureWalker IterateGroundSurface(BuildingClass singleBuilding){
FeatureWalker groundWalker = new FeatureWalker(){
public void visit(GroundSurface groundSurface){
GMLWalker gmlWalker = new GMLWalker(){
public void visit(LinearRing linearRing){
if(linearRing.isSetPosList()){
SurfaceMember surfaceMember = new SurfaceMember();
DirectPositionList posList = linearRing.getPosList();
List<Double> points = posList.toList3d();
List<CoordinateClass> polygonfloor = new ArrayList<CoordinateClass>();
PolygonClass poly = new PolygonClass();
for(int i=0 ; i<points.size() ;i+=3){
double[] vals = new double[]{points.get(i) , points.get(i+1),points.get(i+2)};
//System.out.println(vals[0]+" "+vals[1]+" "+vals[2]);
CoordinateClass coord = new CoordinateClass(vals);
polygonfloor.add(coord);
}
poly.setPolygon(polygonfloor);
surfaceMember.setPolygon(poly);
singleBuilding.setSurfacePolygon(surfaceMember);
//surfacePolygons.add(buildingSurfacePolygon);
}
}
};
groundSurface.accept(gmlWalker);
}
};
return groundWalker;
}
Thanks,

You need to make it final if you want to access it in a inner class. Again if you make it final then you won't be able to re initialize it.
private FeatureWalker IterateGroundSurface(final BuildingClass singleBuilding){
}

Related

How to make an array from a class defined inside another class

I am a novice Java programmer trying to use classes defined in a different file. So, I've written these two .java files:
First, there's MyLibrary.java:
package mymainprogram;
public class MyLibrary {
public class MyRecord {
int number;
char letter;
}
public static int TriplePlusThree(int input_number) {
return ((input_number*3) + 3);
}
}
Then, MyMainProgram.java:
package mymainprogram;
import java.util.Scanner;
public class MyMainProgram {
public static void main(String[] args) {
Scanner keyread = new Scanner(System.in);
System.out.print("Enter Number to Process: ");
int num = keyread.nextInt();
int result = MyLibrary.TriplePlusThree(num);
System.out.println("3x + 3 = "+result);
String letters = "ABCDEFGHIJ";
MyLibrary.MyRecord[] TenRecs = new MyLibrary.MyRecord[10];
for (int i = 0; i < 10; i++) {
TenRecs[i].number = i; //NullPointerException here
TenRecs[i].letter = letters.charAt(i);
}
}
}
I had no problem getting the method to work just fine; now my goal is to create an array where each member of the array has an integer and character. (Note: I'm not looking for better ways to accomplish this objective; I'm merely using this trivial example to try to get this working).
When I tried to run my program, I got:
java.lang.NullPointerException
I researched this, and found this page, which says:
If we try to access the objects even before creating them, run time errors would occur. For instance, the following statement throws a NullPointerException during runtime which indicates that [this array] isn't yet pointing to [an] object. The objects have to be instantiated using the constructor of the class and their references should be assigned to the array elements in the following way.
studentArray[0] = new Student();
So, I tried to do that in my Main Program:
MyRecordArray[0] = new MyLibrary.MyRecord();
but that gives this error:
an enclosing instance that contains MyLibrary.MyRecord is required
That error message led me to this Stack Exchange question, which says:
you have to create an object of X class (outer class) and then use objX.new InnerClass() syntax to create an object of Y class.
X x = new X();
X.Y y = x.new Y();
So, in accordance with that answer, I've added these two lines to my program:
MyLibrary mylibrary = new MyLibrary();
MyLibrary.MyRecord myrecord = mylibrary.new MyRecord();
Those lines don't give any warnings or compilation errors, so I feel like I'm one step closer, but I'm still trying to figure out how to make an array. I know if I wanted to make an array of integers, I would simply do this:
int[] TenInts = new int[10];
So, I've tried things like:
myrecord[] TenRecs = new myrecord[10];
MyRecord[] TenRecs = new MyRecord[10];
But nothing is working, and I feel like I'm grasping at straws now. I get the feeling that the right set of eyes could solve this pretty quickly.
You need to declare the inner class as static.
You can modify the code as follows to suit your requirements:
This is the code for MyLibrary
public class MyLibrary {
public static class MyRecord{
int number;
char letter;
public MyRecord(){
number = 0;
letter = '\0';
}
public MyRecord(int number, char letter){
this.number = number;
this.letter = letter;
}
}
public static int TriplePlusThree(int input_number){
return (input_number * 3 + 3);
}
}
This is the code for the MyMainProgram
import java.util.Scanner;
public class MyMainProgram {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Enter number to process");
int num = in.nextInt();
System.out.println("3x + 3 = " + MyLibrary.TriplePlusThree(num));
String letters = "ABCDEFGHIJ";
MyLibrary.MyRecord[] TenRecords = new MyLibrary.MyRecord[2];
for (int i=0; i<TenRecords.length; i++){
TenRecords[i] = new MyLibrary.MyRecord();
TenRecords[i].number = i;
TenRecords[i].letter = letters.charAt(i);
}
// Printing class records
for (int i=0; i<TenRecords.length; i++){
System.out.println("Printing records of record " + i + " : ");
System.out.println("Number : " + TenRecords[i].number);
System.out.println("Letter : " + TenRecords[i].letter);
}
in.close();
}
}
You can create the instance of the inner class as follows:
TenRecords[i] = new MyLibrary.MyRecord();
Hope this helps.
The nested class MyRecord contains a hidden reference to the outer class MyLibrary and therefore must be associated with an instance of MyLibrary. This way MyRecord can access private members of MyLibrary.
MyLibrary.MyRecord myrecord = mylibrary.new MyRecord();
Wow, this is funny syntax. In all my years of java programming, I never used such a construct. Typically, you would create objects of inner classes (MyRecord) within the outer class (MyLibrary). Another common thing is to declare the inner class as static which would eliminate the need for an instance of the outer class.
MyRecord[] TenRecs = new MyRecord[10];
This will create an array where all the elements are NULL. You have to initialize each of them (e.g. with a loop).
If you initialize MyRecord[10] the array has null objects. You still have to initialize each element in the array to a new MyRecord object. Otherwise you will get the NPE.
one way to do is : List<MyRecord> TenRecs = new ArrayList<MyRecord>();
TenRecs.add( new MyRecord() );
or for ( int i = 0; i < 10; i++ ) TenRecs[i] = new MyRecord();
also if you add an import statement : import mymainpackage.MyLibrary.MyRecord; You don't need to do mylibrary.new MyRecord(); just do new MyRecord();
You have to create each object in array before initialize. Refer to this link.
Create each object like this.
MyLibrary outer = new MyLibrary();
TenRecs[i] = outer.new MyRecord();
Full code:
MyLibrary.MyRecord[] TenRecs = new MyLibrary.MyRecord[10];
for (int i = 0; i < 10; i++) {
MyLibrary outer = new MyLibrary();
TenRecs[i] = outer.new MyRecord();
TenRecs[i].number = i;
TenRecs[i].letter = letters.charAt(i);
}
There are several points you need to note.
First, difference between a instance inner class and a static inner class.
An instance inner class, declared without static modifier,
public class OutterClass {
public class InstanceInnerClass {}
}
should be created like this:
OutterClass outter = new OutterClass();
InstanceInnerClass iInner = outter.new InstanceInnerClass();
while a static inner class, declared with static modifier,
public class OutterClass {
public static class StaticInnerClass {}
}
should be created like this:
StaticInnerClass sInner = new OutterClass.StaticInnerClass();
Secondly, you accessed an array entry before it is filled
MyLibrary library = new MyLibrary();
MyLibrary.MyRecord[] TenRecs = new MyLibrary.MyRecord[10];
for (int i = 0; i < 10; i++) {
// Create new instance
TenRecs[i] = library.new MyRecord();
TenRecs[i].number = i;
TenRecs[i].letter = letters.charAt(i);
}

Java - Method on new operator

Well, I'm not sure if I can do this but let me ask the question anyway...
I got class Budynek which constructor is like this:
public Budynek(int numerBudynku)
{
this.id.nrBudynku = numerBudynku;
this.id.nrPietra = 0;
this.id.nrPokoju = 0;
}
so I am creating it like this:
Budynek Budynek1 = new Budynek(1);
Budynek Budynek2 = new Budynek(2);
Now I want to ask if there is any way to create a method that create new Budynek for me? Lets say if I use switch case, and case 1 will be "create new Budynek"
then I would like this method to do something like this
e.g licznik = 1
Budynek Budynek+licznik(so it will be Budynek1) = new Budynek(licznik)
then just licznik = licznik + 1;
is that possible?
You can create a List and store everything there, since your are indexing anyways with budynek+index
List<Budynek> budynekList = new ArrayList<Budynek>();
budynekList.add(new Budynek(10));
budynekList.add(new Budynek(20));
budynekList.add(new Budynek(400));
budynekList.get(index); // now you have your budynek objects with the given index.
As in the comments already pointed out, you can't declare variables on runtime.
Either
enum Budynek {
BUDYNEK_A,
BUDYNEK_B,
BUDYNEK_C;
public ID id;
private Budynek() {
this.id.nrBudynku = 1 + ordinal();
this.id.nrPietra = 0;
this.id.nrPokoju = 0;
}
}
Budynek.BUDY_A.id.nrBudynku
or you must go for an array:
Budynek[] budyneki = new Budynek[3];
...
budyneki[0].id.nrBudynku
budyneki[1].id.nrBudynku
budyneki[2].id.nrBudynku

Best practice for adding elements to an ArrayList during object construction?

So I'm working on a project for my online AP Computer Science class and have run into a problem... Here's the original class definition I was given to build upon (stripped of code irrelevant to my question):
Note: The constructor of the Bin class accepts a single argument, a String. The String is representative of the Bin's name.
import java.util.*;
public class Warehouse
{
// Declare instance variables here
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( 5 );
// Code that will start the warehouse
// off with 5 empty bins
}
public void addBin()
{
myBins.add( new Bin( "B" + myBins.size() ) );
}
}
My job is to replace the areas commented out with actual code implementation. While the declaration of the instance variables is very straight forward, I'm rather torn on the best way to implement the code mentioned in the second comment.
In short, which is the best way to complete the above constructor?
Solution A:
private int myBinMax;
private ArrayList<MusicMedia> myCatalog;
private ArrayList<Bin> myBins;
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( 5 );
for(int i = 0; i < 5; i++)
{
myBins.add( new Bin( "B" + myBins.size() ) );
}
}
Solution B:
private int myBinMax;
private ArrayList<MusicMedia> myCatalog;
private ArrayList<Bin> myBins;
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( 5 );
for(int i = 0; i < 5; i++)
{
addBin(); // <= Is this considered bad practice?
}
}
Solution C:
// Some magical wizard code I would have never thought of. XD
Thanks in advance!
Can you use Java 8?
final List<Bin> bins = IntStream.range(0, 5).
mapToObj(i -> new Bin("Bin" + i)).
collect(Collectors.toCollection(ArrayList::new));
Otherwise, both your solutions looks fine. I would prefer B as you already have an addBin method with one caveat. You must make addBin final as it is a public method. You should only call private or final methods from constructors otherwise you risk someone (possibly you) overriding that method in a subclass and then the subclasses method will be called from the superclass constructor before the subclass is initialized.
try to use a constant than magic numbers in code :)
import java.util.*;
public class Warehouse
{
// Declare instance variables here
private static final int INITIAL_BINS = 5;
private static final String DEFAULT_BINNAME = "DefaultBin_";
public Warehouse( int binMax )
{
myBinMax = binMax;
myCatalog = new ArrayList<MusicMedia>();
myBins = new ArrayList<Bin>( INITIAL_BINS );
for(int i = 0; i < INITIAL_BINS; i++)
{
myBins.add( new Bin( DEFAULT_BINNAME + i ) );
//addBin();// This is fine too depends on how flexible you want naming to be:)
}
}
public void addBin()
{
myBins.add( new Bin( "B" + myBins.size() ) );
}
}
While I agree with most everything that's already been said, the java 8 functional programming style one-liner is pretty sexy. Magic numbers / strings should be avoided. If your class hasn't gone over functional style why not move the entire for loop into its own function? Generally the only thing that a constructor should do is initialize the state of your object. To make that explicit I try to keep to one line per member variable and that one line is nothing more than an initialization statement. IMO methods (which can reference the current state of the object) shouldn't be called from a constructor because your object hasn't been created yet. If you want to add functions to help you initialize your object, feel free to do so but keep them static so that the intent of the function (not referring to the state of the object) is clear.
...
private static final int INITIAL_BIN_COUNT = 5;
private static final String BIN_PREFIX = "B";
private final List<Bin> myBins;
public Warehouse(...) {
....
myBins = initMyBins();
}
private static List<Bin> initMyBins() {
final List<Bin> result = new ArrayList<Bin>(INITIAL_BIN_COUNT);
for(int i = 0; i < INITIAL_BIN_COUNT; i++) {
result.add(new Bin(BIN_PREFIX+i));
}
return result;
}
...
P.S. A few other notes, it's generally good practice to code to interface types rather than concrete class types (maybe you haven't covered interfaces yet, but that's what I did changing ArrayList to List.

Casting inner objects in java - unchecked exception

I'm having a problem with inner classes. I build an object (let's say a train) with an inner class representing states (let's say the stops of the train).
I'm trying to run this code:
private void CustomObjectBuilder (String [] origin) {
final int array_dim = origin.length;
InnerCustomObject[] tmp_bin = new InnerCustomObject[array_dim];
for (int ii = 0; ii < array_dim; ii++) {
String debug = extractData(origin[ii]);
tmp_bin[ii].setData(debug);
}
}
It compiles just just fine but at runtime I get a null object exception.
What am I doing wrong?
Here you can finde the original code:
public class CustomObject {
InnerCustomObject [] stops;
public class InnerCustomObject {
String name, station, schedTime, depTime, schedRail, depRail;
public void setData (String origin) {
this.station = origin;
}
}
}
Edit: I solved by calling
CustomObject.InnerCustomObject ico = new CustomObject(). new InnerCustomObject();
why it needs to be so verbose?
Well, the most immediate thing I notice is you don't populate tmp_bin[] with any objects after you declare it. When you first create an array, all it contains are nulls.
So when you do this in your loop:
tmp_bin[ii].setData(debug);
There is nothing to invoke setData() on, resulting in the exception.
Re edit: you can just do
InnerCustomObject ico = this.new InnerCustomObject();
since you're creating them within your outer CustomObject class's CustomObjectBuilder() instance method.
InnerCustomObject[] tmp_bin = new InnerCustomObject[array_dim];
declares an array of array_dim elements but all are null. Then this
tmp_bin[ii].setData(debug);
won't work.
No problem with inner classes only with an object that is null (=NPE) so you cannot call the method setData().
In your loop you have to create new instance of InnerCustomObject. By new InnerCustomObject[size] you do not create new instances.

Within an array of objects can one create a new instance of an object at an index?

Here's the sample code:
class TestAO
{
int[] x;
public TestAO ()
{
this.x = new int[5] ;
for (int i = 0; i<x.length; i++)
x[i] = i;
}
public static void main (String[]arg)
{
TestAO a = new TestAO ();
System.out.println (a) ;
TestAO c = new TestAO () ;
c.x[3] = 35 ;
TestAO[] Z = new TestAO[3] ;
Z[0] = a ;
Z[1] = (TestAO b = new TestAO()) ;
Z[2] = c ;
}
}
When I try to compile this I get an error message at the line Z[1] which reads as follows:
TestAO.java:22: ')' expected
Z[1] = (TestAO b = new TestAO()) ;
^
What I'm trying to do here is create an instance of the object TestAO that I want to be in that index within the assignment of the value at that index instead of creating the instance of the object outside of the array like I did with a.
Is this legal and I'm just making some syntax error that I can't see (thus causing the error message) or can what I'm trying to do just not be done?
EDIT:
in regard to Mark's answer here is my follow up question:
is there a shorter way to assign values to the instance variables of an object in the array of objects than this: (without writing any special constructors)
Z[1] = new TestAO() ;
Z[1].x[4] = 80085 ;
It's easier than you think:
Z[1] = new TestAO();
Declaring variable like this is impossible. Just write "Z[1] = new TestAO();" and if you want another reference "TestAO b = Z[1]";
What you're really doing here is assigning the result of an assignment to Z[1]. The return type of an assignment in Java is boolean, so the way you're doing it is not going to work.
Try:
Z[1] = new TestAO();
Try this:
Z[1] = new TestAO() ;

Categories