Reputation: 105
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
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
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
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