Why int[] a = new int[1] instead of just int a? - java

Is there some hidden meaning in this code which I don't see in java? How can it be useful?
int[] a = new int[1];
than just
int a;
because from my point of view it's the same?

int a
defines a primitive int.
int[] a = new int[1];
defines an array that has space to hold 1 int.
They are two very different things. The primitive has no methods/properites on it, but an array has properties on it (length), and methods (specifically its on clone method, and all the methods of Object).
Arrays are a bit of a weird beast. They are defined in the JLS.
In practice, it would make sense to do this when you need to interact with an API that takes an array and operates on the results. It is perfectly valid to pass in a reference to an array with 0, 1, or n properties. There are probably other valid reasons to define an array with 1 element.
I can't think of any use cases where you would want to define an array with one element, just to bypass the array and get the element.

One is on the stack, one is on the heap.

One difference is that you can write a method that changes its int argument by changing arg[0]. This trick is used quite a bit in some of the code I've seen. It allows you to, for instance, return a boolean indicate success or failure and an int value that serves some other purpose. Without that trick, you'd have to return some sort of object containing the two values.

int a;
defines a variable that can hold an int
int[] a;
defines a variable that can hold an array of int
int[] a = new int[1];
does that above but also initializes it by actually creating an array (of size 1 - it can hold 1 int) and defines the variable a to hold that array, but doesn't define what's in the array.
int[] a = new int[1]{1};
does that above but also defines what's in the array: the int 1.
I suppose it does a similar thing, in that space is allocated for 1 int, but the array also defines an array. I suppose you could say these are similar:
int a = 1;
int b = a + 1;
// now b == 2
int[] a = new int[1]{1};
int b = a[0] + 1;
// now b == 2

An array of size one is not the same thing as a single integer.
Even if they carry the same information, they are different types, so you can use them in different contexts.
For example, if you have a function which performs a function on all elements of an array but you want to compute it only on one value, you should pass a int[1], because the function expects an array and wants to know how many values it should process.

All arrays in java are objects. when declaring: int x = 5; you're declaring a primitive type.
When declaring int[] x = new int[]; you're creating an object with type int[].
So int[] is actually a class.

Related

Shallow copying with primitives

From what I understand about Java (which is arguably pretty little =P), Java treats primitive values differently than objects. One example I can think of is that primitives are passed by value, while objects are passed via the value of their references.
Extending this, I have implemented code that creates an array of int, and shallow copied it over to a new array of int:
public class Test {
public static void main(String[] args){
int[] array = {2,3,4,5};
int[] copy = array;
copy[1] = 0;
for (int i : copy){
System.out.print(i);}
System.out.println();
for (int i : array){
System.out.print(i);}
}
}
However, the output is:
2045
2045
So, what puzzles me is why do both arrays change? I thought when we made a copy of the original array, we only copied over the values of the elements (since we are dealing with primitives)?
You didn't copy the array at all. What you did was make the references array and copy point to the same array in memory. Thus, when you change the array via one reference, the other reference will point to the same change.
Arrays are objects. When you set
int[] copy = array;
both copy and array refer to the same object. Your update
copy[1] = 0;
updates "both".
When you made the assignment copy[1] = 0, you told Java to take the array which copy refers to, go to position 1, and assign the value 0. Since you also have the following statement
int[] copy = array;
then copy and array refer to the same array in memory. You never really made a shallow copy, you only assigned another variable to point to the same array.
If you want to make a copy of the array, then you could try:
int[] copy = Arrays.copyOf(array, array.length);

Making a variable length array of ints

