Sentience
Sentience

Reputation: 105

User-Entered value for Array Size doesn't actually change the array's size. [Java]

So as the title says, I'm trying to get a user inputted size to my array, yet every time I run the program it does not change the array size. I'm pretty sure its something to do with my constructors but i'm not positive. Any help would be appreciated!

Class 1 (Numbers)

package lab1;

import java.util.Random;

public class Numbers {
public int size;
public Integer[]arr = new Integer [size];

public Numbers () {
    for (int i = 0; i < size; i++){
        arr[i] = new Integer(i);
    }
}   

public Numbers(int size){
    this.size = size;
    for (int i = 0; i < size; i++){
        arr[i] = new Integer(i);
    }
}
public void generateNumbers(){
    System.out.println(arr.length);
    Random rand = new Random();
    for (int i = 0; i < arr.length; i++)
    {
        arr[i] = rand.nextInt(100);
    }
}
public int count(int val){
    int count = 0;
    for (int i = 0; i < arr.length; i++){
        if (arr[i] == val){
            count++;
        }
    }
    return count;
}

public String toString() {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < arr.length; i++){
        builder.append(arr[i]).append(" ");
    }
    return builder.toString();

}
}

Class 2 (Lab1)

package lab1;
import java.util.Scanner;
public class Lab1 {
public static void main(String[] args)
{   
    Numbers numbers =  new Numbers();
    @SuppressWarnings("resource")
    Scanner input = new Scanner(System.in);
    int menu = 1;
    while (menu != 0){
        System.out.println("1 to create array of new size\n"
                + "2 to generate random numbers into array\n"
                + "3 to count a value\n"
                + "4 to display array\n"
                + "0 to quit\n");
        menu = input.nextInt();
        switch (menu) {
        case 1: 
            System.out.println("Enter new size:\n");
            int size = input.nextInt();
            size = numbers.size;
            System.out.println("Array has been generated of size: " + numbers.size + "\n");
            break;
        case 2: 
            numbers.generateNumbers();
            System.out.println("Numbers have been generated\n");
            break;
        case 3: 
            System.out.println("Enter number to search for:\n");
            int num = input.nextInt();
            System.out.println("There are " + numbers.count(num) + " of the         number " + num);
            break;
        case 4: 
            System.out.println(numbers.toString());
            break;          
        }
    }
}
}

Upvotes: 1

Views: 208

Answers (3)

Abdelhak
Abdelhak

Reputation: 8387

Try to replace this block of code:

  public Integer[]arr = new Integer [size];

Removing this belock below because not necessary:

public Numbers () {
   for (int i = 0; i < size; i++) {
     arr[i] = new Integer(i);
   }
}   

Mantaine this below:

 public Numbers(int size) {
   this.size = size;
   for (int i = 0; i < size; i++) {
     arr[i] = new Integer(i);
   }
 }

With:

  public Integer[] arr; // here declared

  public Numbers(int size) {
    this.size = size;
    arr = new Integer[size]; //here initialize it
    for (int i = 0; i < size; i++) {
      arr[i] = new Integer(i);
    }
 }

Like this you give the size of array with user input.

Upvotes: 0

Andy Turner
Andy Turner

Reputation: 140514

First problem: you're not changing the value of size in your instance of Numbers:

size = numbers.size;

This updates the local variable size, not the member variable of numbers, overwriting the value you just read from the scanner. To update the member variable with that value:

numbers.size = size;

Second problem: you're not actually changing the size of the array.

The array is created when the instance of the class is initialized:

public int size;
public Integer[]arr = new Integer [size];

At the time it is created, size is zero, so arr is initialized to be a zero-length array. Changing the value of size won't change the size of arr automatically.

You will need to create a new instance and assign it to the arr member variable. If you are specifying this at construction time:

public Numbers(int size){
    this.size = size;
    this.arr = new Integer[size];
    for (int i = 0; i < size; i++){
        arr[i] = new Integer(i);
    }
}

Note that because size == 0 initially, your default constructor (public Numbers()) does nothing: the body of the for loop for (int i = 0; i < size; i++){ is never executed, because i == 0 and size == 0 initially, so 0 < 0 is false. You should probably just remove the default constructor, so you always have to specify a value for size to construct the instance.

If you remove the default constructor, you can remove the inline initialization of arr:

public Integer[]arr;

since a non-null value will be assigned in the constructor.

Alternatively, if you only ever use Numbers in the code you've given, you can get rid of both constructors, and just declare your fields as:

public int size = 0;
public Integer[] arr = new Integer[0];

However, in your code, you are trying to change the length of the array after it has been constructed. In this case, you would need to create a new array whenever you change the value of size, for example:

numbers.size = size;
numbers.arr = Arrays.copyOf(numbers.arr, numbers.size);

Arrays.copyOf will appropriately truncate your array or pad it with zeros, depending upon whether size is less than or greater than the current length of the array.

Note that it would be usual to encapsulate such changes in a method on Numbers:

public void setSize(int size) {
  this.size = size;
  this.arr = Arrays.copyOf(this.arr, size);
}

and make the fields private, so that they can only be updated by methods in Numbers:

private int size;
private Integer[]arr;

Finally, note that size is redundant: you can remove it, and simply use arr.length instead.

Upvotes: 1

someone_somewhere
someone_somewhere

Reputation: 811

In the constructor you create the int array. When you call new Numbers() the array size of the created object is 0. Then when you set size with numbers.size you only change the size variable you do not change the size of the array. What you what is to create a setSize(int newSize) functions which sets the array size and resizes the array. For instance if the new size is bigger then copy all the elements (values) into new array which has a few extra spaces if the new size is smaller then the current then copy the max number of elements that can fit into the new array if they are the sam size there is no need to change anything.

Upvotes: 0

Related Questions