What is the difference between the two following methods of array initialization:
Object[] oArr = new Object[] {new Object(), new Object()};
Object[] oArr = {new Object(), new Object()};
Is it related to heap/stack allocation?
Thanks!
None at all - they're just different ways of expressing the same thing.
The second form is only available in a variable declaration, however. For example, you cannot write:
foo.someMethod({x, y});
but you can write:
foo.someMethod(new SomeType[] { x, y });
The relevant bit of the Java language specification is section 10.6 - Array Initializers:
An array initializer may be specified in a declaration,
or as part of an array creation expression (§15.10), creating an array and providing some initial values:
Absolutely identical. The second is allowed shorthand for the first (only when, as here, it is done as part of a variable declaration.
In Java all objects live in the heap, as arrays are objects in Java they lives in the stack.
for these two there is no difference in result, you 'll got two array objects with the same elements.
However sometimes you will encounter some situations where you can't use them, for example you don't know the elements of the array. then you get stuck with this form:
Object [] array=new Object[size];
There is a small and catchy difference still!
You can do
int[] arr;
arr= {1,2,3}; // Illegal
But you can very well do
int[] arr;
arr = new [] {1,2,3} //Legal
Also if you are to initialize later then you cannot do
int arr;
arr = new [] {1,2,3} //Illegal
Related
int[] myArray = new int[5];
Hey guys,
I know there are other ways to initialize an array like:
int[] myArray = {1,2,3,4,5};
But can you tell me what the second int in the top example stands for?
I think the first "int" already specifies the array to have integer values, doesn't it?
The construct in int[] myArray = { 1, 2, 3, 4, 5 }; is handled as a special case. The compiler knows that { 1, 2, 3, 4, 5 } is creating an int[] array because of the declared type.
However, the full array creation syntax for the int array is new int[5] (it can vary), which tells the compiler that a new int[] array is created, regardless of the declared type:
For example, you can declare an Object variable, and assign an int array to it:
Object myArrayObject = new int[5]; //OK: this creates an int array
Whereas this won't work:
Object myArrayObject = { 1, 2, 3, 4, 5 }; //won't compile
With int and other primitive types, you're correct, the double declaration is largely superfluous.
But consider this example:
Object [] array = new String[5];
This is valid Java code (even though it is slightly broken*).
On a more general level it follows the same pattern as when you're initialising any variable with a new object:
Foo foo = new Foo();
The first Foo is the type of the variable (what shape the box is), the second is the type of the actual object (what shape is the thing you put in the box).
Note: Starting with Java 10, you can declare local variables with the keyword var, thus eliminating the need to specify the type twice:
var array = new int[5];
The compiler will infer from this that the type of array will be the same as the object it's initialised with. (int[] in this case).
*It is broken because if you try to put into the array anything other than a String, the code only fails at runtime, not during compilation.
So when you type new, you are specifying you want java to allocate memory to the heap. How much memory? Ah yes enough memory for 5 integers, int[5]. So java will allocated enough consecutive memory on the heap to store 5 integers.
int[] myArray = new int[5];
means you declare an array that can contain integer values called myArray (by int[] myArray) and you define it as an integer-array of size 5 afterwards (= new int[5];);
These steps are made inline, you could alternatively do the same in two lines:
int[] myArray; // declaration
myArray = new int[5]; // definition
First is the data type of the array. And other int is for the intialization of 5 integer object in the array
Say I want to create a List which contains Integer[] arrays. But
Integer[] foo = {1,2,3};
List<Integer[]> bar = Arrays.asList(foo);
The second line wouldn't compile, because Arrays.asList(foo) will return a List with three Integer elements(namely 1, 2, 3), not a List with a single Integer[] element.
Since the documentation states the parameter of asList method as varargs of type T, I don't understand why the compiler doesn't interpret the second line as single argument of type Integer[] given. How do I get a List of single Array element?
List<Integer[]> bar = new ArrayList<Integer[]>(Arrays.asList(foo));
This is what I actually wanted to do, but it also doesn't compile, for the same reason I believe.
A very similar question was just asked the other day, but I suppose this is different enough for it not to be a duplicate. You need to explicitly specify the generic type for it to compile, like so:
Integer[] foo = {1, 2, 3};
List<Integer[]> list = Arrays.<Integer[]>asList(foo);
Unless you actually need the ability to set the element to a different array, you can use:
List<Integer[]> list = Collections.singletonList(foo);
This is more efficient, because it is specialized to just holding one element: no array has to be created, contains is simply checking equality, size is always 1 etc.
No. Arrays.asList takes a projection of your current array and flattens the first dimension into a List. Since you only have one dimension, all of those elements get collected into the list.
You could do it if you had an Integer[][].
Note: asList accepts a vararg of T (so T...), which is effectively T[]. If you substitute that with Integer[][], you get Integer[], since one dimension of your Integer[][] will satisfy T...'s type requirement.
Varargs in java is just a syntactic sugar in Java. So, there is no difference between.
Arrays.asList(1,2,3) and Arrays.asList(new Integer[]{1,2,3}).
So what you can do like below to solve your problem.
Integer[][] foo = {{1,2,3}};
List<Integer[]> bar = Arrays.asList(foo);
Arrays.asList() generates list of contents of array passed as argument. If you need to create list of arrays, you need to pass to this method array of arrays (e.g. Integer[][]).
When you pass to method Integer[] as argument instead of Integer[][] , it makes a list of contents of that array (in that case these are Integers not arrays of Integers).
Wrapping your array in another array will achieve what you want:
Integer[] foo = {1,2,3};
List<Integer[]> bar = Arrays.asList(new Integer[][]{foo});
// OR
Integer[][] foo = {{1,2,3}};
List<Integer[]> bar = Arrays.asList(foo);
You could also just manually set the first element: (I'd probably say this is more readable, but opinions may vary)
Integer[] foo = {1,2,3};
List<Integer[]> bar = new ArrayList<>();
bar.set(0, foo);
I have some questions regarding arrays in java:
How many objects are created in the following expressions?
(a) new int[0] : There is one object created, an array of size 0.???
(b) new int[2][2] : There is one object created, an array with 2 rows and columns.???
(c) new int[2][] : There is no object created???
I was wondering if my solutions next to the expressions are correct. If not, hopefuly you can help and give me some explanation about them. I don't really get what im supposed to do.
Thanks in advance!
The following is an excerpt from the Java Specification:
In the Java programming language arrays are objects (§4.3.1), are
dynamically created, and may be assigned to variables of type Object
(§4.3.2). All methods of class Object may be invoked on an array.
This means every array is an own object, which makes your answer a) correct.
b) 3 objects are created: 1 array first and two arrays containing each 2 ints. I wouldn't count the int-entries as they are primitive types in Java.
c) 1 object is created: 1 array with two null-entries.
new int[0]
Yes this is an empty array, one object is created.
int[] emptyArray = new int[0];
System.out.println(emptyArray.length); // Outputs 0
new int[2][2]
Yes this creates and array with 2 rows and columns, 3 objects are created.
int[][] bar = new int[2][2];
System.out.println(bar.getClass()); // Outputs class [[I
int[] bar1 = bar[0];
System.out.println(bar1.getClass()); // Outputs class [I
int[] bar2 = bar[1];
System.out.println(bar2.getClass()); // Outputs class [I
new int[2][]
Java supports jagged arrays. This means when you create int[2][] this means you have an array of various sized int[]. Only 1 object is created here.
int[][] foo = new int[2][];
System.out.println(foo[0]); // Outputs null
System.out.println(foo[1]); // Outputs null
foo[0] = new int[10];
foo[1] = new int[5];
I am new to Java and for the time created an array of objects in Java.
I have a class A for example -
A[] arr = new A[4];
But this is only creating pointers (references) to A and not 4 objects. Is this correct? I see that when I try to access functions/variables in the objects created I get a null pointer exception.
To be able to manipulate/access the objects I had to do this:
A[] arr = new A[4];
for (int i = 0; i < 4; i++) {
arr[i] = new A();
}
Is this correct or am I doing something wrong? If this is correct its really odd.
EDIT: I find this odd because in C++ you just say new A[4] and it creates the four objects.
This is correct.
A[] a = new A[4];
...creates 4 A references, similar to doing this:
A a1;
A a2;
A a3;
A a4;
Now you couldn't do a1.someMethod() without allocating a1 like this:
a1 = new A();
Similarly, with the array you need to do this:
a[0] = new A();
...before using it.
This is correct. You can also do :
A[] a = new A[] { new A("args"), new A("other args"), .. };
This syntax can also be used to create and initialize an array anywhere, such as in a method argument:
someMethod( new A[] { new A("args"), new A("other args"), . . } )
Yes, it creates only references, which are set to their default value null. That is why you get a NullPointerException You need to create objects separately and assign the reference. There are 3 steps to create arrays in Java -
Declaration – In this step, we specify the data type and the dimensions of the array that we are going to create. But remember, we don't mention the sizes of dimensions yet. They are left empty.
Instantiation – In this step, we create the array, or allocate memory for the array, using the new keyword. It is in this step that we mention the sizes of the array dimensions.
Initialization – The array is always initialized to the data type’s default value. But we can make our own initializations.
Declaring Arrays In Java
This is how we declare a one-dimensional array in Java –
int[] array;
int array[];
Oracle recommends that you use the former syntax for declaring arrays.
Here are some other examples of legal declarations –
// One Dimensional Arrays
int[] intArray; // Good
double[] doubleArray;
// One Dimensional Arrays
byte byteArray[]; // Ugly!
long longArray[];
// Two Dimensional Arrays
int[][] int2DArray; // Good
double[][] double2DArray;
// Two Dimensional Arrays
byte[] byte2DArray[]; // Ugly
long[] long2DArray[];
And these are some examples of illegal declarations –
int[5] intArray; // Don't mention size!
double{} doubleArray; // Square Brackets please!
Instantiation
This is how we “instantiate”, or allocate memory for an array –
int[] array = new int[5];
When the JVM encounters the new keyword, it understands that it must allocate memory for something. And by specifying int[5], we mean that we want an array of ints, of size 5.
So, the JVM creates the memory and assigns the reference of the newly allocated memory to array which a “reference” of type int[]
Initialization
Using a Loop – Using a for loop to initialize elements of an array is the most common way to get the array going. There’s no need to run a for loop if you are going to assign the default value itself, because JVM does it for you.
All in One..! – We can Declare, Instantiate and Initialize our array in one go. Here’s the syntax –
int[] arr = {1, 2, 3, 4, 5};
Here, we don’t mention the size, because JVM can see that we are giving 5 values.
So, until we instantiate the references remain null. I hope my answer has helped you..! :)
Source - Arrays in Java
You are correct. Aside from that if we want to create array of specific size filled with elements provided by some "factory", since Java 8 (which introduces stream API) we can use this one-liner:
A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
Stream.generate(() -> new A()) is like factory for separate A elements created in a way described by lambda, () -> new A() which is implementation of Supplier<A> - it describe how each new A instances should be created.
limit(4) sets amount of elements which stream will generate
toArray(A[]::new) (can also be rewritten as toArray(size -> new A[size])) - it lets us decide/describe type of array which should be returned.
For some primitive types you can use DoubleStream, IntStream, LongStream which additionally provide generators like range rangeClosed and few others.
Here is the clear example of creating array of 10 employee objects, with a constructor that takes parameter:
public class MainClass
{
public static void main(String args[])
{
System.out.println("Hello, World!");
//step1 : first create array of 10 elements that holds object addresses.
Emp[] employees = new Emp[10];
//step2 : now create objects in a loop.
for(int i=0; i<employees.length; i++){
employees[i] = new Emp(i+1);//this will call constructor.
}
}
}
class Emp{
int eno;
public Emp(int no){
eno = no;
System.out.println("emp constructor called..eno is.."+eno);
}
}
The genaral form to declare a new array in java is as follows:
type arrayName[] = new type[numberOfElements];
Where type is a primitive type or Object. numberOfElements is the number of elements you will store into the array and this value can’t change because Java does not support dynamic arrays (if you need a flexible and dynamic structure for holding objects you may want to use some of the Java collections).
Lets initialize an array to store the salaries of all employees in a small company of 5 people:
int salaries[] = new int[5];
The type of the array (in this case int) applies to all values in the array. You can not mix types in one array.
Now that we have our salaries array initialized we want to put some values into it. We can do this either during the initialization like this:
int salaries[] = {50000, 75340, 110500, 98270, 39400};
Or to do it at a later point like this:
salaries[0] = 50000;
salaries[1] = 75340;
salaries[2] = 110500;
salaries[3] = 98270;
salaries[4] = 39400;
More visual example of array creation:
To learn more about Arrays, check out the guide.
Yes it is correct in Java there are several steps to make an array of objects:
Declaring and then Instantiating (Create memory to store '4' objects):
A[ ] arr = new A[4];
Initializing the Objects (In this case you can Initialize 4 objects of class A)
arr[0] = new A();
arr[1] = new A();
arr[2] = new A();
arr[3] = new A();
or
for( int i=0; i<4; i++ )
arr[i] = new A();
Now you can start calling existing methods from the objects you just made etc.
For example:
int x = arr[1].getNumber();
or
arr[1].setNumber(x);
For generic class it is necessary to create a wrapper class.
For Example:
Set<String>[] sets = new HashSet<>[10]
results in: "Cannot create a generic array"
Use instead:
class SetOfS{public Set<String> set = new HashSet<>();}
SetOfS[] sets = new SetOfS[10];
Suppose the class A is such:
class A{
int rollno;
int DOB;
}
and you want to create an array of the objects for the class A. So you do like this,
A[] arr = new A[4]; //Statement 1
for (int i = 0; i < 4; i++) {
arr[i] = new A(); //Statement 2
}
which is absolutely correct.
Here A is the class and in Statement 1 Class A is a datatype of the array. When this statement gets executed because of the new keyword an object is created and dynamically memory is allocated to it which will be equal to the space required for the 4 blocks of datatype A i.e, ( for one block in the array space required is 8 bytes (4+4), I am assuming int takes 4 bytes of space. therefore total space allocated is 4*4 bytes for the array ).
Then the reference of the object is given to the arr variable. Here important point to note is that Statement 1 has nothing to do with creating an object for class A ,no object is created for this class it is only used as a datatype which gives the size of the class A required for the memory allocation of the array.
Then when for loop is run and Statement 2 is executed JVM now allocates the memory for the Class A (i.e creates an object) and gives its reference to the arr[i]. Every time the loop is called an object is created and the reference of it is given to arr[i].
Thus, arr[0] which holds a space of 8 bytes is given the reference of the object of the Class A and everytime loop is run new object is created and reference is given to that object so that it can now access the data in that object .
I expected this code to display true:
int[] array = {1, 2};
System.out.println(Arrays.asList(array).contains(1));
The method Arrays.asList(T ...) is, when generics are erased and varargs are transformed, actually equal to a method of type Arrays.ofList(Object[]) (which is the, binary equivalent, JDK 1.4 version of the same Method).
An array of primitives is an Object (see also this question), but not an Object[], so the compiler thinks you are using the varargs version and generates an Object array around your int array. You could illustrate what's happening by adding an extra step:
int[] array = {1, 2};
List<int[]> listOfArrays = Arrays.asList(array);
System.out.println(listOfArrays.contains(1));
This compiles and is equivalent to your code. It also obviously returns false.
The compiler translates varargs calls into calls with a single array, so calling a varargs method that expects parameters T ... with parameters T t1, T t2, T t3 is equivalent to calling it with new T[]{t1, t2, t3} but the special case here is that varargs with primitives will be autoboxed before the array is created if the method needs an object array. So the compiler thinks the int array is passed in as a single Object and creates a single element array of type Object[], which it passes to asList().
So here's the above code once again, the way the compiler implements it internally:
int[] array = {1, 2};
// no generics because of type erasure
List listOfArrays = Arrays.asList(new Object[]{array});
System.out.println(listOfArrays.contains(1));
Here are some good and bad ways to call Arrays.asList() with int values:
// These versions use autoboxing (which is potentially evil),
// but they are simple and readable
// ints are boxed to Integers, then wrapped in an Object[]
List<Integer> good1 = Arrays.asList(1,2,3);
// here we create an Integer[] array, and fill it with boxed ints
List<Integer> good2 = Arrays.asList(new Integer[]{1,2,3});
// These versions don't use autoboxing,
// but they are very verbose and not at all readable:
// this is awful, don't use Integer constructors
List<Integer> ugly1 = Arrays.asList(
new Integer(1),new Integer(2),new Integer(3)
);
// this is slightly better (it uses the cached pool of Integers),
// but it's still much too verbose
List<Integer> ugly2 = Arrays.asList(
Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)
);
// And these versions produce compile errors:
// compile error, type is List<int[]>
List<Integer> bad1 = Arrays.asList(new int[]{1,2,3});
// compile error, type is List<Object>
List<Integer> bad2 = Arrays.asList(new Object[]{1,2,3});
Reference:
Java Tutorial > Classes and Objects > Passing Information to a Method or a Constructor > Varargs
Arrays.asList(T ...)
But to actually solve your problem in a simple way:
There are some library solutions in Apache Commons / Lang (see Bozho's answer) and in Google Guava:
Ints.contains(int[], int) checks whether an array of ints contains a given int
Ints.asList(int ...) creates a List of Integers from an int array
The Arrays.asList(array) will result in a singleton list of an int[].
It works as you expect if you change int[] to Integer[]. Don't know if that helps you though.
Arrays.asList(ArrayUtils.toObjectArray(array))
(ArrayUtils is from commons-lang)
But if you want to just call contains there is no need of that. Simply use Arrays.binarySearch(..) (sort the array first)
This
System.out.println(Arrays.asList(array).contains(array));
returns true.
It seems like your understanding of Arrays.asList(T... a) is wrong. You wouldn't be the first person to make an assumption as to how it works.
Try it with
System.out.println(Arrays.asList(1, 2).contains(1));
Autoboxing just doesn't work the way you want it to in this case. The following code may be a bit verbose, but does the job of converting an int array to a list:
List<Integer> list = new ArrayList<Integer>(array.length);
for (int value : array) {
list.add(value);
}
The following code displays true:
Integer[] array = {1, 2};
System.out.println(Arrays.asList(array).contains(1));
(Your version fails, since Int's not beeing objects, but Int[] is an object. Therefor you will call asList(T... a) with one element beeing a Collection, since it is not possible to have an Collection a.)
When you call
Arrays.asList(array)
on your array of primitives, you get a List instance containing one object: an array of int values! You have to first convert the array of primitives into an array of objects, as #Bozho suggests in his answer.
If you only want to check whether the array contains certain element just iterate over array and search for element. This will take o(n/2). All other solutions are less effective. Any method that copies array to list must iterate over array and therefore this operation only requires n atomic assignments.
I dont think there is a method call you could use. Try it like this
List<Integer> list = new ArrayList<Integer>();
for (int index = 0; index < array.length; index++)
{
list.add(array[index]);
}