I want to have a array of integers where the length is variable. The obvious choice is to use ArrayList but can I do this for primitive types such as
ArrayList<int> myArray=new ArrayList<int>();
I dont want to use
ArrayList<Integer>
because the Integer class is clumsy in terms of coding.
EDIT: From the answers below I think the solution is to write my own Integer class.
To answer the question below about "clumsy" let me give a specific, and I would of thought common use for integers namely using the last member of the array in any place you would want the integer. If I just call the array "name" then to get the actual integer that can be operated on I need
name.get(name.size()-1).intValue();
To me this seems like an awfully unwieldy expression for a simple integer - particularly if it appears in an expression twice. It also seems that (most of the) methods available for the Integer class are absolutely redundant. Take two examples
static int compare(int a, int b)
Quite unbelievably, according to the documentation, this method returns a-b!!
static Integer valueOf(int a)
returns an Integer instance of the integer a. Can someone give me a single example where
new Integer(a)
does not achieve exactly the same result?
Method 1: (not recommended)
You can do something like this, but this doubles the code and is not efficient:
int[] a;
//get size (from command line maybe ow whatever method you want)
You can set size 0 initially, and for ex. you are transferring values from arraylist so you will have to write:
while(itr.hasNext()){
size++;} //itr is an object of Iterator
int i=0;
a=new int[size];
// then loop again to store values
while(itr.hasNext()){
a[i]=itr.next();
i++;}
Method 2:
Or you may use ArrayList without making it clumsy as follows:
ArrayList al=new ArrayList();
then you may declare Integer objects as volatile and perform operations on them just as you do with the primitive types.
Method 3: (not recommended)
Or simply write:
ArrayList al=new ArrayList();//ignore the warning about <E>
int x=2;
al.add(2);
Method 4: (recommended)
If I were you I would use ArrayList<Integer>.
UPDATE: Another thing that might work is that you may initially create an ArrayList<Integer> and store values there and later convert it to int[]
This SO answer tells about the conversion. Quoted the code form there:
public static int[] convertIntegers(List<Integer> integers)
{
int[] ret = new int[integers.size()];
for (int i=0; i < ret.length; i++)
{
ret[i] = integers.get(i).intValue();
}
return ret;
}
Hope this helps.
No it's not possible to use primitive types as generic type.
Well I would recommend you do use ArrayList and avoid primitive types in this case.
You can't change the size of an array once created. You have to allocate it bigger than you think you'll ever need
or
Accept the overhead of having to reallocate it to a new larger array and copy the data from the old to the new:
System.arraycopy(oldItems, 0, newItems, 0, 10);
But Much simpler to go with ArrayList.

Array Initialization: int versus other Objects

I'm confused on whether I need to do array initialization...
For this code:
private int[][][] rPos = new int[SIZE][SIZE][2];
Can I start using the array right way, like the following line?
getLocationOnScreen(rPos[i][j]); // pass an array of two integers
And, for this code:
View[][] allViews = new View[SIZE][SIZE];
I then have to make another nested loop, and initialize every View by calling their constructors like so:
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
allViews[i][j] = new View(ctor1, ctor2);
}
}
My question is, why didn't I need to do this for an integer array? And also, what did my "new" keyword do, when I typed View[][] allViews = new View[SIZE][SIZE];?
why didn't I need to do this for an integer array?
Whenever you create an array, the array elements are assigned the default value for the component type of that array. For an int, the default value is 0, so for an int[], all the elements will be initialized to 0 by default.
With reference type, however, the default value is null. So, the issue with those arrays are that, you might get potential NullPointerException, when you try to access some property or method in those array elements. Basically, with array of reference, we mean that the array elements are nothing but references to the actual objects. Initially they don't point to any object.
So, to access any property or method, you have to initialize each array elements to some instance, so as to avoid the NPE.
what did my "new" keyword do, when I typed View[][] allViews = new View[SIZE][SIZE];?
It created an array of array, of type View. The dimension being SIZE x SIZE. But since View is not a primitive type, but a reference type. The values are by default null, as already explained.
getLocationOnScreen(rPos[i][j]); // pass an array of two integers
Of course you passed an array of 2 integers. The component type of rPos[i][j] is an int[]. The default value is null for that too. But in this case, it wouldn't be null, as you have given the dimension for all of your inner array too.
If you change your array declaration to:
private int[][][] rPos = new int[SIZE][SIZE][]; // Missing last dimension
then the value of rPos[i][j] will be null.

