You have created the array already, and your setArraySize changes the size variable only.

public class SortTests {
    private static int size; <-- setArraySize affects this.
    private static int [] myArray = new int [size];  <-- setArraySize does not affect this.  Size was defaulted to 0, so myArray will always be a 0-sized array.

Change to something similar to this:

public class SortTests {
    private static int [] myArray = new int [size]; 

    public static void setArraySize() {
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter a whole number to specify the size of the array: ");
        int size = scan.nextInt();
        myArray = Arrays.copyOf(myArray, size);
    }
Answer from John on Stack Overflow
Top answer
1 of 2
2

You have created the array already, and your setArraySize changes the size variable only.

public class SortTests {
    private static int size; <-- setArraySize affects this.
    private static int [] myArray = new int [size];  <-- setArraySize does not affect this.  Size was defaulted to 0, so myArray will always be a 0-sized array.

Change to something similar to this:

public class SortTests {
    private static int [] myArray = new int [size]; 

    public static void setArraySize() {
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter a whole number to specify the size of the array: ");
        int size = scan.nextInt();
        myArray = Arrays.copyOf(myArray, size);
    }
2 of 2
0

To add to @John's answer

This is not the correct way to initialize Arrays. You're using the compiler-provided default value for for an int (which is 0) to initialize the length of myArray. The initialization of myArray occurs on class instantiation. This means that size is read once when the class is created, then discarded. Thus, the initial array size from the code you provided will always be the length of the original value of size. Since size was 0, it is proper for the array to be empty.

If you want to retrieve an array of a specific size, you need to create it dynamically after the user has submitted his input (Per @John's answer)

Additionally, you will definitely want to consider using Java's Collections framework instead of dealing with raw Arrays. Array sizes are managed dynamically.

package com.company;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class ScannerToArraySize {

    private static Integer size;
    private static ArrayList<Integer> myArray = new ArrayList<>();

    public static void setArraySize() {
        Scanner  scan = new Scanner(System.in);
        System.out.println("Enter a whole number to specify the size of the array: ");
        size = scan.nextInt();
    }

    public static void fillArray() {
        Random randNum = new Random();
        for (int i = 0; i < size; i++) {
            myArray.add(randNum.nextInt(100));
        }
    }

    public static void printArray(){
        for (Integer integer : myArray) {
            System.out.println(integer);
        }
    }
}
Top answer
1 of 16
3263

You can either use array declaration or array literal (but only when you declare and affect the variable right away, array literals cannot be used for re-assigning an array).

For primitive types:

int[] myIntArray = new int[3]; // each element of the array is initialised to 0
int[] myIntArray = {1, 2, 3};
int[] myIntArray = new int[]{1, 2, 3};

// Since Java 8. Doc of IntStream: https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html

int [] myIntArray = IntStream.range(0, 100).toArray(); // From 0 to 99
int [] myIntArray = IntStream.rangeClosed(0, 100).toArray(); // From 0 to 100
int [] myIntArray = IntStream.of(12,25,36,85,28,96,47).toArray(); // The order is preserved.
int [] myIntArray = IntStream.of(12,25,36,85,28,96,47).sorted().toArray(); // Sort 

For classes, for example String, it's the same:

String[] myStringArray = new String[3]; // each element is initialised to null
String[] myStringArray = {"a", "b", "c"};
String[] myStringArray = new String[]{"a", "b", "c"};

The third way of initializing is useful when you declare an array first and then initialize it, pass an array as a function argument, or return an array. The explicit type is required.

String[] myStringArray;
myStringArray = new String[]{"a", "b", "c"};
2 of 16
336

There are two types of array.

One Dimensional Array

Syntax for default values:

int[] num = new int[5];

Or (less preferred)

int num[] = new int[5];

Syntax with values given (variable/field initialization):

int[] num = {1,2,3,4,5};

Or (less preferred)

int num[] = {1, 2, 3, 4, 5};

Note: For convenience int[] num is preferable because it clearly tells that you are talking here about array. Otherwise no difference. Not at all.

Multidimensional array

Declaration

int[][] num = new int[5][2];

Or

int num[][] = new int[5][2];

Or

int[] num[] = new int[5][2];

Initialization

 num[0][0]=1;
 num[0][1]=2;
 num[1][0]=1;
 num[1][1]=2;
 num[2][0]=1;
 num[2][1]=2;
 num[3][0]=1;
 num[3][1]=2;
 num[4][0]=1;
 num[4][1]=2;

Or

 int[][] num={ {1,2}, {1,2}, {1,2}, {1,2}, {1,2} };

Ragged Array (or Non-rectangular Array)

 int[][] num = new int[5][];
 num[0] = new int[1];
 num[1] = new int[5];
 num[2] = new int[2];
 num[3] = new int[3];

So here we are defining columns explicitly.
Another Way:

int[][] num={ {1}, {1,2}, {1,2,3,4,5}, {1,2}, {1,2,3} };

For Accessing:

for (int i=0; i<(num.length); i++ ) {
    for (int j=0;j<num[i].length;j++)
        System.out.println(num[i][j]);
}

Alternatively:

for (int[] a : num) {
  for (int i : a) {
    System.out.println(i);
  }
}

Ragged arrays are multidimensional arrays.
For explanation see multidimensional array detail at the official java tutorials

Top answer
1 of 5
9

You cannot do it like that. In Java, the type of an array does not include it's size. See my answer to this earlier question. (Ignore the part about abstract methods in that question ... it's not the real issue.)

The size of an array is determined by the expression that creates it; e.g. the following creates a char array that contains 5 characters, then later replaces it with another array that contains 21 characters.

public char[] language = new char[5];
...
language = new char[21];

Note that the creation is done by the expression on the RHS of the equals. The length of an array is part of its 'value', not its 'type'.

2 of 5
5

To quote the JLS :

An array's length is not part of its type.

To initialize an array you should do :

public char[] language = new char[5];

Other solutions are

public char[] language = {0, 0, 0, 0, 0};

or

public char[] language;
language = new char[5];

In Java, the array declaration can't contain the size of the array; we only know the variable will contain an array of a specific type. To have an array initialized (and with a size) you have to initialize it either by using new or by using a shortcut which allows to initialize and set values for an array at the same time.

Best way to have to check if an array has a specified size, is actually checking the size of the array yourself with something like if(array.length == 5).


Resources :

