ArrayList is empty in other Methods in Java - java

The ArrayList is initialised inside a Class and its values are set in a method (which are only existent in this method)
How could I prevent the arraylist from being empty or why is this even happening?
(Edit: I added this minor project to github (https://github.com/goodstuff20/NENAM))
List<Node> nodes = new ArrayList<Node>();
public Creature(Node[] nodes){
for(int i = 0; i < nodes.length; i++) {
this.nodes.add(nodes[i]);
}
System.out.println(this.nodes.size()); //4
}
public void tick(){
System.out.println(nodes.size()); //0
}

You have defined 2 contructors in class Creature. In the second ctor you make a call to the first using the new-operator:
public Creature(Node[] nodes){
//....
for(int i = 0; i < nodes.length; i++){
nodess.add(nodes[i]);
}
//....
}
public Creature(int[][] nodePos, int[][] musclePos){
//...
Node[] nodes = new Node[nodePos.length];
//...
new Creature(nodes);
}
Maybe your intention is to change the currently created object by calling the other ctor, but instead you create a new object with no relation to the first.
To call another ctor inside a ctor on the same object you have to use this, but that must be done in the first line.
For example:
public Creature(int[][] nodePos, int[][] musclePos){
this(...);
}
For your purposes it is better to use an init-method:
public Creature(Node[] nodes){
init(nodes);
}
public Creature(int[][] nodePos, int[][] musclePos){
//...
Node[] nodes = new Node[nodePos.length]; //when defineing an int length = normal and not -1
//...
init(nodes);
}
private void init(Node[] nodes) {
//...
for(int i = 0; i < nodes.length; i++){
nodess.add(nodes[i]);
}
//...
}

Related

How to call the constructor of the members of an array in Java?

I have a class:
public class a {
public int memberA;
private int memberB;
public a (int i) {
memberA = i;
memberB = ...;
}
}
and another one:
public class b {
public a[] = new a[10]; // <-- How do I call the constructor of 'a' with a value?
...
}
I tried many things, but nothing works! My app crashes if I don't call the constructor!
You can just use a for loop to instantiate each element of the array.
public class b {
public a[] arr = new a[10];
{
for(int i = 0; i < arr.length; i++) arr[i] = new a(/*some value*/);
}
}
As an aside, always follow Java naming conventions e.g. the name of the classes should be A and B instead of a and b. Better if you use self-descriptive names.

get an object based on its static value

I am initalizing several objects of the same type that have a common field:
public class Example {
private static objectCounter = 1;
public Example () {
objectCounter++;
}
}
Since these objects are created with a for loop like this
for (int i = 0; i<5; i++) {
Example e = new Example();
}
they are not referenced.
Is there a way to get a specific object based on objectCounter value ?
Something like
//get the Example object with objectCounter==2
get(2);
Thank you
My suggestion will be saving into array:
Example store[] = new Example[5]
for (int i = 0; i<5; i++) {
store[i] = new Example();
}
And then , search for the specific object.
As stated in the comments, a static value will persist through all instances of your class.
If you want your Example to "know" it's identity, pass it in when you construct it:
Example:
public class Example {
private int id;
public Example (int val) {
this.id = val;
}
// Getters/setters
}
Probably also want to add your objects to a list to access them later, so before your for-loop:
List<Example> examples = new ArrayList()<Example>;
And create them like this:
for (int i = 0; i<5; i++) {
Example e = new Example(i);
examples.add(e);
}

JUnit: test builder with private field

I'm a beginner and I have a problem with JUnit test in the constructor of a class.
The class that I want to test is called IntSortedArray and is as follows:
public class IntSortedArray {
private int[] elements;
private int size;
public IntSortedArray() {
this.elements = new int[16];
this.size = 0;
}
public IntSortedArray(int initialCapacity) throws IllegalArgumentException {
if(initialCapacity < 0) {
throw new IllegalArgumentException("Error - You can't create an array of negative length.");
}
else {
elements = new int[initialCapacity];
size = 0;
}
}
public IntSortedArray(int[] a) {
elements = new int[a.length + 16];
for(int i = 0; i < a.length; i++)
elements[i] = a[i];
size = a.length;
insertionSort(elements);
}
//other code...
}
With Eclipse I created a class for JUnit:
public class IntSortedArrayUnitTest {
private IntSortedArray isa;
#Test
public void testConstructorArray16Elements() {
isa = new IntSortedArray();
int expected = 0;
for(int i: isa.elements) **<-- ERROR**
expected += 1;
assertEquals(expected, 16);
}
}
I started to write a test class with the intention to test all the methods of the class IntSortedArray, including constructors.
The first method testConstructorArray16Elements() wants to test the first builder.
So I thought I would check if the creation of the array elements is done properly, so the for loop counts how long elements and make sure it along 16 (as required).
But Eclipse generates (rightly) a mistake because elements is private.
How can I fix this error? I don't want to put the public field and if possible I would like to avoid creating a method public int[] getElements().
What do you recommend?
Another question: I can do two assert the same method? One to test the length of the array and the other to test that size is 0.
I hope not to have made big mistakes, this is the first time I use JUnit.
PS: how can I test the second constructor?
Thank you very much!
It looks like your class fields are declare as private but you trying to access then from outside the class. You need to provide the accessors methods in you class to make them visible:
private int[] elements;
private int size;
public static final int MAX = 16;
public int[] getElements() { ... }
public int getSize() { return size; }
Then you will be able to write below code:
isa = new IntSortedArray();
int expected = 0;
for(int i: isa.getElements()) {
expected += 1;
}
assertEquals(expected, IntSortedArray.MAX );
It looks like your constructor has created an array for 16 integers, but does not initialize it with any value. To do that you should have below code:
public IntSortedArray() {
this.elements = new int[MAX];
this.size = 0;
for (int i=0 ; i < MAX ;i++) {
elements[i] = i;
size++;
}
}
You'll have to write a getter method for your array, or implement an Iterator

My Constructor won't construct or "return" what should be returned

This is my Constructor:
public class OrderedIntList extends ArrayList{
public OrderedIntList(int ... elements) {
ArrayList <Integer> temp = new ArrayList<Integer>();
for(int i=0; i<elements.length; i++) {
temp.add(elements[i]);
}
}
}
This is my program:
public static void main(String[] args) {
int[] a = {1,2,4,5,3};
OrderedIntList la = new OrderedIntList(a);
System.out.println(la);
}
When I run it the output is: [ ]. So technically the constructor dint give back the construct right? how do i fix this?
The code snippet for adding occures that much, a utility functions exists in class Collections.
I have made an alternative with addAll.
public class OrderedIntList extends ArrayList<Integer> {
public OrderedIntList(int... elements) {
for (int element : elements) {
add(element);
}
}
public OrderedIntList(Integer... elements) {
Collections.addAll(this, elements);
}
}
Also ArrayList is parametrised.
In your constructor you initialized local ArrayList which holds elements passed in constructor, but toString is not aware of this local list and is printing elements held by inherited structure from class you extend - ArrayList. So consider changing your constructor to
public OrderedIntList(int... elements) {
for (int i = 0; i < elements.length; i++) {
this.add(elements[i]);// your class extends ArrayList
// so it inherited structure to store elements
// and toString is base on this structure
// not on local list declared in constructor
}
}
You are adding element to temp list in your constructor, instead you should add to your list like this
for(int i=0; i<elements.length; i++) {
add(elements[i]);
}
You are creating a local ArrayList in the constructor:
OrderedIntList(int... elements) {
ArrayList temp = new ArrayList();
You should write the passed values directly:
public OrderedIntList(int... elements) {
for (int i = 0; i < elements.length; i++) {
add(elements[i]);
}
}

Am I not understanding ArrayList or am I missing something?

I'm trying to create a very, very simple program.
I want my class called Text to simply print out a string, specifically, one letter.
Then in my second class called Window, I want to create an ArrayList of that class, iterate through the list and call the method of my Text class to print out the string. But it does not print anything.
What am I doing wrong?
public class Text {
private String a;
public void printA() {
a = "a";
System.out.print(a);
}
}
and the other class..
import java.util.ArrayList;
public class Window {
private ArrayList<Text> string = new ArrayList<Text>(5);
public Window() {
addText();
}
public void iterate() {
for (int i = 0; i < string.size() - 1; i++) {
string.get(i).printA();
}
}
public void addText() {
for (int i = 0; i <string.size() - 1; i++) {
string.add(new Text());
}
}
public static void main(String[] args) {
Window wind = new Window();
wind.iterate();
}
}
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
initialy the arraylist is empty, so string.size() == 0
the forlus wil not be executed, change to
public void addText(){
string.add(new Text())
}
or even better
public void addText(Text t){
string.add(t)
}
that way you can add Text-object created with different constructors
If you modify iterate to:
public void iterate(){
System.out.println(string.size()-1);
for(int i = 0; i < string.size()-1;i++){
string.get(i).printA();
}
}
You will get -1
Let me explain why:
Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. private ArrayList<Text>string = new ArrayList<Text>(5); merely sets the capacity of the underlying array that is the data structure that implement the ArrayList object. size() returns the number of objects inside of the ArrayList not the capcity
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
The for loop's expression doesn't evaluate to true, and therefore you never add a single object to the loop which is why iterate would print -1 if you added the print statement there
The
new ArrayList<Text>(5);
Doesn't mean you have 5 elements array. It means that this is just initial capacity of internal array for storing elements. Due to this your init code:
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
faces no elements in the list with string.size() = 0.
Use this instead (If you like to add 5 elements):
public void addText(){
for(int i = 0; i < 5;i++){
string.add(new Text());
}
}
There is no problem to add more elements (even if the initial capacity was only '5'). From docu "As elements are added to an ArrayList, its capacity grows automatically."
problem it this method.
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
this doesn't add anything at all. because string.size() is 0.
may be you should change it to
public void addText(int size){
for(int i = 0; i <size-1;i++){
string.add(new Text());
}
}
Ps: new Arraylist<Text>(5) actually creates an empty list with initial capacity = 5 (not size). See it here
Well for stater your method in Text needs parameter so it KNOWS to take in 'a' and if you're variable in your parameter is going to be 'a' as well you need use "this." so that the compiler knows that the two are different.
public class Text {
private String a;
public void printA(String a) {
this.a = "a";
System.out.print(a);
}
}
What you are doing wrong is that you are creating the ArrayList with a capacity of 5, but it does not yet have 5 objects in it. Thus, the addText method does nothing. Here's a version that works:
public void addText(){
for(int i = 0; i < 4; i++){
string.add(new Text());
}
}
Note that string.size() - 1 has been changed to 4, becuase string.size() is 0, and you want to add 4 elements to the list. Also, your iterate method could use a little refactoring:
public void iterate(){
for(Text text : string){
string.get(i).printA();
}
}
Instead of a simple loop, an enhanced for is used instead. This is no more than a typing shortcut, but it improves efficiency for LinkedLists.

Categories

Resources