Simple way to re-assign values in an array

I'm having trouble reassigning values in an array.
public static void main(String[] {
int[] arrayOfIntegers = new int[4];
arrayOfIntegers[0] = 11;
arrayOfIntegers[1] = 12;
arrayOfIntegers[2] = 13;
arrayOfIntegers[3] = 14;
arrayOfIntegers = {11,12,15,17};
}
Why am I unable to reassign values in the manner that I've attempted? If I can't do it, why can't I do it?
Why am I unable to reassign values in the manner that I've attempted? If I can't do it, why can't I do it?
Because Java doesn't have destructuring assignment like some other languages do.
Your choices are:
Assign a new array to the array variable as shown by Rohit and Kayaman, but that's not what you asked. You said you wanted to assign to the elements. If you assign a new array to ArrayOfIntegers, anything else that has a reference to the old array in a different variable or member will still refer to the old array.
Use System.arraycopy, but it involves creating a temporary array:
System.arraycopy(new int[]{11,12,15,17},
0,
ArrayOfIntegers,
0,
ArrayOfIntegers.length);
System.arraycopy will copy the elements into the existing array.
You need to provide the type of array. Use this:
arrayOfIntegers = new int[] {11,12,15,17};
From JLS Section 10.6:
An array initializer may be specified in a declaration (§8.3, §9.3, §14.4), or as part of an array creation expression (§15.10), to create an array and provide some initial values.
If you are trying to re-assign array elements in some range, you can't do that with direct assignment. Either you need to assign values at indices individually, or use the way as given by #TJCrowder in his answer.
The correct syntax is:
arrayOfIntegers = new int[]{11,12,15,17};

Passing array as an argument: C and Java

Before I ask my question, I will note that I know:
In C, we can call a method by value as well by reference
In Java, we can only call a method by value ( when we pass an Object, we are passing the value of the object reference not the object reference itself )
In C and Java context, there is a difference between pointers and reference.
Now to the question:
Consider an array:
arr = {1,2,3,4,5} //len =5
In C, I can do the following two things:
foo(arr, len);
bar (arr+ 2, len -2);
Function definitions:
foo(int *a, int l) {
...
printf("%d", &a[0]; //prints 1
...
}
bar (int *a, int l){
printf("%d", &a[0]; //prints 3
...
}
As we can see array a in function bar starts with the value 3, as it contains the address of arr[2](the original array). This is a neat way of passing arrays in C, if we want to treat a sub-array as a new array with starting index 0.
I was wondering if same can be achieved in Java not withstanding that the following call has different meanings in C and Java:
foo(arr);
yes, just add a parameter int off or use the IntBuffer class.
void foo(int[] a,int off, int l) {
...
System.out.printf("%d", a[off]; //prints 1
...
...
}
f(a,2,l);
void foo(IntBuffer a,int l){
System.out.printf("%d",a.get(0));
}
IntBuffer buffer = IntBuffer.wrap(a,2,a.length-2);
foo(buffer,l);
If your question is about whether you can address the elements of the array by doing pointer arithmetic like in arr + 2, then the answer is no.
However, you can achieve the same effect by passing in the array and the position where you want start reading the array.
The underlying structure of the array in java has an extra element at the head that indicates it's length. So your original array would be {len, 1, 2, 3, 4, 5} as stored by the JVM. This is done to keep java 'safe' from out of index operations on the array. This also makes it almost impossible to do pointer arithmetic in java.
To do something like this in java you would typically use some sort of Buffer class to wrap your array.
Java lacks native slicing functions (as the implicit one you have in C regarding the start of the array or the explicit ones you have in a few modern languages) but it's easy to build your own class wrapping an array, an index and a length if you need it.
The idea is the same when you pass arrays in C and Java.
In Java, all that are passed for objects are references to them, namely pointers. In Java, you never say: A *a = new A(); you just write A a = new A(); The lack of * is the difference. Otherwise, A behaves exactly like a pointer.
Primitive variables are passed by value.

Categories