0

I need to access lots of very similar objects and everything within them. So far, I have three classes:

"Piece" - Does nothing so far, but is subclassed by LcPawn.

"LcPawn" - This has one line of code, '''public static int ID;''' which is supposed to hold a different number for each instance of the LcPawn.

"Main" - The code in question is as follows:

public static ArrayList<LcPawn> LcPawns = new ArrayList<LcPawn>(256);
for (int i = 0; i < 256; i ++) {
    LcPawns.add(i, new LcPawn());
}
for (int i = 0; i < LcPawns.size(); i ++) {
    LcPawns.get(i).ID = i; 
}
for (int i = 0; i < LcPawns.size(); i ++) {
    System.out.println(LcPawns.get(i).ID);
}

However, nothing comes up on the console. The separate loops are so I can make sure this works without having to reset all the objects over and over again. This is as much as i know.

2
  • 2
    Can you explain what the keyword static means? Commented Jan 27, 2020 at 2:24
  • 1
    This has one line of code, '''public static int ID;''' which is supposed to hold a different number for each instance of the LcPawn - this is not how static variables work. An Object with a static variable will be limited to one instance Commented Jan 27, 2020 at 2:46

1 Answer 1

1

Some things to note:

Your LcPawn class has a variable public static int ID; which you say should have a different value for each instance. In Java, the keyword static in this context does the opposite of that, it declares a "class variable", instead of an "instance variable". To provide one instance of ID for each instance of LcPawn, just remove static here and that should be fine.

Second, a convention worth sticking to is to make all fields private, while providing "getters and setters". For example, instead of declaring a class as follows:

public class MyClass {
    public int value;
}

instead declare it as:

public class MyClass {
    private int value;

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return this.value;
    }
}

This has several advantages:

  • You can add business logic to the functions, e.g. perhaps you want to forbid negative numbers in the value field. You can add a line: if (value < 0) throw new NegativeNumberException();

  • You can change implementation without changing the rest of your code. Perhaps you want to get your value from the internet, or you use a library that wants to lazy-load your variable. This is only possible with a method call, and cannot be done by a raw variable.

  • Many popular libraries expect classes to be in this format (e.g. Jackson Databind, and Spring).

You should also follow standard Java capitalization rules:

  • field names and methods are written likeThis and likeThis()
  • class names are written LikeThis
  • constants are written LIKE_THIS

With that in mind, here is how I would write your code:

public static void main(String[] args) {
    List<LcPawn> pawns = new ArrayList<>(256);  // more generic type and type parameter omitted for brevity

    for (int i = 0; i < 256; i++) {
        pawns.add(new LcPawn());  // no need to specify an index, it gets added to the end by default
    }

    for (int i = 0; i < pawns.size(); i++) {
        pawns.get(i).setId(i);  // using setter method
    }

    for (int i = 0; i < pawns.size(); i++) {
        System.out.println(pawns.get(i).getId());  // using getter method
    }
}

However, this can be compacted into one single for loop:

List<LcPawn> pawns = new ArrayList<>(256);
for (int i = 0; i < 256; i++) {
    LcPawn pawn = new LcPawn();
    pawn.setId(i);
    System.out.println(pawn.getId());
    pawns.add(pawn);
}

Or, with Java 8 streams:

IntStream.range(0, 256)  // generate a stream of integers from 0-255
    .map(i -> {  // map each integer to a pawn with that integer as its id
        LcPawn pawn = new LcPawn();
        pawn.setId(i);
        return pawn;
    })
    .forEach(System.out::println);  // print all of them, using a "method reference"
Sign up to request clarification or add additional context in comments.

1 Comment

I think that It would be better to pass the id as a constructor parameter for the LcPawn class in order to get rid of the second for loop

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.