  • JLS - Array Types
  • JLS - Array Creation Expressions

On the same topic :

  • abstract method of a set length array in java?
Top answer
1 of 3
43

Abridged:

For an array: use .length.

For a Collection (or Map): use .size().

For a CharSequence (which includes CharBuffer, Segment, String, StringBuffer, and StringBuilder): use .length().


Arrays

One would use the .length property on an array to access it. Despite an array being a dynamically created Object, the mandate for the length property is defined by the Java Language Specification, ยง10.3:

An array is created by an array creation expression (ยง15.10) or an array initializer (ยง10.6).

An array creation expression specifies the element type, the number of levels of nested arrays, and the length of the array for at least one of the levels of nesting. The array's length is available as a final instance variable length.

An array initializer creates an array and provides initial values for all its components.

Since the length of an array cannot change without the creation of a new array instance, repeated accesses of .length will not change the value, regardless of what is done to the array instance (unless its reference is replaced with a differently sized array).

As an example, to get the length of a declared one-dimensional array, one would write this:

double[] testScores = new double[] {100.0, 97.3, 88.3, 79.9};
System.out.println(testScores.length); // prints 4

To get lengths in an n-dimensional array, one needs to bear in mind that they are accessing one dimension of the array at a time.

Here's an example for a two-dimensional array.

int[][] matrix
      = new int[][] {
                         {1, 2, 3, 4},
                         {-1, 2, -3, 4},
                         {1, -2, 3, -4}
    };

System.out.println(matrix.length); // prints 3 (row length or the length of the array that holds the other arrays)
System.out.println(matrix[0].length); // prints 4 (column length or the length of the array at the index 0)

This is important to make use of, especially in the case of jagged arrays; the columns or rows may not always line up all the time.

Collections (Set, List, etc.)

For every object that implements the Collection interface, they will have a method called size() with which to access the overall size of the collection.

Unlike arrays, collections are not fixed length, and can have elements added or removed at any time. A call to size() will produce a nonzero result if and only if there has been anything added to the list itself.

Example:

List<String> shoppingList = new ArrayList<>();
shoppingList.add("Eggs");
System.out.println(shoppingList.size()); // prints 1

Certain collections may refuse to add an element, either because it's null, or it's a duplicate (in the case of a Set). In this case, repeated additions to the collection will not cause the size to increment.

Example:

Set<String> uniqueShoppingList = new HashSet<>();
uniqueShoppingList.add("Milk");
System.out.println(uniqueShoppingList.size()); // prints 1
uniqueShoppingList.add("Milk");
System.out.println(uniqueShoppingList.size()); // prints 1

Accessing the size of a List<List<Object>>* is done in a similar way to a jagged array:

List<List<Integer>> oddCollection = new ArrayList<>();
List<Integer> numbers = new ArrayList<Integer>() {{
    add(1);
    add(2);
    add(3);
}};
oddCollection.add(numbers);
System.out.println(oddCollection.size()); // prints 1
System.out.println(oddCollection.get(0).size()); // prints 3

*: Collection doesn't have the get method defined in its interface.

As an aside, a Map is not a Collection, but it also has a size() method defined. This simply returns the number of key-value pairs contained in the Map.

String

A String has a method length() defined. What it does is print the number of characters present in that instance of the String.

Example:

System.out.println("alphabet".length()); // prints 8
2 of 3
6

Don't forget CollectionUtils.size() from the commons library, its null safe so you don't have to null check beforehand.

Top answer
1 of 2
4

1

You should declare the fields elements and top as private. Also, since you do not expand the storage array (elements), you can declare it final as well.

2

It's kind of funny that your stack grows from larger indices towards smaller ones. I suggest you rename top to size, and make your stack grow towards larger indices. That way, the value of size will be the storage array index at which the next pushed element would be placed.

3

In the constructor, you call erase that sets all the storage array components to null. Don't do this, JVM initializes all object array components to null by default.

2 of 2
3

Suppressing warnings

It's recommended to suppress the smallest possible unit. For example here:

@SuppressWarnings("unchecked")
public void setSize(int size){
    this.elements = (E[]) new Object[size];
    resetTop(false);
}

Instead of suppressing the unchecked warning in the entire method, it would be better to do it for the one offending statement, like this:

public void setSize(int size){
    @SuppressWarnings("unchecked")
    this.elements = (E[]) new Object[size];
    resetTop(false);
}

In some methods you suppress unnecessarily, for example here:

@SuppressWarnings("unchecked")
public FixedStack(int capacity) {
    setSize(capacity);
    resetTop(false);
}

I'm going to take a wild guess that in a previous version there was indeed an offending statement in this method. You suppressed the warning at the method level, then refactored the code, the offending statement got moved somewhere else, and you forgot to remove the suppression. This mistake would not have happened if you had suppressed at the statement level, you see?

Encapsulation

I'm wondering if you really intended for some of the methods to be public. For example setSize and resetTop. These methods manipulate the internal state of the stack, which is not common in stack implementations. I think these should be private, to hide from users.

On a related note, it would be better to extract the interface of the fixed stack, which would make it perfectly clear whih methods are intentionally exposed.

Avoid confusion by better names

I purposely throw a custom StackOverflowException subclassing java.lang.IndexOutOfBoundsException rather than a java.lang.StackOverflowError as the latter indicates an overflow of the JVM internal stack specifically.

To avoid confusion, I propose the name FixedStackOverflowException for your custom exception class.

Find elsewhere
๐ŸŒ
TheServerSide
theserverside.com โ€บ blog โ€บ Coffee-Talk-Java-News-Stories-and-Opinions โ€บ Java-array-size-explained-by-example
Java array size, length and loop examples
The 32-bit Java int can go to a maximum of 2,147,483,647, so that is the theoretical maximum Java array size. However, virtual machines for different operating systems may not allocate every available bit to the elements in the Java array. Thus, the maximum number of elements a Java array can hold is typically a little less than the upper limit of a Java int. In Java, once you set the Java array size it is fixed, and it canโ€™t be changed.
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 33226364 โ€บ stack-array-implementation-returning-size-of-array
java - stack array implementation, returning size of array - Stack Overflow
I am trying to find the number of elements in a stack (I am implementing an array). So far I have int size = 0; while( top != -1 ){ size++; pop(); } return size; } This works perfe...
๐ŸŒ
Coderanch
coderanch.com โ€บ t โ€บ 411644 โ€บ java โ€บ declare-size-Array-java
Why cant we declare the size of Array in java? (Beginning Java forum at Coderanch)
Once you create the 'house' with five bedrooms via the "new int[5]", you can now write the address on the paper. so the reason "int[2] array;" is wrong is because the reference doesn't know about the size of the array... it just needs to know it will point to an array that holds 'int's. There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors ... One more think I observe, When a programmer has a strong background of C and C++, the code : int arr[5]; seems to be perfectly legal and good to him, but in Java arrays are handled as object so new has to be ther to make it sense ..
Top answer
1 of 2
1

As mentioned in @rolfl's to your later question, there is limited value in this class as elements cannot be easily retrieved.

Putting aside the obvious improvements to the seemingly toy implementations, you have a mistake in describing whether the stack has 'overflow' or 'underflow': the meanings should be inversed. When you try to push(int) to a full stack, that is known as an overflow, and you need to check whether the stack is empty when pop()-ping instead of checking for 'overflows'.

To better indicate error conditions such as those mentioned above, you can make use of throwing Exceptions instead of a simple System.out.println(). In fact, I will suggest using System.err.println() at the very least to differentiate between normal and error 'outputs'.

A Java 8 way of printing the contents of the stack is to use Arrays.stream(int[]):

public void display() {
    Arrays.stream(stack).forEach(System.out::println);
}

This uses System.out.println(int) as a method reference to print each int value on the console.

Simply running through some test operations in the main() method is also barely enough, you should consider proper unit testing techniques such as using a testing framework that can arrange-act-assert for you.

Last but not least, you should also take a look at the standard JDK classes' stack implementations for greater inspiration, such as the Deque interface.

2 of 2
1

Why not just throw exceptions instead of writing something to the console? Also make use of generics? It is highly unlikely that Stack will be used only for integers. A stack implementation using arrays is good, but most of the time people also use LinkedList to implement it, so that you do not have to resize once you exceed INITIAL_CAPACITY. It all comes down to the user's choice.

Here are two implementations which can be useful:

Array implementation of Java Stack

My own Stack Implementation in Java

๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ can-you-change-size-of-array-in-java-once-created
Can you change size of Array in Java once created?
In Java, arrays are treated as referenced types you can create an array using the new keyword similar to objects and populate it using the indices as โˆ’ ยท The size of an array is fixed, if you create an array using the new keyword you need to specify the length/size of it in the constructor as โˆ’
Top answer
1 of 16
192

No you can't change the size of an array once created. You either have to allocate it bigger than you think you'll need or accept the overhead of having to reallocate it needs to grow in size. When it does you'll have to allocate a new one and copy the data from the old to the new:

int[] oldItems = new int[10];
for (int i = 0; i < 10; i++) {
    oldItems[i] = i + 10;
}
int[] newItems = new int[20];
System.arraycopy(oldItems, 0, newItems, 0, 10);
oldItems = newItems;

If you find yourself in this situation, I'd highly recommend using the Java Collections instead. In particular ArrayList essentially wraps an array and takes care of the logic for growing the array as required:

List<XClass> myclass = new ArrayList<XClass>();
myclass.add(new XClass());
myclass.add(new XClass());

Generally an ArrayList is a preferable solution to an array anyway for several reasons. For one thing, arrays are mutable. If you have a class that does this:

class Myclass {
    private int[] items;

