The Arrays.asList()(opens new window) method can be used to return a fixed-size List containing the elements of the given array. The resulting List will be of the same parameter type as the base type of the array.
Note: This list is backed by (a view of) the original array, meaning that any changes to the list will change the array and vice versa. However, changes to the list that would change its size (and hence the array length) will throw an exception.
In Java SE 7 and later, a pair of angle brackets <> (empty set of type arguments) can be used, which is called the Diamond(opens new window). The compiler can determine the type arguments from the context. This means the type information can be left out when calling the constructor of ArrayList and it will be inferred automatically during compilation. This is called Type Inference(opens new window) which is a part of Java Generics(opens new window).
// Using Arrays.asList()String[] stringArray ={"foo","bar","baz"};List<String> stringList =newArrayList<>(Arrays.asList(stringArray));// Using ArrayList.addAll()String[] stringArray ={"foo","bar","baz"};ArrayList<String> list =newArrayList<>();
list.addAll(Arrays.asList(stringArray));// Using Collections.addAll()String[] stringArray ={"foo","bar","baz"};ArrayList<String> list =newArrayList<>();Collections.addAll(list, stringArray);
// Using Streamsint[] ints ={1,2,3};List<Integer> list =Arrays.stream(ints).boxed().collect(Collectors.toList());String[] stringArray ={"foo","bar","baz"};List<Object> list =Arrays.stream(stringArray).collect(Collectors.toList());
Important notes related to using Arrays.asList() method
This method returns `List`, which is an instance of `Arrays$ArrayList`(static inner class of `Arrays`) and not `java.util.ArrayList`. The resulting `List` is of fixed-size. That means, adding or removing elements is not supported and will throw an `UnsupportedOperationException`:
A new `List` can be created by passing an array-backed `List` to the constructor of a new `List`. This creates a new copy of the data, which has changeable size and that is not backed by the original array:
Calling ` List asList(T... a)` on a primitive array, such as an
`int[]`, will produce a `List` whose only element is the source
primitive array instead of the actual elements of the source array.
The reason for this behavior is that primitive types cannot be used in place of generic type parameters, so the entire primitive array replaces the generic type parameter in this case. In order to convert a primitive array to a `List`, first of all, convert the primitive array to an array of the corresponding wrapper type (i.e. call `Arrays.asList` on an `Integer[]` instead of an `int[]`).
Therefore, this will print `false`:
int[] arr ={1,2,3};// primitive array of intSystem.out.println(Arrays.asList(arr).contains(1));
Set<String> set =newHashSet<String>();
set.add("red");
set.add("blue");// although set is a Set<String>, toArray() returns an Object[] not a String[]Object[] objectArray = set.toArray();
<T> T[] toArray(T[] a) can be used as follows:
Set<String> set =newHashSet<String>();
set.add("red");
set.add("blue");// The array does not need to be created up front with the correct size.// Only the array type matters. (If the size is wrong, a new array will// be created with the same type.)String[] stringArray = set.toArray(newString[0]);// If you supply an array of the same size as collection or bigger, it// will be populated with collection values and returned (new array// won't be allocated)String[] stringArray2 = set.toArray(newString[set.size()]);
The difference between them is more than just having untyped vs typed results. Their performance can differ as well (for details please read this performance analysis section(opens new window)):
`Object[] toArray()` uses vectorized `arraycopy`, which is much faster
than the type-checked `arraycopy` used in `T[] toArray(T[] a)`.
`T[] toArray(new T[non-zero-size])` needs to zero-out the array at runtime, while
`T[] toArray(new T[0])` does not. Such avoidance makes the latter call
faster than the former. Detailed analysis here : [Arrays of Wisdom of the Ancients](https://shipilev.net/blog/2016/arrays-wisdom-ancients/).
Starting from Java SE 8+, where the concept of Stream(opens new window) has been introduced, it is possible to use the Stream produced by the collection in order to create a new Array using the Stream.toArray(opens new window) method.
It is possible to define an array with more than one dimension. Instead of being accessed by providing a single index, a multidimensional array is accessed by specifying an index for each dimension.
The declaration of multidimensional array can be done by adding [] for each dimension to a regular array decleration. For instance, to make a 2-dimensional int array, add another set of brackets to the declaration, such as int[][]. This continues for 3-dimensional arrays (int[][][]) and so forth.
To define a 2-dimensional array with three rows and three columns:
int rows =3;int columns =3;int[][] table =newint[rows][columns];
The array can be indexed and assign values to it with this construct. Note that the unassigned values are the default values for the type of an array, in this case 0 for int.
table[0][0]=0;
table[0][1]=1;
table[0][2]=2;
It is also possible to instantiate a dimension at a time, and even make non-rectangular arrays. These are more commonly referred to as jagged arrays(opens new window).
int[][] nonRect =newint[4][];
It is important to note that although it is possible to define any dimension of jagged array, it's preceding level must be defined.
Multidimensional arrays and jagged arrays can also be initialized with a literal expression. The following declares and populates a 2x3 int array:
int[][] table ={{1,2,3},{4,5,6}};
Note: Jagged subarrays may also be null. For instance, the following code declares and populates a two dimensional int array whose first subarray is null, second subarray is of zero length, third subarray is of one length and the last subarray is a two length array:
int[][] table ={null,{},{1},{1,2}};
For multidimensional array it is possible to extract arrays of lower-level dimension by their indices:
int[][][] arr =newint[3][3][3];int[][] arr1 = arr[0];// get first 3x3-dimensional array from arrint[] arr2 = arr1[0];// get first 3-dimensional array from arr1int[] arr3 = arr[0];// error: cannot convert from int[][] to int[]
Arrays are zero-based indexed, so the index of the first element is 0 and the index of the last element is the array capacity minus 1 (i.e. array.length - 1).
Therefore, any request for an array element by the index i has to satisfy the condition 0 <= i < array.length, otherwise the ArrayIndexOutOfBoundsException will be thrown.
The following code is a simple example where an ArrayIndexOutOfBoundsException is thrown.
String[] people =newString[]{"Carol","Andy"};// An array will be created:// people[0]: "Carol"// people[1]: "Andy"// Notice: no item on index 2. Trying to access it triggers the exception:System.out.println(people[2]);// throws an ArrayIndexOutOfBoundsException.
Output:
Exception in thread "main"java.lang.ArrayIndexOutOfBoundsException:2
at your.package.path.method(YourClass.java:15)
Note that the illegal index that is being accessed is also included in the exception (2 in the example); this information could be useful to find the cause of the exception.
To avoid this, simply check that the index is within the limits of the array:
int index =2;if(index >=0&& index < people.length){System.out.println(people[index]);}
A method similar to Arrays.stream() appears in the Stream class: Stream.of()(opens new window). The difference is that Stream.of() uses a varargs parameter, so you can write something like:
Object arrays are covariant, which means that just as Integer is a subclass of Number, Integer[] is a subclass of Number[]. This may seem intuitive, but can result in surprising behavior:
It's not necessary for all of the array elements to share the same type, as long as they are a subclass of the array's type:
interfaceI{}classAimplementsI{}classBimplementsI{}classCimplementsI{}I[] array10 =newI[]{newA(),newB(),newC()};// Create an array with new// operator and array initializer.I[] array11 ={newA(),newB(),newC()};// Shortcut syntax with array// initializer.I[] array12 =newI[3];// { null, null, null }I[] array13 =newA[]{newA(),newA()};// Works because A implements I.Object[] array14 =newObject[]{"Hello, World!",3.14159,42};// Create an array with// new operator and array initializer.Object[] array15 ={newA(),64,"My String"};// Shortcut syntax // with array initializer.
Iterating over arrays
You can iterate over arrays either by using enhanced for loop (aka foreach) or by using array indices:
int[] array =newint[10];// using indices: read and writefor(int i =0; i < array.length; i++){
array[i]= i;}
// extended for: read onlyfor(int e : array){System.out.println(e);}
It is worth noting here that there is no direct way to use an Iterator on an Array, but through the Arrays library it can be easily converted to a list to obtain an Iterable object.
for(int[] numbers : array){for(int value : numbers){System.out.println(value);}}
It is impossible to set an Array to any non-uniform value without using an index based loop.
Of course you can also use while or do-while loops when iterating using indices.
One note of caution: when using array indices, make sure the index is between 0 and array.length - 1 (both inclusive). Don't make hard coded assumptions on the array length otherwise you might break your code if the array length changes but your hard coded values don't.
Example:
int[] numbers ={1,2,3,4};publicvoidincrementNumbers(){// DO THIS :for(int i =0; i < numbers.length; i++){
numbers[i]+=1;//or this: numbers[i] = numbers[i] + 1; or numbers[i]++; }// DON'T DO THIS :for(int i =0; i <4; i++){
numbers[i]+=1;}}
It's also best if you don't use fancy calculations to get the index but use the index to iterate and if you need different values calculate those.
Example:
publicvoidfillArrayWithDoubleIndex(int[] array){// DO THIS :for(int i =0; i < array.length; i++){
array[i]= i *2;}// DON'T DO THIS :int doubleLength = array.length *2;for(int i =0; i < doubleLength; i +=2){
array[i /2]= i;}}
Accessing Arrays in reverse order
int[] array ={0,1,1,2,3,5,8,13};for(int i = array.length -1; i >=0; i--){System.out.println(array[i]);}
Using temporary Arrays to reduce code repetition
Iterating over a temporary array instead of repeating code can make your code cleaner. It can be used where the same operation is performed on multiple variables.
// we want to print out all of theseString name ="Margaret";int eyeCount =16;double height =50.2;int legs =9;int arms =5;// copy-paste approach:System.out.println(name);System.out.println(eyeCount);System.out.println(height);System.out.println(legs);System.out.println(arms);// temporary array approach:for(Object attribute :newObject[]{name, eyeCount, height, legs, arms})System.out.println(attribute);// using only numbersfor(double number :newdouble[]{eyeCount, legs, arms, height})System.out.println(Math.sqrt(number));
Keep in mind that this code should not be used in performance-critical sections, as an array is created every time the loop is entered, and that primitive variables will be copied into the array and thus cannot be modified.
Arrays.toString() method uses Object.toString()(opens new window) method to produce String values of every item in the array, beside primitive type array, it can be used for all type of arrays. For instance:
If no overridden toString() exists for the class, then the inherited toString() from Object will be used. Usually the output is then not very useful, for example:
importjava.util.Arrays;// creating an array with integersint[] array ={7,4,2,1,19};// this is the sorting part just one function ready to be usedArrays.sort(array);// prints [1, 2, 4, 7, 19]System.out.println(Arrays.toString(array));
Sorting String arrays:
String is not a numeric data, it defines it's own order which is called lexicographic order, also known as alphabetic order. When you sort an array of String using sort() method, it sorts array into natural order defined by Comparable interface, as shown below :
Increasing Order
String[] names ={"John","Steve","Shane","Adam","Ben"};System.out.println("String array before sorting : "+Arrays.toString(names));Arrays.sort(names);System.out.println("String array after sorting in ascending order : "+Arrays.toString(names));
Output:
String array before sorting :[John,Steve,Shane,Adam,Ben]String array after sorting in ascending order :[Adam,Ben,John,Shane,Steve]
Decreasing Order
Arrays.sort(names,0, names.length,Collections.reverseOrder());System.out.println("String array after sorting in descending order : "+Arrays.toString(names));
Output:
String array after sorting in descending order :[Steve,Shane,John,Ben,Adam]
Sorting an Object array
In order to sort an object array, all elements must implement either Comparable or Comparator interface to define the order of the sorting.
We can use either sort(Object[]) method to sort an object array on its natural order, but you must ensure that all elements in the array must implement Comparable.
Furthermore, they must be mutually comparable as well, for example e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the array. Alternatively you can sort an Object array on custom order using sort(T[], Comparator) method as shown in following example.
// How to Sort Object Array in Java using Comparator and ComparableCourse[] courses =newCourse[4];
courses[0]=newCourse(101,"Java",200);
courses[1]=newCourse(201,"Ruby",300);
courses[2]=newCourse(301,"Python",400);
courses[3]=newCourse(401,"Scala",500);System.out.println("Object array before sorting : "+Arrays.toString(courses));Arrays.sort(courses);System.out.println("Object array after sorting in natural order : "+Arrays.toString(courses));Arrays.sort(courses,newCourse.PriceComparator());System.out.println("Object array after sorting by price : "+Arrays.toString(courses));Arrays.sort(courses,newCourse.NameComparator());System.out.println("Object array after sorting by name : "+Arrays.toString(courses));
Output:
Object array before sorting :[#101Java@200, #201Ruby@300, #301Python@400, #401Scala@500]Object array after sorting in natural order :[#101Java@200, #201Ruby@300, #301Python@400, #401Scala@500]Object array after sorting by price :[#101Java@200, #201Ruby@300, #301Python@400, #401Scala@500]Object array after sorting by name :[#101Java@200, #301Python@400, #201Ruby@300, #401Scala@500]
Getting the Length of an Array
Arrays are objects which provide space to store up to its size of elements of specified type. An array's size can not be modified after the array is created.
The length field in an array stores the size of an array. It is a final field and cannot be modified.
This code shows the difference between the length of an array and amount of objects an array stores.
publicstaticvoidmain(String[] args){Integer arr[]=newInteger[]{1,2,3,null,5,null,7,null,null,null,11,null,13};int arrayLength = arr.length;int nonEmptyElementsCount =0;for(int i=0; i<arrayLength; i++){Integer arrElt = arr[i];if(arrElt !=null){
nonEmptyElementsCount++;}}System.out.println("Array 'arr' has a length of "+arrayLength+"\n"+"and it contains "+nonEmptyElementsCount+" non-empty values");}
Result:
Array'arr' has a length of 13
and it contains 7 non-empty values
Remove an element from an array
Java doesn't provide a direct method in java.util.Arrays(opens new window) to remove an element from an array. To perform it, you can either copy the original array to a new one without the element to remove or convert your array to another structure allowing the removal.
Using ArrayList
You can convert the array to a java.util.List(opens new window), remove the element and convert the list back to an array as follows:
String[] array =newString[]{"foo","bar","baz"};List<String> list =newArrayList<>(Arrays.asList(array));
list.remove("foo");// Creates a new array with the same size as the list and copies the list// elements to it.
array = list.toArray(newString[list.size()]);System.out.println(Arrays.toString(array));//[bar, baz]
int[] array =newint[]{1,2,3,4};// Original array.int[] result =newint[array.length -1];// Array which will contain the result.int index =1;// Remove the value "2".// Copy the elements at the left of the index.System.arraycopy(array,0, result,0, index);// Copy the elements at the right of the index.System.arraycopy(array, index +1, result, index, array.length - index -1);System.out.println(Arrays.toString(result));//[1, 3, 4]
int[] array =newint[]{1,2,3,4};
array =ArrayUtils.removeElement(array,2);//remove first occurrence of 2System.out.println(Arrays.toString(array));//[1, 3, 4]
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. Instead, an array can only be "resized" by creating a new array with the appropriate size and copying the elements from the existing array to the new one.
String[] listOfCities =newString[3];// array created with size 3.
listOfCities[0]="New York";
listOfCities[1]="London";
listOfCities[2]="Berlin";
Suppose (for example) that a new element needs to be added to the listOfCities array defined as above. To do this, you will need to:
create a new array with size 4,
copy the existing 3 elements of the old array to the new array at offsets 0, 1 and 2, and
add the new element to the new array at offset 3.
There are various ways to do the above. Prior to Java 6, the most concise way was:
For other ways to copy an array, refer to the following example. Bear in mind that you need an array copy with a different length to the original when resizing.
There two major drawbacks with resizing an array as described above:
It is inefficient. Making an array bigger (or smaller) involves copying many or all of the existing array elements, and allocating a new array object. The larger the array, the more expensive it gets.
You need to be able to update any "live" variables that contain references to the old array.
One alternative is to create the array with a large enough size to start with. This is only viable if you can determine that size accurately before allocating the array. If you cannot do that, then the problem of resizing the array arises again.
The other alternative is to use a data structure class provided by the Java SE class library or a third-party library. For example, the Java SE "collections" framework provides a number of implementations of the List, Set and Map APIs with different runtime properties. The ArrayList class is closest to performance characteristics of a plain array (e.g. O(N) lookup, O(1) get and set, O(N) random insertion and deletion) while providing more efficient resizing without the reference update problem.
(The resize efficiency for ArrayList comes from its strategy of doubling the size of the backing array on each resize. For a typical use-case, this means that you only resize occasionally. When you amortize over the lifetime of the list, the resize cost per insert is O(1). It may be possible to use the same strategy when resizing a plain array.)
Finding an element in an array
There are many ways find the location of a value in an array. The following example snippets all assume that the array is one of the following:
int index = Arrays.binarySearch(strings, "A");
int index2 = Arrays.binarySearch(ints, 1);
Using a Arrays.asList (for non-primitive arrays only)
int index = Arrays.asList(strings).indexOf("A");
int index2 = Arrays.asList(ints).indexOf(1); // compilation error
Using a Stream
int index = IntStream.range(0, strings.length)
.filter(i -> "A".equals(strings[i]))
.findFirst()
.orElse(-1); // If not present, gives us -1.
// Similar for an array of primitives
Linear search using a loop
int index = -1;
for (int i = 0; i < array.length; i++) {
if ("A".equals(array[i])) {
index = i;
break;
}
}
// Similar for an array of primitives
With lower versions it can be by iterating the primitive array and explicitly copying it to the boxed array:
int[] primitiveArray ={1,2,3,4};Integer[] boxedArray =newInteger[primitiveArray.length];for(int i =0; i < primitiveArray.length;++i){
boxedArray[i]= primitiveArray[i];// Each element is autoboxed here}
Similarly, a boxed array can be converted to an array of its primitive counterpart:
Integer[] boxedArray ={1,2,3,4};int[] primitiveArray =newint[boxedArray.length];for(int i =0; i < boxedArray.length;++i){
primitiveArray[i]= boxedArray[i];// Each element is outboxed here}
int[] a =newint[]{1,2,3};int[] b =newint[]{1,2,3};System.out.println(a.equals(b));//prints "false" because a and b refer to different objectsSystem.out.println(Arrays.equals(a, b));//prints "true" because the elements of a and b have the same values
When the element type is a reference type, Arrays.equals() calls equals() on the array elements to determine equality. In particular, if the element type is itself an array type, identity comparison will be used. To compare multidimensional arrays for equality, use Arrays.deepEquals()(opens new window) instead as below:
int a[]={1,2,3};int b[]={1,2,3};Object[] aObject ={ a };// aObject contains one elementObject[] bObject ={ b };// bObject contains one elementSystem.out.println(Arrays.equals(aObject, bObject));// falseSystem.out.println(Arrays.deepEquals(aObject, bObject));// true
Because sets and maps use equals() and hashCode(), arrays are generally not useful as set elements or map keys. Either wrap them in a helper class that implements equals() and hashCode() in terms of the array elements, or convert them to List instances and store the lists.
Copying arrays
Java provides several ways to copy an array.
for loop
int[] a ={4,1,3,2};int[] b =newint[a.length];for(int i =0; i < a.length; i++){
b[i]= a[i];}
Note that using this option with an Object array instead of primitive array will fill the copy with reference to the original content instead of copy of it.
int[] a ={4,1,3,2};int[] b = a.clone();// [4, 1, 3, 2]
Note that the Object.clone method for an array performs a shallow copy, i.e. it returns a reference to a new array which references the same elements as the source array.
`public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)` Copies an array from the specified source array,
beginning at the specified position, to the specified position of the
destination array.
Below an example of use
int[] a ={4,1,3,2};int[] b =newint[a.length];System.arraycopy(a,0, b,0, a.length);// [4, 1, 3, 2]
Mainly used to copy a part of an Array, you can also use it to copy whole array to another as below:
int[] a ={4,1,3,2};int[] b =Arrays.copyOfRange(a,0, a.length);// [4, 1, 3, 2]
Casting Arrays
Arrays are objects, but their type is defined by the type of the contained objects. Therefore, one cannot just cast A[] to T[], but each A member of the specific A[] must be cast to a T object. Generic example:
publicstatic<T,A>T[]castArray(T[] target,A[] array){for(int i =0; i < array.length; i++){
target[i]=(T) array[i];}return target;}
ArrayType myVar = myArray[index]; // Accessing (reading) element at index
myArray[index] = value; // Assign value to position index of array
ArrayType[] myArray = new ArrayType[arrayLength]; // Array initialization syntax
int[] ints = {1, 2, 3}; // Array initialization syntax with values provided, length is inferred from the number of provided values: {[value1[, value2]*]}
new int[]{4, -5, 6} // Can be used as argument, without a local variable
int[] ints = new int[3]; // same as {0, 0, 0}
int[][] ints = {{1, 2}, {3}, null}; // Multi-dimensional array initialization. int[] extends Object (and so does anyType[]) so null is a valid value.
Parameters
Parameter
Details
ArrayType
Type of the array. This can be primitive (int, long, byte) or Objects (String, MyObject, etc).
index
Index refers to the position of a certain Object in an array.
length
Every array, when being created, needs a set length specified. This is either done when creating an empty array (new int[3]) or implied when specifying values ({1, 2, 3}).