Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding size i.e. number of non-null elements stored in array in Java

Tags:

java

arrays

Purpose : Array.length gives us storage initialized to array. But wanted to find out count of non-null elements stored in array out of total storage initialized. I know many approaches are possible but here question is related to approach which I used.

Since ArrayList has a size() method which gives us count of actual elements stored regardless of total storage initialized.

So, I thought of converting array to ArrayList and finding out the size. Hence I used Arrays.asList(a).size() as shown below:

public class Driver {

    public static void main(String []args)
    {
        int a[] = new int[10];
        a[0]=30;
        a[1]=100;
        a[2]=33;
        System.out.println((Arrays.asList(a)).size() );
    }

Strangely , it returns result as 1 regardless of the a[0], a[1], a[2].

Same steps if we do with ArrayList instead of Array gives us result 3:

{
    List<Integer> temp = new ArrayList<Integer>(20); 
    System.out.println(temp.size()); 
    temp.add(20); 
    temp.add(40); 
    System.out.println(temp.size()); 
}

Result is 0 2.

Question: Should be agree that something is wrong with asList API of Arrays utitlity like bug or limitation?

Remarks: Looking at internal implementation, I understand that asList invokes constructor of ArrayList:

  public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
        .....
  }

It again invokes the collection's toArray. But then not sure why we are getting answer as 1 since elementData.length should have stored in size value 10?

like image 853
DPKGRG Avatar asked Sep 06 '18 05:09

DPKGRG


People also ask

How do you find the size of an array in Java?

To get the size of a Java array, you use the length property. To get the size of an ArrayList, you use the size() method.

How do you find the size of an array?

We can find the size of an array using the sizeof() operator as shown: // Finds size of arr[] and stores in 'size' int size = sizeof(arr)/sizeof(arr[0]);

Which method is used to get the number of elements in an array?

sizeof() Function: The sizeof() function is used to count the number of elements present in an array or any other countable object.


1 Answers

There are three very different concepts that you are somehow attempting to equate here.

First there's null elements in a list or array. null is a perfectly valid value to have in either. It is not the same as being uninitialized. In fact, arrays of any non-primitive type are explicitly initialized to null by default.

Then there are unused elements in a list. When you do

ArrayList<Integer> a = new ArrayList<>(20);
a.add(null);

you will have a List of size 1. null is a totally valid reference to stick in a list, and the capacity has nothing to do with the size. The 20 you passed to the constructor is just a hint not to reallocate memory until you've inserted 20 actual elements into the list. Those 19 other elements are not null. They literally don't exist.

Third, there is the issue of primitive arrays. When you create a primitive array, it will have a fixed length and every element contains a valid value. By default, arrays are zeroed out with false, 0, 0L, 0.0f, 0.0, or whatever is appropriate for the type. Your code creates an array with three non-zero elements and seven zeros. Primitives are not references, so can never be null. Even if they could, making a List from a 10 element array would give you a size of 10.

Your attempt at creating an ArrayList is in no way equivalent to applying Arrays.asList(), even if that were to work. Creating a list and adding three elements to it will make a list of size three. On top of that, keep in mind that a List can only hold references, in your case to the boxed type Integer. An Integer reference can be null and still be a valid list item, but can't be unboxed into a primitive value.

Finally, you can't convert an array of primitives into a list using asList. asList accepts varargs, rather than a single list, which is why you always end up with one element list. The problem here is actually that you have a list of primitives: an array of references would be expanded just fine. An alternative in Java 8 is

List<Integer> list = Arrays.stream(ints).boxed().collect(Collectors.toList());

Notice the explicit boxing operation. The size of your list will still be 10, not 3.

Reference: How to convert int[] into List<Integer> in Java?

like image 102
Mad Physicist Avatar answered Oct 31 '22 10:10

Mad Physicist