    public int[] getItems() {
        return items;
    }
}

you've created a problem as a caller can change your private data member, which leads to all sorts of defensive copying. Compare this to the List version:

class Myclass {
    private List<Integer> items;

    public List<Integer> getItems() {
        return Collections.unmodifiableList(items);
    }
}
2 of 16
32

In java array length is fixed.

You can use a List to hold the values and invoke the toArray method if needed See the following sample:

import java.util.List;
import java.util.ArrayList;
import java.util.Random;

public class A  {

    public static void main( String [] args ) {
        // dynamically hold the instances
        List<xClass> list = new ArrayList<xClass>();

        // fill it with a random number between 0 and 100
        int elements = new Random().nextInt(100);  
        for( int i = 0 ; i < elements ; i++ ) {
            list.add( new xClass() );
        }

        // convert it to array
        xClass [] array = list.toArray( new xClass[ list.size() ] );


        System.out.println( "size of array = " + array.length );
    }
}
class xClass {}
๐ŸŒ
Rip Tutorial
riptutorial.com โ€บ how do you change the size of an array?
Java Language Tutorial => How do you change the size of an array?
The simple answer is that you cannot do this. Once an array has been created, its size cannot be changed.
๐ŸŒ
Quora
quora.com โ€บ Can-we-able-to-change-the-size-of-the-array-during-runtime-in-Java
Can we able to change the size of the array during runtime in Java? - Quora
Answer (1 of 2): No, you can't and that's why we use linked list. But there is a concept called dynamic arrays. In these arrays whenever the number of elements stored reaches the initial capacity of the array a new array is created and all the ...
๐ŸŒ
Educative
educative.io โ€บ answers โ€บ how-to-resize-an-array-in-java
How to resize an array in Java
Line 8: We set oldArray to null, freeing up the memory it was using. Line 10: We print out the contents of newArray. The java.util.Arrays class has a method named copyOf(), which can also be used to increase or decrease the size of an array.