By Wael

Posted :

arrays in java a tutorial

This tutorial is about arrays in java . It will show how to declare and create arrays , how to assign values and access elements of an array , how to loop , and print the elements of an array .

It will also show how to copy , clone and merge arrays . How to sort , search , and check for the equality of arrays . How to fill an array , generate an array , reduce an array : find the max , min or average ... How to convert arrays to streams , or collections , how to reverse an array , and how to calculate the Cartesian product of two arrays .

arrays java tutorial
Table of contents Declaring and Creating arrays Array length Assigning values to elements of an array Accessing the elements of an array Looping through arrays Printing arrays Copying and cloning arrays Merging arrays Sorting arrays Searching for an element in an Array Checking for arrays equality Filling an array Generating an array Finding the max and min elements of an array Finding the average , and the sum of an array Reducing an array Converting arrays Reversing an Array Cartesian product of Two arrays

1- Declaring and Creating arrays

A variable of type array , can be declared by using either Type[] nameOfVariable or Type nameOfVariable[] . In the first case all the variables after Type[] are of type array . In the second case , only the variable with the square brackets is of type array . There can be spaces between Type and [] .

int[] iArrayOne , iArrayTwo ;
/* 
iArrayOne and iArrayTwo are variables 
  of type int[] , since the square brackets
  are placed after the int type .*/


String sArray[] , aString ;
/* 
sArray is a variable of type
  String[] , since the square 
  brackets is placed after sArray.
aString is a variable of type
  String .*/

A variable of type array can be assigned a reference of type array . If no array reference is assigned to a variable of type array , the value assigned to the variable of type array is null .

int iArray[];
/*
iArray is a variable of type 
  int[] .
No array reference was assigned
  to iArray , as such it is 
  assigned the null value .*/

To create an array , The notations :

can be used .

The notation {expression , expression ...} can only be used while declaring an array , while other notations can be used everywhere .

jshell> 

> String[] sArrayOne;
/*
Declare the sArrayOne variable , to
  be an array of type 
  String . 
The sArrayOne variable is not 
  initialized with any value
  that holds a reference to 
  an array of type String[]
  ,as such it has a null
  value .*/
sArrayOne ==> null


> int[] iArrayOne , iArrayTwo = { 1, 2, 3+5 }
/*
Declare iArrayOne and iArrayTwo to 
be variables of type int[] . 
iArrayOne is not initialized , to 
  any value which holds a reference 
  to an array of type int[] . As 
  such it has a null value . 
iArrayTwo is initialized using 
  { 1, 2, 3+5 } . 
  An array of type int[] is created . 
    Its length is equal to the number of 
      elements inside { 1, 2, 3+5 } . 
    The expressions in { 1, 2, 3+5 }
      are evaluated and are assigned 
      to the first , second and third 
      element of the newly created array . 
  A reference of the newly created array , 
    is stored inside iArrayTwo .*/
iArrayOne ==> null
iArrayTwo ==> [ 1, 2, 8 ]


> Object[] oArrayOne , oArrayTwo = {new Object()};
/*
oArrayOne is a variable , of type 
  Object[]. It is not initialized ,
  to hold a reference to an array 
  of type Object[] , as such it 
  is assigned a null value . 
oArrayTwo is a variable of type 
  Object[]. It is initialized using 
    {new Object()}. 
  An array of type Object is created , 
    it has a length of 1 . The expression 
    new Object is evaluated , it creates
    a new instance of Object . A reference 
    of  the newly created object is stored 
    inside the first element of the newly 
    created array . 
  A reference of the newly created array
    is stored inside oArrayTo .*/
oArrayOne ==> null
oArrayTwo ==> [ java.lang.Object@59f99ea ]


> oArrayOne = {new Object()}
/* 
It is illegal to use 
  {expression , expression ..}
  anywhere beside in array 
  declaration .*/
|  Error:
|  illegal start of expression
|  oArrayOne = {new Object()}

> oArrayOne = oArrayTwo
/*
Assign the value of the variable 
  oArrayTwo to oArrayOne .*/
oArrayOne ==> [ java.lang.Object@59f99ea ]

When using the notation new Type[length_expression] , an array of the specified length and type is created , and all of its elements are null , unless the array is of the primitive type , in this case the element are initialized to their default value . For example the default value of int is 0.

The length expression must evaluate to a type int , and must be >=0 . As such the max length of an array that can be created is 2147483647 .

jshell> 

> import java.util.Arrays;
/* 
import the Arrays utility 
  class .*/


> String []sArray;
/* 
Declare a variable of type 
  String [] .
It is not initialized ,
  as such its value is 
  null .*/
sArray ==> null


> sArray = new String[3];
/* 
Create an array of type String[]
  which has three elements 
  initialized to null . 
A reference of this array is 
  stored inside the variable 
  sArray .*/
sArray ==> [ null, null, null ]


> int k = 1 ; 
> int j = 3 ; 
> int iArray[] = new int[k*j];
/* 
Declare the iArray variable
  to be an array of type 
  int .
Evaluate the expression 
  k*j , its value is 3 .  
Create a new array of 
  length three , of type 
  int , with all of its 
  elements having a value 
  of 0. 
Assign a reference of
  the newly created array 
  to the variable iArray .*/
iArray ==> [ 0, 0, 0 ]


> char cArray[] = new char[2];
/* 
Declare cArray to be a variable
  of type char[]. 
Create a char array of length 
  two , with all of its elements 
  initialized to their default
  values . 
Assign a reference of the newly 
  created array to the
  variable cArray .*/
cArray ==> [ '\000', '\000' ]


> Arrays.toString(new int[5])
/*
Create a new array of type int ,
  which has a length of 5 . 
Pass a reference to it , 
  to Arrays toString method . 
Arrays.toString method will print 
  the elements contained in this 
  array .*/
[0, 0, 0, 0, 0]

When using the notation new Type[]{expression , expression ...} , an array of the given type and of the length of the {expression , expression ...} is created .

The expressions are evaluated. If the array type is primitive , the value of the expression is stored inside the array . If the array type is of the reference type , a reference to the evaluated value is stored .

jshell> 

> import java.util.Arrays;
/* 
import the Arrays utility 
  class .*/


> Arrays.toString(new int[]{ 1, 2, 3 })
/*
Create an anonymous array , 
  of type int .
Its elements are initialized to 
  the three elements 1 , 2 and 3 .
Use the Arrays.toString method 
  to print the value of each
  element in the newly created 
  array .*/
[ 1, 2, 3 ]


> int[] iArrayOne = new int[]{}
/*
Declare iArrayOne to be a variable 
  of type int [] . 
Create an new array of type
  int , containing no elements .
Assign a reference to the
  newly created array to 
  iArrayOne .*/
iArrayOne ==> []

Variable of type multidimensional arrays can be created by adding brackets to the variable declaration , each additional brackets corresponds to an additional dimension .

jshell>

> int[][] iArrayOne , iArratTwo;
/*
Create two variables of the type :
  int [][] . 
int[][] is an an array , which 
  elements references arrays 
  of the type int [] .*/
iArrayOne ==> null
iArratTwo ==> null


> int iArrayOne[][] , iArratTwo;
/*
Declare a variable of the type :
  int [][] , and a variable of 
  the type int .*/
iArrayOne ==> null
iArratTwo ==> 0

To create a multidimensional array , we can also use the methods describe earlier on .

jshell>

/* 
Creating arrays using the notation
  {expression , expression ...} */

> int[][] iArray = { { 1, 2 } , { 1, 2, 3, 4 } };
iArray ==> [ [ 1, 2 ] , [ 1, 2, 3, 4 ] ] 
/*
Create a multi dimensional array of length
  2 and of type int [][]. 
Each element of this multidimensional array 
  references an array of type int []. 
The first element reference an array of 
  type int [] which has a length of 2 , 
  and which contains the elements 1 
  and 2 . 
The second element also reference an array 
  of type int[] which has a length of 
  4 ,  and contains the elements 1 2 3 
  and 4 .
Store a reference of the array of 
  type int [][] into the variable 
  iArray .*/


/*
Creating arrays using the notation 
  new Type[length] .*/
  
> String sArray[][];
/*
Declare a variable of type String[][] .*/

> sArray = new String[2][2]
/*
Create an array of type String[][]
  and of length two .
It contain references to arrays of 
  type String[] .
The first element reference an array
  of type String[] , of length two , 
  which elements contains references to
  null . 
The second element reference an array 
  of type String[] , of length two , 
  which elements contains references to 
  null . 
Assign a reference to the array of type 
  String[][] to the variable sArray .*/
sArray ==> [ [ null, null ],[ null, null ] ]


> sArray = new String[3][]
/*
Create an array of length 3 , 
  which elements hold references
  to arrays of type String[] .*/
sArray ==> [ null , null , null ]

> sArray[0] = new String[]{ "hello", "arrays" };
/*
Each element of sArray , can be assigned
  an array of type String[]
Create a new array of type String[] , 
  which elements reference the two
  String "hello" and "arrays".
Store a reference to this array in
  sArray[0] .*/

> sArray
sArray ==> [ [ "hello", "arrays" ], null, null ]


/*
Creating arrays using the notation 
  new Type[]{expression , expression ...} .*/

> sArray = new String[][]{ { "hey", "java" }, { "chrome", "help" , "space" } }
sArray ==> [ [ "hey", "java" ], [ "chrome", "help", "space" ] ]

2- Array length

An array length can be gotten using the .length property .

Example of accessing the array length of arrays having a single dimension.

jshell>

> int []iArrayOne = {} , iArrayTwo = { 1, 2 } , iArrayThree;
/*
Declare three variables of type int[].
iArrayOne contains a reference 
  to an array which contains 
  no elements. 
iArrayTwo contains a reference 
  to an array which contains 
  2 elements. 
iArrayThree contains a reference 
  to null .*/
iArrayOne ==> []
iArrayTwo ==> [ 1, 2 ]
iArrayThree ==> null

> iArrayOne.length
/*
iArrayOne reference an array 
  which contains no elements
  , the length of the array 
  is 0 .*/
0

> iArrayTwo.length
/*
iArrayTwo reference an array
  which contains two elements , 
  as such its length is 2 .*/
2

> iArrathree.length
/*
iArrayThree does not reference
  any array . It contains a
  reference to a null value , as 
  such it cannot access the 
  length property .*/
|  Exception java.lang.NullPointerException
|        at (#26:1)

Example of accessing the array length of arrays having multiple dimensions .

jshell>

> int[][] iArrayOne = new int[2][] , iArrayTwo  , iArrayThree = { { 1, 2, 3 }, { } } ;
/*
Create three variables of type 
  int [][] .
The first variable references an 
  array of length 2 , which elements 
  references array of type int [] .
The second variable is of type int[][] ,
  but does not reference any array of 
  type int [][] , as such it 
  references a null value.
The third variable references an 
  array of length 2 , which elements
  references an array of type 
  int [] .*/
iArrayOne ==> [ null, null ]
iArrayTwo ==> null
iArrayThree ==> [ [ 1, 2, 3 ], [ ] ]

> iArrayOne.length;
/*
The length of the array which 
  elements contain references
  to arrays of type int[]
  is : */
2

> iArrayOne[0].length;
/* 
The first element of the array
  referenced by iArrayOne does 
  not reference any array
  of type int[] , as such it 
  references a null value . 
Trying to access the length property
  of null will result in 
  NullPointerException .*/
 Exception java.lang.NullPointerException
|        at (#5:1)

> iArrayTwo.length;
/*
iArrayTwo references a null value , 
  so trying to access the length 
  property of a null value results 
  in a null pointer exception. */
|  Exception java.lang.NullPointerException
|        at (#4:1)

> iArrayThree[1].length
/*
Access the first element of 
  int[][] , which is {} an array
  of type int [] .
Access its length property .*/
0

3- Assigning values to elements of an array

An array is formed of zero or more elements . Elements of an array can be assigned a value using the square notation , which takes an expression which is evaluated .

When an element of an array is assigned a value , the value is assigned based on the rules of assigning a primitive or a reference type .

If the value to be assigned is of the primitive type , then the primitive type value is copied and stored in the array .

jshell>

> int []iArrayOne = new int[1];
/*
iArrayOne is a variable of type int[] .
new int[1] , creates an array 
  of the primitive type int , 
  of length 1 . 
The elements of the newly created 
  array are initialized to the 
  default value 0 . 
A reference to the newly created 
  array is stored inside iArrayOne .*/
iArrayOne ==> [ 0 ]


> iArrayOne[1-1]  = 10 ;
/*
1 - 1 is evaluated to 0 . 
The first element of the 
  array reference by iArrayOne 
  is assigned the value 10 . 
10 is a primitive value , 
  as such it is copied and 
  stored inside the array .*/


> int anInt = 1 ; 
/*
anInt contains the value
  1 .*/


> iArrayOne[0]  = anInt ; 
/*
The value contained in anInt
  is copied to iArrayOne[0] .
anInt contains 1 , as such 
  iArrayOne[0] contains 1 .*/


> iArrayOne
/*
iArrayOne is a variable which
  references an array of type
  int[] , and which contains
  the element 1 .*/
iArrayOne ==> [1]

If the value to be assigned is a reference type , then the reference is copied and stored inside the array .

jshell>

> String aString = "hello";
/*
Create a variable of type
  String . 
Assign a reference of 
  the String "hello" to
  aString .*/

> String[] sArray = {aString};
/*
sArray is a variable of type
  String [] . 
it is initialized using 
  {aString} .
A new array of type String[]
  and of length 1 is created . 
  aString is a reference type , 
  as such the value  of aString ,
  which is a reference , is stored 
  inside the first element of 
  sArray . 
A reference of the newly created 
  array is stored inside the 
  variable sArray .
sArray[0] and aString contain the  
  same reference .*/

> sArray[0] = "hey"
/*
"hey" is a string literal , 
  a reference for the String
  "hey" is stored inside 
  sArray[0] . 
sArray[0] and aString do not
  contain the same reference 
  anymore .*/
sArray[0] ==> "hey"

> aString
/*
aString is still referencing the
  String literal "hello"*/
aString ==> "hello"

/*
String are immutable , so their 
  values cannot change .*/


> class WWW{
	String address; 
}
/*
Create the WWW class , with one
  field of type String . */

> WWW aWWW = new WWW();
/*
Create a new instance of WWW , 
  and store a reference to
  it in the variable aWWW . 
aWWW address attribute is initialized , 
  to null. */
aWWW ==> WWW@6ddf90b0

> aWWW.address
aWWW.address ==> null

> WWW wwwArray[] = {aWWW};
/*
wwwArray is a variable of 
  type WWW[] .
A new array is created , 
  of type WWW and of length 
  1 . 
The reference contained in
  the variable aWWW , is copied
  and stored inside aWWW[0].
aWWW[0] and the variable 
  aWWW contain the same reference . 
A reference of the newly created
  array is stored in the 
  wwwArray variable .*/
wwwArray ==> [ WWW@6ddf90b0 ]

> wwwArray[0].address = "http://difyel.com";
/*
wwwArray[0] address field is 
  assigned the value of 
  "http://difyel.com" .*/
wwwArray[0].address ==> "http://difyel.com"

> aWWW.address
/*
aWWW refers to the same object , 
  referenced by wwwArray[0] . As 
  such aWWW.address field has a 
  value of http://difyel.com .*/
aWWW.address ==> "http://difyel.com"

> aWWW = new WWW();
/*
A new instance of WWW is 
  created . Its reference is 
  assigned to the variable 
  aWWW .*/
aWWW ==> WWW@369f73a2
/*
aWWW and wwwArray[0] do not refer to 
  the same object . So changing 
  the field value of aWWW , will 
  not affect the field value 
  of wwwArray[0] and the inverse
  is also true .*/


> int[][] iArrayOne = new int[2][];
/*
Declare a variable iArrayOne 
  of the type int[][] . 
Create an array of length 2 , 
  which elements reference an array
  of type int [] .
Assign a reference to the newly created
  array inside the variable 
  iArrayOne .*/
iArrayOne ==> [ null, null ]

> iArrayOne[0] = new int[1] ;
/*
Create an array of type int[]
  of length 1 . 
Store a reference to the newly
  created array to iArrayOne[0] .*/

> iArrayOne[0][0] = 1 
/*
Access the first array of type 
  int[] .
Store inside the first element
  of the array of type int[] ,
  the value 1 .*/

4- Accessing the elements of an array

Elements of an array can be accessed using the square brackets notation , which takes an int value >=0 and less than the length of the array .

jshell>

> int[] iArray = new int[]{ 0, 1, 2 }
/*
iArray is a variable of type int[].
It is assigned a reference to an
  array of length 3 and of type 
  int[] .*/
iArray ==> [ 0, 1, 2 ]

> iArray[0]
/*
Access the first element 
  of the array referenced by 
  iArray[0] .*/
iArray[0] ==> 0

> iArray[0+2]
/*
0+2 is evaluated to 2 .
Access the third element 
  of the array referenced by 
  iArray[2] .*/
iArray[2] ==> 2

> iArray[3]
/*
An ArrayIndexOutOfBoundsException is 
  thrown , when trying to access an element
  with index <0 or >= length of the array .*/
|  Exception java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
|        at (#3:1)

> iArray[-1]
|  Exception java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 3
|        at (#4:1)


> int iArrayTwo[][] = {{}} 
/*
Create an array which references
  an array of type int [] . 
The array of type int[] does not
  contain any elements .
Store a reference of the newly
  created array inside the 
  variable iArrayTwo .*/
iArrayTwo ==> [ [ ] ]

> iArrayTwo[0][0]
/*
Access the first element of
  the array referenced by the
  variable iArrayTwo . 
Access the first element 
  referenced by the array of type
  int [] .
There is no elements found in 
  the array of type int[] , 
  as such an index out of 
  bound exception is thrown .*/
|  Exception java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
|        at (#5:1)

5- Looping through arrays

To loop through an array , a for loop can be used as follows .

jshell>

> int iArray[] = {1, 2, 3 }
/*
iArray is a variable of type int[] .
  It holds a reference to an array
  of three elements 1 , 2 and 3 .*/
iArray ==> [ 1, 2, 3 ]

> /* Loop through the array using a for loop */
for( int i = 0 ; i < iArray.length ; i++ )
{
    int elementAtIndexI = iArray[i];
    /*
      do something , for example 
      print the array elements .*/
    System.out.println(elementAtIndexI);
}
1
2
3


> int iArrayTwo[][] = { { 1, 2 }, { 3, 4 } }
/*
iArrayTwo is a variable of type 
  int[][] . It hold a reference to 
  an array of type int[][]. 
The array of type int[][] has a 
  length of two , and contains 
  references to two arrays of 
  type int[] .
The arrays of type int[] , each 
  contain two int elements .*/
iArrayTwo ==> [ [ 1, 2 ], [ 3, 4 ] ]

> /* For each additional dimension , 
  an additional for loop must 
  be added .*/
for( int i = 0 ; i < iArrayTwo.length ; i++ )
{
    for( int j = 0 ; j < iArrayTwo[i].length ; j++ )
    {
        int elementAtIndexIJ = iArrayTwo[i][j];
        /*
            Do something , for example 
            print the array elements .*/
        System.out.println(elementAtIndexIJ);  
    }
}
1
2
3
4

A for each loop can also be used to loop through an array . The difference between a for and a for each loop , is that in a for each loop it is not necessary to declare the index used to loop through the array , but at the same time this means no access to the index .

A for and a for each loop can be mixed .

jshell>

> String sArray[] = { "Hello", "Search" }
/*
sArray is a variable of type
  String [] .
It holds a reference to an array 
  of type String [] .
The array of type String []
  holds two references for 
  Strings .*/
sArray ==> [ "Hello", "Search" ]

> /* Loop through an array using a for each loop */
for( String element : sArray )
{
    /*
      do something , with the
      element .*/
    System.out.println(element);
}
Hello
Search


> String sArrayOne[][] =  { {"java"} , {"red" , "green"} }
/*
sArrayOne is a variable of type String [][] .
It hold a reference to an array which
  contains two references to arrays of 
  type String[] .*/
sArrayOne ==> [ [ "java" ] , [ "red", "green" ] ]

> for( String[] stArray : sArrayOne )
{
    for(String sElem : stArray)
    {
        /*
          Do something with the element .*/
          System.out.println(sElem);
    }
}
java
red
green

A Spliterator can also be used to loop through an array . As its name convey , a Spliterator is an iterator which can be split . It allows to perform looping one element at a time using its tryAdvance method , or for all the remaining elements using its forEachRemaining method , or to obtain another Spliterator from this Spliterator using the trySplit method , which ideally may try to split the Spliterator in half , but might split it at other points , or might fail .

A Spliterator source must not be modified , if it does not have the immutable or concurrent characteristics .

A Spliterator can be iterated over only once .

jshell>

> import java.util.Arrays;
> import java.util.Spliterator;


> int iArray[] = { 1, 2, 3, 4 } ;
/*
iArray is a variable which contains
  a reference to an array of
  type int [] .*/
iArray ==> [ 1, 2, 3, 4 ]

> Spliterator<Integer> iSpliterator = Arrays.spliterator(iArray);
/*
Use Arrays.spliterator to create a 
  Spliterator which has a source , 
  the array referenced by 
  iArray .*/
iSpliterator ==> java.util.Spliterators$IntArraySpliterator@68be2bc2

> iSpliterator.hasCharacteristics(Spliterator.IMMUTABLE)
/*
Using hasCharacteristics , check 
  if the created Spliterator 
  has the characteristic of being 
  Immutable .*/
$ ==> true

> iSpliterator.hasCharacteristics(Spliterator.CONCURRENT)
/*
Using hasCharacteristics , check 
  if the created Spliterator
  has the characteristic of being
  Concurrent .*/
$ ==> false

> iSpliterator.hasCharacteristics(Spliterator.NONNULL)
/*
Using hasCharacteristics , check 
  if the Source guarantees 
  that encountered elements
  will not be null .*/
$ ==> false

> iSpliterator.hasCharacteristics(Spliterator.ORDERED)
/*
Using hasCharacteristics , check 
  if an encounter order
  is defined for the
  elements .*/
$ ==> true

> iSpliterator.tryAdvance(System.out::println)
/*
Using the tryAdvance method , try 
  to advance one element in the 
  Spliterator .
Returns true on success , false 
  on failure.
Pass the println function as argument 
  to tryAdvance , to print the 
  element .*/
1
$ ==> true

> int index = 1 ; 
/*
Declare a variable containing the 
  current index of the 
  Spliterator .*/

> iSpliterator.forEachRemaining( iElement -> {
    System.out.println(iElement);
    if(index < iArray.length - 1)
        iArray[++index] *= 2;
    } )
/*
Use forEachRemaining , to loop 
  through the remaining elements 
  of the Spliterator . 
Pass a lambda function to 
  forEachRemaining, which takes 
  as argument : iElement , the 
  current iterating element , print 
  it , and modify the next element 
  by doubling it .*/
2
6
8


> String [][]sArray = { { "ae", "ar" }, { "be", "br" }, { "ce", "ck" } }
/*
Create an array of type 
  String [][] . It contains 
  three references to arrays
  of types String [] . Each
  contains two references to
  Strings .*/
sArray ==> [ [ "ae", "ar" ] , ["be" , "br"]  , [ "ce", "ck" ] ]

> Spliterator<String []> saSpliterator = Arrays.spliterator(sArray , 1 , 3 ) ;
/*
Use Arrays.spliterator , to create 
  a Spliterator which has a 
  source the array referenced by 
  the  variable sArray , starting 
  from index 1 inclusive , till
  index 3 non inclusive .*/

> Spliterator<String []> splitSaSplitIerator = saSpliterator.trySplit();
/*
Use trySplit to split the 
  Spliterator which has a source 
  the array referenced by sArray .
Store a reference to the created 
  Spliterator in the variable 
  splitSaSplitIerator .*/

> saSpliterator.forEachRemaining(
    aElement -> {
        for(String sElement : aElement)
            System.out.println(sElement);
    })
/*
Use forEachRemaining , to loop 
  through the elements of the
  Spliterator referenced by
  the variable saSpliterator .
Pass in a lambda function , 
  which takes one argument ,
  of type String [] : aElement .
Loop through aElement , which 
  is an array of type String [] , 
  using a for each loop . 
Print the values referenced 
  by the elements of the
  array of type String[] .*/
ce
ck 

> splitSaSplitIerator.forEachRemaining(
    aElement -> {
        for(String sElement : aElement)
            System.out.println(sElement);
    })
/*
Use forEachRemaining to loop 
  through the elements of the 
  Spliterator referenced by 
  splitSaSplitIerator . They 
  are of type String [] .
Pass in a lambda function , 
  which takes one argument 
  of type String[] : aElement . 
Loop through the elements
  of the array referenced by 
  the variable aElement . 
Each element contains a 
  reference to a String .
Print the String . */
be
br

Also a Stream can be obtained from an array , and it can be used to loop over the element of the array . A Stream can only be iterated over once .

jshell>

> import java.util.Arrays ;
> import java.util.stream.IntStream ;
> import java.util.stream.Stream ;

> int iArray[] = { 0, 3, 1, 2 };
/*
Create an array of type int[]
  , which has 4 elements .
Store a reference to it in
  the variable iArray .*/
iArray ==> [ 0, 3, 1, 2 ]

> IntStream iStream = Arrays.stream(iArray);
/*
Use Arrays.stream , to create 
  a sequential Stream .
It has a source the array 
  referenced by the variable 
  iArray .*/
iStream ==> java.util.stream.IntPipeline$Head@29ee9faa

> iStream.forEach(System.out::println);
/*
Iterate over the stream using 
  the forEach method.
The forEach method takes as 
  argument the function println , 
  and use it to print the 
  stream .*/
0
3
1
2

> iStream = Arrays.stream(iArray);
/*
Using Arrays.stream , create 
  a sequential stream , which 
  source is the array referenced 
  by iArray .*/

> iStream.parallel().forEach(System.out::println);
/*
Create a parallel Stream from the 
  sequential stream referenced by 
  the variable iStream.
The forEach method does not guarantee 
  the order of encounter as defined
  in the Stream source for parallel 
  streams .*/
1
2
3
0

> iStream = Arrays.stream(iArray);
/*
Use Arrays.stream to create 
  a sequential stream , which 
  source is the array referenced 
  by iArray .*/

> iStream.parallel().forEachOrdered(System.out::println);
/*
Create a parallel Stream from the
  sequential stream referenced
  by the variable iStream .
Iterate over the parallel Stream using 
  forEachOrdered .
The forEachOrdered guarantees the order
  of encounter as defined in the Stream
  source for parallel Streams. */
0
3
1
2


> String[][] sArray = { { "aa", "ab" }, { "cd", "c" } }
/*
Create an array of type String[][]
  and assign a reference to it 
  to the variable sArray .*/
sArray ==> [ [ "aa", "ab" ], [ "cd", "c" ] ]

> Stream<String[]> saStream = Arrays.stream(sArray , 1 , 2);
/* 
Use Arrays.stream to create a 
  sequential Stream which has a 
  source the array  referenced by 
  sArray , starting at index 1 
  inclusive , ending index 2 
  exclusive .*/
saStream ==> java.util.stream.ReferencePipeline$Head@6f7fd0e6

> saStream.forEach( aString -> Arrays.stream(aString).forEach(System.out::println));
/*
Iterate over the Stream using
  forEach Method.
Pass in a lambda function , which
  takes as argument an element of
  type String[] . 
Create a Stream from this element ,
  and use the forEach method , to
  iterate over its elements .
  Pass to the forEach method , 
    the println function to print
    the elements .*/
cd
c

6- Printing arrays

The Arrays.toString , and Arrays.deepToString , can be used to get a String representation of an array . The Arrays.deepToString will get the String representation of arrays containing other arrays .

jshell> 

> int iArray[][] = { { 1, 2 }, { 3, 4 } }
/*
Create an array of type int [][] ,
  and store a reference to it 
  in the variable iArray .*/
iArray ==> [ [ 1, 2 ], [ 3, 4 ] ]

> Arrays.toString(iArray)
/*
Use Arrays.toString to get a 
  toString representation of 
  the array referenced by the 
  variable iArray .*/
$ ==> "[[I@58651fd0, [I@4520ebad]"

> Arrays.deepToString(iArray)
/*
Use Arrays.deepToString to 
  get a deep toString 
  representation of the array , 
  referenced by the variable
  iArray .*/
$ ==> "[[1, 2], [3, 4]]"

7- Copying and cloning arrays

The clone method can be used to clone an array . This will return a shallow copy of the elements of the array .

If the array is an array of primitive types , this works well . If the array is of reference type , this means the elements of the array and its clone contains the same references , as such they share the same objects .

jshell>

> int iArray[] = { 1, 2, 4 };
/*
Create an array of type 
  int[] which contains 
  three integers .
Store a reference to it 
  in the variable 
  iArray .*/
iArray ==> [ 1, 2, 4 ]

> int iArrayClone[] = iArray.clone() 
/*
Create a new array , and 
  shallow copy the elements 
  1 , 2 and 4 , of the array 
  referenced by the iArray 
  variable .
Store a reference of the 
  newly created array in 
  iArrayClone .*/
iArrayClone ==> [ 1, 2, 4 ]


> Object oArray[] = { new Object(), new Object() }
/*
Create an array of type 
  Object[] , and which contains 
  two elements . 
Store the reference of 
  this array in the variable 
  oArray .*/
oArray ==> [ java.lang.Object@4520ebad, java.lang.Object@5419f379 ]

> Object oArrayClone[] = oArray.clone();
/*
Shallow copy the elements of 
  the array referenced by 
  oArray , into a new array of 
  type Object[] .
They are of reference type , as 
  such shallow copy the 
  references .
Store the reference of the newly 
  created array inside 
  oArrayClone .
The elements of the arrays 
  referenced by the oArray ,
   and oArrayClone variable 
   refer to the same Objects .*/
oArrayClone ==> [ java.lang.Object@4520ebad, java.lang.Object@5419f379 ]


> int iArrayTwo [][] = { {1, 2, 3 }, { 0 } }
/*
Create an array of length 2 , 
  which elements refers to 
  arrays of type int [] .
Store a reference to this 
  array , in the variable 
  iArrayTwo .*/
iArrayTwo ==> [ [ 1, 2, 3 ], [ 0 ] ]

> int[][] iArrayTwoClone = iArrayTwo.clone();
/*
Create a shallow copy of the array
  referenced by the variable
  iArrayTwo .
A new array which elements can
  hold a reference to arrays of 
  type int [] is created . 
The elements of the array referenced
  by the iArrayTwo variable are 
  copied .
They contain references to arrays of 
  type int []. 
Store a reference of the newly 
  created array in the variable
  iArrayTwoClone .
The elements of the arrays referenced
  by iArrayTwo and iArrayTwoClone ,
  reference the same arrays of type 
  int [] .*/
iArrayTwoClone ==> [ [ 1, 2, 3 ], [ 0 ] ]

> iArrayTwo[1][0] = 3
/* 
Access the second element of the
  array referenced by the variable
  iArrayTwo.
Assign to this array first 
  element the value of 3 .*/

> iArrayTwoClone 
/*
Print the array referenced by 
  the variable iArrayTwoClone .
The arrays referenced by the 
  variables iArrayTwoClone
  and iArrayTwo , contain 
  the same references . 
iArrayTwoClone[1][0] is equal 
  also to 3 .*/
iArrayTwoClone ==> [ [ 1, 2, 3 ] ,[ 3  ] ]

Another method to create a shallow copy of an array , is by using the System.arraycopy method .

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

Its first argument is the source array to copy from . Its second argument is the index from which to start copying from the source array . Its third argument is the array to copy to . Its fourth argument is the index from which to start copying at the destination array . Its fifth argument is the number of elements to copy .

The difference between this method and the clone method , is that this method can be used to copy just a portion of an array , or the whole array , and that both arrays must exists or be created before performing the copying .

jshell>

> int [] iArray = { 10, 1, 2, 34, 12 }
/*
Create an array of type int[]
  and store a reference to it
  in the variable iArray .*/
iArray ==> [ 10, 1, 2, 34, 12 ]

int [] iArrayCopy = new int[2]
/*
Create an aray of length 2 , 
  of type int[].
Store a reference to it inside 
  iArrayCopy .*/
iArrayCopy ==> [ 0, 0 ]


> System.arraycopy(iArray , 2 , iArrayCopy , 0 , 2 )
/*
Using System.arraycopy , copy 
  from the array referenced 
  by iArray , starting at index 
  2 , to the array referenced by 
  iArrayCopy , starting at index 
  0 , two elements .*/

> iArrayCopy
iArrayCopy ==> [ 2, 34 ]


> int iArrayTwo[][] = { {}, {1 , 2} }
/*
Create an array of length 2 , 
  which elements contains 
  references to arrays of 
  type int [] .*/
iArrayTwo ==> [ [ ], [ 1, 2 ] ]

> int iArrayTwoCopy[][] = new int[4][]
/*
Create an array of length 4 , 
  which elements contain 
  references to arrays of 
  types int[] .*/
iArrayTwoCopy ==> [ null, null, null, null ]

> System.arraycopy(iArrayTwo , 0 , iArrayTwoCopy , 0 , 2 )
/*
Use System.arraycopy to copy
  from the array referenced by 
  iArrayTwo , starting at index 0 , 
  to the array referenced by 
  iArrayTwoCopy , starting at 
  position 0 , 2 elements . 
The elements which are copied are
  references to arrays of type 
  int [] .*/

> iArrayTwoCopy
iArrayTwoCopy ==> [  [ ], [ 1, 2 ], null, null ]

The source and destination array can be the same . System.araycopy proceeds as if there is a temporary array .

jshell>

> int [] iArray = { 10, 1, 2, 34, 12 }
iArray ==> [ 10, 1, 2, 34, 12 ]

> System.arraycopy(iArray , 2 , iArray , 0 , 3 )
/*
Use System.arraycopy , to copy from 
  the array referenced by iArray ,
  starting at index 2 , to itself , 
  starting at index 0 , 
  three elements .*/

> iArray
iArray ==> [ 2, 34, 12, 34, 12 ]

An IndexOutOfBoundsException is thrown , when any of the source or destination indexes are negative , or larger than the source or destination array length .

An IndexOutOfBoundsException is also thrown , when the srcPos + length is greater than the source array length , or when the destPost + length is greater than the destination array length .

An IndexOutOfBoundsException is also thrown when the length is negative .

If an IndexOutOfBoundsException is thrown the destination array is not modified .

jshell>


> int [] iArray = { 10, 1, 2, 34, 12 }
/*
Create an array of five elements
  of type int[] , and store
  a reference to it in the 
  variable iArray .*/
iArray ==> [ 10, 1, 2, 34, 12 ]

> System.arraycopy(iArray , 2 , iArray , 0 , 10 )
/*
Use System.arraycopy to copy from 
  the array reference by the 
  variable iArray starting at position
  2 , to itself starting position
  0 , 10 elements. 
IndexOutOfBoundsException is 
  thrown because 12 is larger 
  then the length of the source 
  array .*/
|  Exception java.lang.ArrayIndexOutOfBoundsException: arraycopy: last source index 12 out of bounds for int[5]
|        at System.arraycopy (Native Method)
|        at (#11:1)

> iArray
/*
The array referenced by 
  iArray is not 
  modified .*/
iArray ==> int[5] { 10, 1, 2, 34, 12 }

A NullPointerException is thrown if the variables pointing to the source or destination arrays are null .

jshell>

> int[] iArray = { 10, 1, 2, 34, 12 }
/*
Create an array of type int [] , 
  containing five elements . 
Store a reference to it inside
  the variable iArray .*/
iArray ==> [ 10, 1, 2, 34, 12 ]

> int[] iArrayCopy;
/*
Declare a variable iArrayCopy , 
  of type int [] .
It is assigned a null value .*/
iArrayCopy ==> null

> System.arraycopy(iArray , 0 , iArrayCopy , 0 , 5 )
/*
iArrayCopy is a variable which does 
  not refer to an array , it contains 
  a null reference , as such 
  System.arraycopy throws a null 
  exception .*/
|  Exception java.lang.NullPointerException
|        at System.arraycopy (Native Method)
|        at (#3:1)

An ArrayStoreException is thrown when the source or destination are not of type array , or when the source or destination are arrays of different primitive types , or when one is an array of primitive type and the other is an array of reference type . In these cases the destination array is not modified .

jshell>

> int iArray[] = { 10, 2, 33, 4, 1 }
/*
Create an array of type int[]
  formed of five elements. 
Store a reference to it inside
  the iArray variable .*/
iArray ==> [ 10, 2, 33, 4, 1 ]

> System.arraycopy(new Object(), 0 , iArray  , 2 , 3 )
/*
ArrayStoreException is thrown 
  because the source is not 
  of type array .*/
|  Exception java.lang.ArrayStoreException: arraycopy: source type java.lang.Object is not an array
|        at System.arraycopy (Native Method)
|        at (#2:1)
  
> iArray
/*
The array reference by iArray 
  was not modified .*/
iArray ==> [ 10, 2, 33, 4, 1 ]

An ArrayStoreException is is also thrown when both the source and the destination are arrays of the reference type , and an element referenced by the source array cannot be converted to the destination array , elements type . In this case the destination array is modified till when the exception occurs .

jshell>

> Object oArray[] = {new Integer(1), new Object() }
/*
Create an array of type Object[] ,
  formed of two elements .
Store a reference to this array 
  inside the variable oArray .*/
oArray ==> [ 1 , java.lang.Object@64bfbc86 ]

> Integer iArray[] = new Integer[2] 
/*
Create an array of type Integer[]
  of length 2 .
Store a reference to it inside the 
  variable iArray .*/
iArray ==> [ null, null ]

> System.arraycopy(oArray , 0 , iArray , 0 , 2 )
/*
Use System.arraycopy to copy from 
  the array referenced by oArray 
  starting index 0 , to the array
  referenced by iArray starting index 
  0 , 2 elements .
ArrayStoreException is thrown because
  an Object cannot be stored inside
  an Integer array .*/
|  Exception java.lang.ArrayStoreException: arraycopy: element type mismatch: can not cast one of the elements of java.lang.Object[] to the type of the destination array, java.lang.Integer
|        at System.arraycopy (Native Method)
|        at (#5:1)

> iArray
/*
Only one element is copied from 
  the array referenced by oArray 
  to iArray .*/
iArray ==> [ 1, null ]

A shallow copy of an array , can also be created using the Stream toArray method .

jshell>
> import java.util.Arrays;

> int iArray[] = { 1, 2, 34 };
/*
Create an array of type int[] , 
  and store a reference to it
  inside the variable iArray .*/
iArray ==> [ 1 , 2 , 34 ]

> int iArrayClone[] = Arrays.stream(iArray).toArray();
/*
For primitive types : double , int , long ,
  Arrays.stream create a stream of type 
  DoubleStream IntStream and LongStream . 
Use the toArray method to collect 
  the elements of the Stream into
  an array .*/
iArrayClone ==> [ 1, 2, 34 ]


> String sArray[][] = { {"ae" , "df"}, {"oo", "on"} }
/*
Create an array of type String [][] , and 
  store a reference to it in the variable
  sArray .*/
sArray ==> [ [ "ae", "df" ] , [ "oo", "on" ] ]

> String sArrayClone[][] = Arrays.stream(sArray).toArray(String[][]::new);
/* 
Use Arrays.stream method , to
  create a sequential stream 
  backed by  the array 
  referenced by sArray . 
Use the toArray method , to return
  an array containing the elements
  of the Stream .
Pass in the function which will be used
  to create the array , of the specified
  type. 
The function receive as a 
  parameter the length of the 
  to be created array .*/
sArrayClone ==> [ [ "ae", "df" ], [ "oo", "on" ] ]

8- Merging arrays

There is no inbuilt java method to merge multiple arrays , a possible solution is as follows .

jshell>
> import java.lang.reflect.Array;

> /*Create a Class named MergeArrays*/
class MergeArrays
{

    public static Object mergeArrays(Object ... oElements)
    {
        if(oElements.length == 0)
            /* 
              If no arguments were provided , 
              return null .*/
            return null ;
        int length = 0 ; 

        for( int i = 0 ; i < oElements.length ; i++ )
        {
            /* 
            check that oElements types are arrays .
            Check that the arrays referred by 
              oElements , have the same Component
              types or that their component type
              is a subtype of the component type
              of oElements[0] .
            Get the length of the arrays referred 
              by oElements , and calculate 
              the total length of the to be newly 
              created array .*/
            if(! oElements[i].getClass().isArray())
                throw new IllegalArgumentException("All elements must be arrays");
            if(! oElements[0].getClass().getComponentType().isAssignableFrom(oElements[i].getClass().getComponentType()))
                throw new IllegalArgumentException("oElements[" + i + "] component type is not a subclass or class of oElements[0] component type");
            length += Array.getLength(oElements[i]);
        }

        Object rASrray = Array.newInstance(oElements[0].getClass().getComponentType(), length);
        System.arraycopy(oElements[0] , 0 , rASrray , 0 , Array.getLength(oElements[0]));
        for(int i = 1 ; i < oElements.length ; i++)
        {
            System.arraycopy(oElements[i] , 0 , rASrray , Array.getLength(oElements[i-1]) , Array.getLength(oElements[i]));
        }
        return rASrray;
    }
}

> int iArray[] = (int []) MergeArrays.mergeArrays( new int[]{ 0, 1 }, new int[]{ 2, 3 } )
iArray ==> [ 0, 1, 2, 3 ]

> String sArray[][] = (String [][] )MergeArrays.mergeArrays( new String[][]{ {"hello"}, {"world"} } , new String[][]{ { "df", "8" } } )
sArray ==> [ [ "hello" ], [ "world" ], [ "df", "8" ] ]

arrays can also be merged by using the Stream API .

jshell>

> import java.util.stream.Stream;

> Stream<int []> iaStream = Stream.of(new int[]{ 1, 2, 3 }, new int[]{ 5, 9, 12 })
/*
Create using the Stream.of 
  method a sequential  
  stream whose elements are 
  of type int [] .*/
iaStream ==> java.util.stream.ReferencePipeline$Head@4678c730

> int iaMerged[] = iaStream.flatMapToInt(iArray -> Arrays.stream(iArray)).toArray()
/*
The elements of the stream are
  of type int[] .
For each element of the stream , 
  create a stream backed by
  this element using the 
  Arrays.stream method. 
The created stream will be of 
  type int . 
This is why the flatMapToInt 
  method was used . 
This will flat and map each 
  element of the type int[]
  of the Stream referenced by
  iaStream into elements of 
  the type int , creating
  an IntStream . 
Collect the elements of the 
  IntStream into an array .
  array . */
iaMerged ==> [ 1, 2, 3, 1, 5, 9 ]


> Stream <int [][]> iaaStream = Stream.of(new int[][] { { 1, 2, 3 } , { 4, 5, 6 } }, new int[][]{ {5, 9 , 12 } })
/*
Using the Stream.of method create
  a sequential order Stream 
  whose elements are of type 
  int[][] .*/
iaaStream ==> java.util.stream.ReferencePipeline$Head@6767c1fc

> int iaaMerged[][] = iaaStream.flatMap(iaaElement -> Arrays.stream(iaaElement)).toArray(int[][]::new)
/*
For each element of the stream ,
  apply the method Arrays.stream .
This methods will return a stream
  which elements are of type 
  int [] . 
The result of the flatMap function
  is a Stream of objects .
Using the toArray method , collect
  the elements of the flat mapped
  stream of objects , into an array
  of type int[][] .*/
iaaMerged ==>  [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 5, 9, 12 ] ]

9- Sorting arrays

The java.util.Arrays class provides some utility methods to manipulate arrays .

The Arrays.parallelSort method can be used to sort arrays in parallel . If the number of elements of the array to be sorted is less then a specified threshold the Arrays.parallelSort will sort the arrays elements using the Arrays.sort method .

For arrays of primitive types , Arrays.parallelSort and Arrays.sort will sort the element in ascending order.

jshell> 

> import java.util.Arrays;


> int[] iArray = { 4, 1, 7, 8, 3 };
iArray ==> [ 4, 1, 7, 8, 3 ]

> Arrays.sort(iArray)

> iArray
iArray ==> [ 1, 3, 4, 7, 8 ]


> double[] dArray = {10 , 12 , 14 , 5.0  , 1/3.0}

> Arrays.parallelSort(dArray)

> dArray
dArray ==> [ 0.3333333333333333, 5.0, 10.0, 12.0, 14.0 ]


> char cArray[] = { 'a' , 'e' , 'i' , 'o' , 'u' , 'z' , 'h' , 'r' , 'v' }

> Arrays.sort(cArray , 5 , 9)
/*
Sort cArray only from index 5 
    inclusive , till index 9 not
    inclusive .*/

> cArray
cArray ==> [ 'a', 'e', 'i', 'o', 'u', 'h', 'r', 'v', 'z' ]

> Arrays.parallelSort(cArray , 1 , 9)
/*
Parallel sort cArray from
    index 1 inclusive , till
    index 9 not inclusive .*/

> cArray
cArray ==> [ 'a', 'e', 'h', 'i', 'o', 'r', 'u', 'v', 'z' ]


> int iArrayOne [][] = { { 4, 2 }, { 1, 0 } }
iArrayOne ==> [ [4, 2 ], [ 1, 0 ] ]

> for ( int i = 0 ; i < iArrayOne.length ; i++ )
    Arrays.parallelSort(iArrayOne[i]);

> iArrayOne
iArrayOne ==> [ [ 2, 4 ], [ 0, 1 ] ]


> int iArrayTwo [][][] = { { { 4, 2 }, { 1, 0 } } };
iArrayTwo ==> [ [ [ 4, 2 ], [ 1, 0 ] ] ]

> for (int i = 0 ; i < iArrayTwo.length ; i++ )
    for(int j = 0 ; j < iArrayTwo[i].length ; j++ )
            Arrays.parallelSort(iArrayTwo[i][j]);

> iArrayTwo
iArrayTwo ==> [ [ [ 2, 4 ], [ 0, 1 ] ] ]

For arrays of reference type , if the type implements the Comparable interface , then these methods will use the compareTo method of the Comparable interface to sort the array . This is called the natural ordering , and the compareTo method is called the natural comparison method .

jshell> 

> import java.util.Arrays; 

> String sArray[] = { "ab", "aa", "ae" }
sArray ==> [ "ab", "aa", "ae" ]

> Arrays.parallelSort(sArray)
/*
The String class implements the comparable
  interface as such it is possible 
  to use either of Arrays.parallelSort
  or Arrays.sort to sort an array of 
  Strings .*/

> sArray
sArray ==> String[3] { "aa", "ab", "ae" }


> Object oArray[] = { new Object(), new Object() }
oArray ==> [ java.lang.Object@5e5792a0, java.lang.Object@26653222 ]

> Arrays.sort(oArray)
/*
The Object class does not implement 
  the Comparable interface , as such , 
  an array of Objects cannot be sorted
  using Arrays.sort or Arrays.parallelSort .*/
|  Exception java.lang.ClassCastException: class java.lang.Object cannot be cast to class java.lang.Comparable (java.lang.Object and java.lang.Comparable are in module java.base of loader 'bootstrap')
|        at ComparableTimSort.countRunAndMakeAscending (ComparableTimSort.java:320)
|        at ComparableTimSort.sort (ComparableTimSort.java:188)
|        at Arrays.sort (Arrays.java:1249)
|        at (#6:1)


> /*
Create a class File
  which implements the Comparable 
  interface .*/
class File implements Comparable<File>
{
    String fileName;
    public File(String fileName)
    {
        this.fileName = fileName ;
    }
    @Override
    public int compareTo(File file)
    {
        return this.fileName.compareTo(file.fileName);
    }
}

> File files[] = { new File("Manager.java"), new File("File.java") }
files ==> [ File@4b9e13df, File@2b98378d ]

> System.out.println( "[ " + files[0].fileName + " , " + files[1].fileName + " ]"); 
[ Manager.java , File.java ]

> Arrays.parallelSort(files , 0 , 2 )

> System.out.println( "[ " + files[0].fileName + " , " + files[1].fileName + " ]"); 
[ File.java , Manager.java ]

If a type does not implement the Comparable interface , then the Arrays.parallelSort and Arrays.sort , can be passed a Comparator to sort the arrays .

jshell> 

> import java.util.Arrays ; 

> Object oArray[] = { new Object(), new Object() }
oArray ==> [ java.lang.Object@735b5592, java.lang.Object@58651fd0 ]

> Arrays.parallelSort(oArray , 0 , 2 , new Comparator<Object>(){
    @Override 
    public int compare(Object objectOne , Object objectTwo)
    {
        return objectOne.toString().compareTo(objectTwo.toString());
    }
});
/*
Sort the array by passing a
  Comparator which sort by 
  the String value of Object .*/

> oArray
oArray ==> [ java.lang.Object@58651fd0, java.lang.Object@735b5592 ]


> /* 
Create a Class Point
which does not implement 
Comparable .*/
class Point
{
    String axis ; 
    int position ;
     
    public Point(String axis , int position)
    {
        this.axis = axis;
        this.position = position;
    }

    public String getAxis()
    {
        return this.axis;
    }

    public int getPosition()
    {
        return this.position;
    }

    public String toString()
    {
        return this.axis + ":" + position ; 
    }
}


> Point points[] = { new Point("y",10), new Point("x",5), new Point("y" ,1), new Point("z" , 4) }
/*
Create an array of points .*/
points ==> [ y:10, x:5, y:1, z:4 ]

Comparator<Point> axisComparator  = Comparator.comparing(Point::getAxis);
/*
The Comparator class has a static 
  method comparing.
It creates a Comparator using a 
  Comparable value extracted by 
  a function . 
In this case the Comparator created 
  for the Point type is using 
  the axis field which is a Comparable
  of type String .*/

> Arrays.sort( points , axisComparator )
/*
Sort the array using the Comparator :
  axisComparator .*/

> points
points ==> [ x:5, y:10, y:1, z:4 ]

> Arrays.sort( points , axisComparator.reversed())
/*
The reversed method of Comparator
  returns a reverse Comparator . 
  So the ordering will be 
  reversed .*/

> points
points ==> [ z:4.0, y:10.0, y:1.0, x:5.0 ]

> Comparator<Point> axisPositionComparator = Comparator.comparing(Point::getAxis).thenComparing(Point::getPosition);
/*
Create a Comparator which first 
  compares using the axis field , 
  and when the values are equal 
  compare using the position field .*/

> Arrays.parallelSort(points , axisPositionComparator );

> points
points ==> [ x:5, y:1, y:10, z:4 ]

> Arrays.parallelSort(points , ( point1 , point2 ) -> point1.position - point2.position ) ;
/*
Use lambda expression , to pass
  the compare method of Comparator .*/

> points
points ==> [ y:1, z:4, x:5, y:10 ]

The Stream API can also be used to create a sorted shallow copy of the array .

jshell> 

> import java.util.Arrays;

> int iArray[] = { 10, 3, 5 }
/*
Create an array of type 
  int[] , and store a 
  reference to it in the 
  variable iArray .*/
iArray ==> int[3] { 10, 3, 5 }

> int iArrayCopySorted [] = Arrays.stream(iArray).sorted().toArray()
/*
Use Arrays.stream to create a 
  sequential IntStream , with 
  its source being the
  array referenced by the
  variable iArray .
Using the sorted function ,
  create a sorted stream ,
  using primitive types 
  comparaison .
Use toArray method to create 
  an array of type int[]
  from the sorted IntStream 
Store a reference to the 
  created array in the 
  variable iArrayCopySorted .*/
iArrayCopySorted ==> int[3] { 3, 5, 10 }


> String sArray[] = {"ar" , "ab"}
/*
Create an array of type 
  String[] and store a 
  reference to it in the 
  variable sArray .*/
sArray ==> String[2] { "ar", "ab" }

> String sArrayCopySorted[] = Arrays.stream(sArray).sorted().toArray(String[]::new)
/*
Using Arrays.stream , create a 
  stream backed by the array 
  referenced by sArray . 
Using the sorted method , sort
  the String elements . String 
  implements the Comparable 
  interface . As such sort using 
  the compareTo method .
The sorted method returns a 
  sorted Stream of Objects .
Using the toArray method , create 
  an array from the elements of the 
  sorted Stream . 
Pass to the toArray , method the 
  function which will create the 
  array of the given type , and 
  the passed size to the 
  function 
Store a reference to the sorted
  array in the sArrayCopySorted
  variable .*/
sArrayCopySorted ==> [ "ab", "ar" ]


> int iaa[][] = { { 4, 3 }, { 2, 1 } } 
/*
Create an array of type int[][] ,
  and store a reference to it 
  in iaa .*/

> int iaaShallowCopySorted[][] = Arrays.
    stream(iaa).
    sorted(
        (ia1 , ia2)->
            {
                Arrays.parallelSort(ia1);
                Arrays.parallelSort(ia2);
                return ia1[0] - ia2[0];
            }).
    toArray(int[][]::new);
/*
Use Arrays.stream to create a 
  sequential stream backed by 
  the array referenced by the 
  variable iaa.
The elements of the stream are 
  of type int[] , and they don't
  implement the Comparable interface . 
As such we can pass to the sorted
  function a comparator , to be used
  for performing comparison between
  elements .
The comparator is passed as a lambda
  function . 
The lambda function takes , two variables
  of type int[] . Using Arrays.parallelSort
  it sorts , the arrays , and finally to 
  compare the two arrays , it compare 
  the first element of the two arrays , 
  by subtracting them .
The sorted function return a sorted 
  stream of objects .
Use the toArray method , to create
  an array of type int[][] , from 
  this sorted stream .
Store a reference of the newly
  created array in the variable 
  iaaShallowCopySorted .*/
iaaShallowCopySorted ==> [ [ 1, 2 ], [ 3, 4 ] ]
/*
iaaShallowCopySorted[0] is sorted.
iaaShallowCopySorted[1] is sorted.
The array referenced by iaaShallowCopySorted
  is sorted .*/

> iaa 
/*
iaa[0] is sorted . 
iaa[1] is sorted .
The array referenced by iaa is 
  not sorted .*/
iaa ==> [ [ 3, 4 ], [ 1, 2 ] ]

10- Searching for an element in an Array

If an array is sorted , the java.util.Arrays.binarySearch method can be used to search the array for a given element .

The Arrays.binarySearch method returns the index of the element if it is found . If not found it will return (-(insertion point) - 1) . So to get where the not found element must be inserted in the array , just negate the return value and subtract 1 .

If multiple elements match the elements to search for , there is no guarantee which matching element index is returned .

jshell> 

> import java.util.Arrays;

> int iArray[] = { 0, 1, 2 }
/*
iArray is a variable of type 
  int[] which holds a reference
  to a sorted Array .*/

> Arrays.binarySearch(iArray , -1)
/*
Search for the element -1 
  in the sorted array . 
The element -1 is not found.
-1 is less than 0 , so it must
  be inserted at index 0 , As such
  the binary search method returns 
  minus the insert position minus 1 , 
  which is : -0 -1 , which is -1 . 
To get where the element will be 
  inserted from the value returned 
  by Arrays.binarySearch , negate 
  the value and substract 1 . In this
  case --1 -1 = 1 -1 = 0 .*/
-1


> Arrays.binarySearch(iArray , 10)
/*
10 is not found in the sorted
  array , the binarySearch method 
  return minus the insert position
  of 10 minus 1. 
10 if it is to be inserted must be 
  inserted as the last element . As
  such binarySearch return -3 -1 
  which is -4 .*/
-4

> Arrays.binarySearch(iArray , 0 , 1 , 0)
/*
Search the array from index 0 inclusive , 
  to index 1 not inclusive , for the 
  integer 0 . 
The integer 0 is found in the array , 
  and this is the first element .*/
0


>int iArrayOne [][] = { { 2, 4 } , { 0, 1 } } ;
/*
iArrayOne holds a reference to an 
  array of length 2 which its elements
  are of type int [] . Each element of
  type int[] is sorted .*/

> int ElementToSearchFor = 0 ; 
/*
The element to search for is 0 .*/

> /*
Loop through the elements of the array
  referenced by the variable iArrayOne .
The elements of the array are of type
  int[] .
Each type int [] element is sorted , 
  search it using Arrays.binarySearch .
Print the index of the array where 
  the element is found , and the index
  of the element in the array .*/
for ( int i = 0 ; i < iArrayOne.length ; i++ )
    {
        int indexFoundElement = Arrays.binarySearch(iArrayOne[i] , ElementToSearchFor) ;
        if( indexFoundElement >= 0 ){
            System.out.println("Found at : [" + i + "]"  + "[" + indexFoundElement + "]");
            break;
        }
    }
Found at : [1][0]

When searching arrays which are not of the primitive types using the Arrays.binarySearch , the array elements type must implement the Comparable interface , or if not , a Comparator must be passed to Arrays.binarySearch .

jshell> 

> import java.util.Arrays;

> String sArray[] = { "ea", "ca", "ba" };
sArray ==> [ "ea", "ca", "ba" ]

> Arrays.parallelSort(sArray)
/*
sArray is not sorted , to search
  an array using Arrays.binarySearch
  it must be sorted . As such sort the 
  array using Arrays.parallelSort . 
If we don't want to sort the array , 
  a copy of it can be created and 
  searched .*/
sArray ==> [ "ba", "ca", "ea" ]

> Arrays.binarySearch(sArray , 1 , 3 , "ca")
/*
Search the array from index
  1 till index 3 , for the 
  element "ca" . 
String type implements the 
  Comparable interface , as 
  such the binarySearch method
  can be used .
An element containing a 
  reference to "ca" was 
  found at index 1 
  of the array . 
If String did not implement the
  Comparable interface a 
  java.lang.ClassCastException
  would have been thrown .*/
1

>/* Create class Seconds */
class Seconds
{
    int seconds ; 
    public Seconds(int seconds)
    {
        this.seconds = seconds;
    }
}

> Seconds time[] = { new Seconds(10), new Seconds(20) }
/*
The array containing Seconds(10) 
  and Seconds(20) is sorted by 
  seconds , since 10 < 20 .*/
time ==> [ Seconds@58651fd0, Seconds@4520ebad ]

> System.out.println( "[ " + time[0].seconds + " , " + time[1].seconds + " ]"); 
/*output*/
[ 10 , 20 ]

> Arrays.binarySearch( time , 0 , 2 , new Seconds(20) , new Comparator<Seconds>(){
    @Override 
    public int compare(Seconds secondsOne , Seconds secondsTwo)
    {
        return secondsOne.seconds - secondsTwo.seconds ;
    }});
/*
Use Arrays.binarySearch method 
  to search an array from 
  start index 0 inclusive , till
  index 2 exclusive . 
The element to search for is : 
  new Seconds(20) .
A Comparator was created to 
  compare the values of the 
  elements of the array by the 
  seconds field .*/
1

If the elements of the array are not sorted , we can loop over the array and compare each element individually , and just return the index.

jshelh>

> /*Class IndexSearch*/
class IndexSearch
{
    public static int findByIndex (int[] iArray , int iElement)
    {
    /* Method for primitive type int
     * Returns the index of the element to search for .  
     * -1 if not found .*/
        for(int i = 0 ; i < iArray.length ; i++)
        {
            if(iArray[i] == iElement )
            /* element found return its index .*/
                return i;
        }
        return -1 ;
    }


    public static <T extends Comparable<? super T>> int findByIndex (T[] cArray , T element)
    {
    /* Method for types which implement the Comparable interface
     * Returns the index of the element to search for .  
     * -1 if not found .*/
        for(int i = 0 ; i < cArray.length ; i++)
        {
            if(cArray[i].compareTo(element) == 0 )
            /* element found return its index .*/
                return i;
        }
        return -1 ;
    }

    public static <T> int findByIndex(T[] ncArray , T element , Comparator<? super T> comparator)
    /* Method For types that do not implement Comparable interface .
     * As such they must provide a Comparator .
     * Returns the index of the element to search for .  
     * -1 if not found .*/
    {
        for(int i = 0 ; i < ncArray.length ; i++)
        {
            if(comparator.compare(ncArray[i] , element) == 0 )
            /* element found return its index .*/
                return i;
        }
        return -1 ; 
    }
}

> int iArray[] = { 10, 0, 22, 11 }
/*
Create an array which has 
  a type of int[] , and which 
  is not sorted .
Store a reference to it in 
  the variable iArray .*/
iArray ==> [ 10, 0, 22, 11 ]

> IndexSearch.findByIndex(iArray , 22)
/*
Search the array for the 
  element 22 .
The element 22 is found at 
  index 2 .*/
2

> String sArray[] = { "ce", "af", "ah" }
/*
Create an array of type 
  String[] which is not 
  sorted .*/
sArray ==> [ "ce", "af", "ah" ]

> IndexSearch.findByIndex(sArray , "af")
/*
Search the array for the element 
  "af".
The String type implements the 
  Comparable interface , as such 
  the Comparable findByIndex 
  method is called .
The element of the array containing 
  a reference to a String of value 
  "af" is found at index 1 .*/
1

> Object object = new Object() ; 
/*
Create a new Object .*/
object ==> java.lang.Object@20e2cbe0

> Object oArray[] = { new Object()  , object };
/*
Create an array of two 
  objects .*/
oArray ==> Object[2] { java.lang.Object@68be2bc2, java.lang.Object@20e2cbe0 }

> IndexSearch.findByIndex(oArray , object , Comparator.comparing(Object::toString))
/*
Search the array for an object . 
Object does not implement the
  Comparable interface .
Create a Comparator using the 
  Comparator.comparing method from 
  the Object toString method .
IndexSearch.findByIndex comparator
  method is called .
A reference to the object searched 
  for is found at index 1 .*/
1

The Stream API , can be used to check for the existence of an element in an array , and to return the element , but it cannot be used to get the index of the element in a straight forward manner .

The Stream anyMatch method can be used to check if an element in the array verifies certain conditions , like for example equality , larger or equal , or anything else.

jshelh>

> import java.util.Arrays;

> int iArray[] = { 10, 2, 15 }
/*
Create an array of type int[] , 
  and store a reference to it 
  in iArray .*/
iArray ==> [ 10, 2, 15 ]

> Arrays.stream(iArray).anyMatch(iElem -> iElem == 2 );
/*
Using Arrays.stream create a
  sequential stream backed
  by the array referenced by
  the variable iArray.
Using the anyMatch method , 
  pass a lambda function , 
  to test if any element 
  is equal to 2 .*/
$ ==> true

> import java.util.function.Predicate;
/*
A predicate is a functional 
  interface , it can be assigned 
  a lambda function . 
A predicate can be combined 
  with another predicate using 
  the and , or methods . 
It can be negated using the 
  negate method .
A predicate is used to test for 
  a condition .*/

> import java.util.function.IntPredicate;

> IntPredicate lessTwenty = iElem  -> iElem < 20  ;
/*
Create a predicate which will test , 
  if the passed integer element
  is less than 20 . 
*/
lessTwenty ==> $Lambda$15/0x000000102faa9440@4520ebad

> IntPredicate lessTwentyAndLargerFourteen = lessTwenty.and( iElem -> iElem > 14 )
/*
Create a predicate , which will test
  if an element is less than twenty , 
  and larger than 14 .*/
lessTwentyAndLargerFourteen ==> java.util.function.Predicate$$Lambda$17/0x000000102faaa840@548a9f61

> Arrays.stream(iArray).anyMatch(lessTwentyAndLargerFourteen)
/*
Use Arrays.stream , to create 
  a sequential Stream backed by 
  the array referenced by the 
  variable iArray .
Use anyMatch with the predicate
  lessTwentyAndLargerFourteen , to 
  test if any element is larger than
  fourteen and less than twenty .*/
$ ==> true


> String[][] sArray = { { "ab", "ar" }, {"iq", "id" } }
/*
Create an array of type String[][] , 
  and store a reference to it in , 
  the variable sArray .*/
sArray ==> [ [ "ab", "ar" ], [ "iq", "id" ] ]

> Predicate<String[]> isNull = saElem -> saElem == null ;
/*
Create a lambda function which takes
  an element of type String[] , and
  check if its null .
Store a reference to it , in the 
  variable isNull .*/
isNull ==> $Lambda$28/0x000000102faad040@57baeedf

> Arrays.stream(sArray).anyMatch(isNull)
/*
Use Arrays.stream method to create
  a sequential stream , backed by
  the array referenced by sArray.
Use the anymatch method to check , if
  any element , is null , by passing
  the predicate isNull .*/
$ ==> false

> Arrays.stream(sArray).anyMatch(isNull.negate())
/*
Use Arrays.stream method to 
  create a sequential stream , 
  backed by the array 
  referenced by sArray.
Use the anymatch method to 
  check , if any element , 
  is not null , by passing
  the negation of the 
  predicate isNull .*/
$ ==> true

The Stream filter method can be used to get a stream which elements satisfies certain predicates .

An array can be constructed from the filtered stream using the Stream toArray method .

A stream truncated to a certain number of elements , can be created from the filtered Stream using the Stream limit method .

An optional can be returned from the filtered Stream using the Stream findAny or findFirst methods .

The findFirst method , will return the first element of a Stream if the Stream has an encounter order , or any element if the stream does not have an encounter order .

The findAny will return any element of a Stream .

jshell>

> import java.util.Arrays;

> int iArray[] = { 1, 2, 10, 2 }
/*
Create an array of type int[] ,
  store a reference to it , in 
  the variable iArray .*/

> Arrays.stream(iArray).filter( iElem -> iElem == 2 ).toArray()
/*
Use Arrays.stream to create a 
  sequential Stream backed
  by the array referenced by 
  iArray .
Using the filter method , pass 
  a predicate which create a
  stream whose elements are
  filtered to be equal to 2 .
Using the toArray method , convert
  the filtered Stream to an int [] .*/
[ 2 , 2 ]

> Arrays.stream(iArray).filter( iElem -> iElem != 2 ).limit(1).toArray()
/*
Use Arrays.stream to create a 
  sequential Stream backed
  by the array referenced by 
  iArray .
Using filter method , pass a predicate , 
  which create a stream containing
  elements different than
  2 .
Using limit method , create a Stream 
  from the filtered Stream truncated
  to length 1 .
Using the toArray method , create an  
  array of type int[] .*/
[ 1 ]

> Arrays.stream(iArray).filter( iElem -> iElem > 1 ).findFirst()
/*
Use Arrays.stream to create a 
  sequential Stream backed
  by the array referenced by 
  iArray .
Use filter method , to create a 
  Stream containing elements 
  larger than 1 . 
Use findFirst to return an 
  optional , containing the 
  first element in the Stream , 
  if the Stream has an encounter 
  order , or any element if
  not .*/
$ ==> OptionalInt[2]

> Arrays.stream(iArray).filter( iElem -> iElem > 1 ).findAny()
$ ==> OptionalInt[2]
/*
Use Arrays.stream to create a 
  sequential Stream backed
  by the array referenced by 
  iArray .
Use filter method , to create a 
  Stream containing elements 
  larger than 1 . 
Use findAny to return an optional , 
  containing any element in the 
  Stream .*/
$ ==> OptionalInt[2]



> int iArray[][] = { { 1, 2 }, null, { } }
/*
Create an array of type int [][] , 
  and store a reference to it , 
  in the variable iArray. */
[ [ 1 , 2 ], null, [ ] ]

> Predicate<int []> isNull = iaElem -> iaElem == null ;
/*
Create a lambda function , which 
  checks , if its parameter of 
  type int [] is null .*/
isNull ==> $Lambda$15/0x000000102faa9440@5419f379

> Predicate<int []> isNullOrEmpty = isNull.or( iaElem -> iaElem.length == 0 ) 
/* 
Create a Predicate which check if its 
  parameter of type int[] is null or 
  if it has a length of 0 .*/
isNullOrEmpty ==> java.util.function.Predicate$$Lambda$17/0x000000102faaa840@1753acfe

> Arrays.stream(iArray).filter(isNullOrEmpty.negate()).findAny()
/*
Use Arrays.stream to create a 
  sequential Stream backed
  by the array referenced by 
  iArray .
Use the filter method , to 
  create a Stream which elements
  are neither null nor arrays
  which have a length of 0 .
use findAny method to return , 
  the first found element , if 
  the stream has an encounter
  order , or any element if
  not .*/
$10 ==> Optional[[I@6093dd95]

11- Checking for arrays equality

The == operator can be used to check if two variables refers to the same array .

jshell>

> int iArray[] = { 1, 2, 3 } , iArrayTwo[] , iArrayThree[] ;
/*
Create an array of type 
  int[] , having the three 
  elements 1 , 2 and 3 .
Store a reference to it , 
  in the variable iArray .
The variable iArrayTwo 
  and iArrayThree holds 
  no reference to any 
  array of type int[] , 
  as such they refer 
  to null .*/
iArray ==> int[3] { 1, 2, 3 }
iArrayTwo ==> null
iArrayThree ==> null

> iArrayThree == iArrayTwo
/*
The variable iArrayThree and
  iArrayTwo are both of type
  int [] , and they both hold
  no reference to any array
  of type int[] , as such they
  both refers to null .*/
$ ==> true

> iArray == iArrayTwo
/*
Compare the reference held 
  by the variable iArray , 
  and the reference held 
  by the variable iArrayTwo 
  for equality .*/
$ ==> false

> iArrayTwo = iArray
/*
Assign the reference held by the
  variable iArray , to the 
  variable iArrayTwo. */

> iArray == iArrayTwo
/*
Compare the reference held by
  the variable iArray , to the 
  reference held by the variable
  iArrayTwo for equality */
$ ==> true

The Arrays.equals and Arrays.deepEquals methods can be used to compare two arrays for equality .

The Arrays.equals , will first check if the two passed variables refer to the same arrays , if so , they are equal . If not , and if any refers to null while the other is not null , it will return false . If not , if their length is different , it will return false . Finally it will compare the elements of the arrays using the == operator . If all the elements are deemed equal by ==, then Arrays.equals return true .

jshell>

> int iArrayOne[] = { 1, 2, 3 } , iArrayTwo[] = { 1, 2, 4 } ;
/*
Create an array of type int [] ,
  formed from the elements : 1 ,
  2 and 3 , and store a reference
  to it in the variable 
  iArrayOne .
Create an array of type int[] , 
  containing the elements : 1 , 2 
  , 4 , and hold a reference to it
  in the variable iArrayTwo .*/
iArrayOne ==>  { 1, 2, 3 }
iArrayTwo ==>  { 1, 2, 4 }

> Arrays.equals( iArrayOne , iArrayTwo )
/*
iArrayOne != iArrayTwo
iArrayOne and iArrayTwo are both
  not null . 
iArrayOne and iArrayTwo have the same 
  length .
Compare the elements of both arrays , 
  using the == operator . 
1 == 1 , 2 == 2 , 3 != 4 .*/
$ ==> false

The Arrays.deepEquals method will first check if the two passed variables are equal using the == operator .

Next if the variables are not equal using the == operator , and if any is null , it will return false .

If neither variables holds a reference to null , but if the arrays referred by these variables have different length , this method return false .

Next this method will loop through the two arrays , comparing the elements in order .

Two elements are equal if either using the== return true , or if they are both not arrays and using the element from the first array equals method , passing the element from the second array , returns true , or if they are both arrays of objects , and recursively calling the deepEquals method on these two elements return true , or if they are arrays of the primitive types and calling the Arrays.equals method on these two elements return true .

jshell>

> int iArray[] = { 1, 2 };
/*
Create an array of type int 
  [] , containing the elements 
  1 and 2 , and store a reference 
  to it in the variable 
  iArray .*/
iArray ==> [ 1, 2 ]

> int iArrayTwo[][] = { iArray , iArray } ;
/*
Create an array of type int[][] , 
  stores inside it two references
  to the array referenced by 
  the iArray variable .*/
iArrayTwo ==> [ [ 1, 2 ], [ 1, 2 ] ]

> int iArrayThree[][] = { iArray , { 1, 2 } }
/*
Create an array of type int[][] , 
  store a reference inside it to the 
  array referenced by the variable 
  iArray . 
Create another array of type int[] , 
  containing the values 1 and 2 , 
  and store a reference to it 
  inside the array referenced by
  iArrayThree .*/
iArrayThree ==> [ [ 1, 2 ], [ 1, 2 ] ]

> Arrays.equals(iArrayTwo , iArrayThree)
/*
iArrayTwo != iArrayThree .
iArrayTwo and iArrayThree are 
  both not null .
iArrayTwo and iArrayThree have 
  equal length .
Compare the elements of both 
  arrays in order .
iArrayTwo[0] == iArrayThree[0]
iArrayTwo[1] != iArrayThree[1] .*/
$ ==> false


> Arrays.deepEquals(iArrayTwo , iArrayThree)
/*
iArrayTwo != iArrayThree .
iArrayTwo and iArrayThree are 
  both not null .
iArrayTwo and iArrayThree have 
  equal length .
Compare the elements of both 
  arrays in order .
iArrayTwo[0] == iArrayThree[0]
iArrayTwo[1] != iArrayThree[1]
Both iArrayTwo[1] and iArrayThree[1] 
  are not null .
Both iArrayTwo[1] and iArrayThree[1] 
  are of type int[] .
Use Arrays.equals(iArrayTwo[1] , iArrayThree[1]  )
  iArrayTwo[1]  != iArrayThree[1] .
  iArrayTwo[1] and iArrayThree[1] are 
    both not null .
  iArrayTwo[1] and iArrayThree[1] have 
    equal length .
  Compare the elements of both 
    iArrayTwo[1] and iArrayThree[1] 
    in order .
  iArrayTwo[1][0] == iArrayThree[1][0]
  iArrayTwo[1][1] == iArrayThree[1][1] .*/
$ ==> true

12- Filling an array

The Arrays.fill method , can be used to fill a part of an array , or a whole array , using a provided single value .

jshell>

> import java.util.Arrays ; 

> int iArray[] = new int[3];
/*
Create an array of type int[]
  , having a length of 
  three .
The array is of type int[] , as
  such all of its elements are 
  initialized to the default 
  value of 0 .
Store a reference to the 
  newly created array in the 
  variable iArray .*/
iArray ==> [ 0, 0, 0 ]

> Arrays.fill(iArray , 1 , 3 , 1 )
/*
Fill the elements of
  the array referenced by
  the variable iArray , 
  starting index 1 inclusive , 
  till index 3 exclusive , 
  with the value 1 .*/

> iArray
iArray ==> [ 0, 1, 1 ]


> int iArrayOne[][] = new int[2][2]
/*
Create an array of length 2 , 
  which elements are of type 
  int[] .
Create two arrays of type 
  int[] , each of length 2 ,
  which elements are initialized
  to 0 , and store a reference 
  to them inside the array
  referenced by the variable
  iArrayOne .*/
iArrayOne ==> [ [ 0, 0 ], [ 0, 0 ] ]

> Arrays.fill(iArrayOne , new int[]{1,0})
/*
Create an array of type int [] ,
  having the two elements 1 , 
  and 0 .
Fill the elements of the array 
  referenced by the variable 
  iArrayOne , with a reference
  to the newly created array .*/

> iArrayOne
iArrayOne ==> [ [ 1, 0 ], [ 1, 0 ] ]

13- Generating an array

The Arrays.parallelSetAll and Arrays.setAll methods can be used to fill all the elements of an array using a provided generator function . The generator functions receives the index of the element to be filled.

The difference between Arrays.parallelSetAll and Arrays.setAll is that in Arrays.parallelSetAll , the filling is done in parallel .

jshell >

> import java.util.Arrays ;

> double dArray[] = new double[2] ; 
/*
Create an array of type double[] ,
  which its elements are 
  initialized to the default 
  value of 0.0 .
Store a reference to it in the 
  variable dArray .*/

> Arrays.parallelSetAll( dArray, index -> Math.random() + index );
/*
Parallel set all the elements of 
  the array referenced by the 
  variable dArray using the
  parallelSetAll function . 
The parallelSetAll receives , 
  as a first argument , the 
  array to be filled , and 
  as a second argument , a 
  function which receives the
  index of the element to be
  filled , and generates 
  an element .*/

> dArray
dArray ==> [ 0.5157471129598236, 1.1915950324664246 ]

The Stream API generate method can be used to generate a sequential unordered stream .

It receives as an argument a function which will perform generating the elements of the stream .

The generate method can be used with the limit method of the Stream API , to create a stream with the specified limit , and with the toArray method to create an array.

jshell >

> import java.util.stream.Stream;

> Double dArray[] = Stream.generate(()->Math.random()).limit(2).toArray(Double[]::new);
/*
Pass to the Stream.generate method
  a lambda function , which 
  returns a random double 
  number .
Using limit , create a stream with 
  only 2 elements from the stream 
  generated by generate . 
Using toArray , create an array 
  out of the elements of this 
  stream , passing a function which 
  will create an array of a Double 
  type , and of the length provided 
  by toArray .*/
dArray ==> [ 0.12407886170343518, 0.6000542329067424 ]

The Stream API iterate method can be used to generate a sequential ordered stream . It takes as an argument a seed , and a function , and it will produce the series seed , f(seed) , f(f(seed)) ... .

Using the limit method of Stream , a stream with a limited number of elements can be created from the stream generated by iterate , and using the Stream toArray method , an array can be created out of the limited Stream .

jshell >

> import java.util.stream.Stream;

> Integer iArray [] = Stream.iterate( 1 , seed -> 2 * seed).limit(4).toArray(Integer[]::new);
/*
Create a Stream using the iterate
  method . The elements of the 
  stream are 1 , 2 , 4 , 8... They 
  are the seed and the computed values 
  by the function passed to iterate 
  which receives as argument , 
  the seed , f(seed) ...
Create a stream of 4 elements using
  the limit method . 
Create an array from the elements
  of the limited Stream , passing
  to toArray , a function which 
  will create an array of the 
  Integer type , and of the length
  provided by toArray .*/
iArray ==> [ 1, 2, 4, 8 ]

14- Finding the max and min elements of an array

If the array is sorted in ascending order, then the min element is the first element of the array , and the max element is the last element of the array .

If the array is not sorted , any of the looping mechanism can be used to search the array for the min and max value .

> int iArray[] = { 1 , 2, 3 }
/*
Create an array of type int [] ,
  containing the three elements 
  1 , 2 and 3 .
Store a reference to this array , 
  in the variable iArray .*/
iArray ==> [ 1, 2, 3 ]

/*
The array referenced by iArray ,
  is sorted in ascending order , 
  as such the min value is 
  iArray[0] , and the max value
  is iArray[2] .*/


> int iArray[] = { 3 , -1, 2 }
/*
Create an array of type int[] , 
  containing the elements 3 , -1
  and 2 . 
Store a reference to it inside 
  the variable iArray .*/
iArray ==> [ 3, -1, 2 ]

> int max = Integer.MIN_VALUE
/*
set max equal to 
  Integer.MIN_VALUE .*/
max ==> -2147483648

> int min = Integer.MAX_VALUE
/*
set min equal to 
  Integer.MAX_VALUE .*/
min ==> 2147483647

> for (int iElem : iArray)
{
   if(iElem > max)
      max = iElem;
   if(iElem < min )
      min = iElem;
}
> max 
max ==> 3

> min
min ==> -1

The Stream API max and min methods , can also be used for finding the max and min values .

> import java.util.Arrays;

> int iArray[] = { 1, -1, 2 }
/*
Create an array of type int[] , and
  store a reference to it in
  the variable iArray .*/

> Arrays.stream(iArray).max()
/*
Use Arrays.stream method to 
  get a sequential stream backed
  by the array referenced by 
  iArray .
Use the Stream max method to 
  find the max element of the
  stream .
The Stream max method returns
  an Optional .*/
$ ==> OptionalInt[2]

> Arrays.stream(iArray).min()
/*
Use Arrays.stream method to
  create a sequential stream
  backed by the array referenced
  by iArray .
Use the Stream method min , 
  to find the min value of the
  stream .
The stream min method returns , 
  an Optional .*/
$ ==> OptionalInt[-1]


> String sArray[] = { "or" , "ei" }
/*
Create an array of type String[] ,
  containing two references
  to the Strings "or" , and 
  "ei" .
Store a reference of this array ,
  in the variable sArray .*/

> Arrays.stream(sArray).min((elem1 , elem2)-> elem1.compareTo(elem2))
/*
use Arrays.stream to create
  a sequential stream backed
  by the array referenced by 
  sArray .
The created stream is a stream of 
  objects , as such we pass a 
  Comparator to min , to perform
  the Comparison . 
The passed Comparator is a lambda
  function , which calls the compareTo
  method of elem1 . 
elem1 and elem2 , both have the 
  compareTo method because the 
  stream objects are of type 
  String , and String implements
  the Comparable interface .*/
$ ==> Optional[ei]

> Arrays.stream(sArray).max((elem1 , elem2)-> elem1.compareTo(elem2))
/*
Use Arrays.stream method to 
  create a sequential stream 
  backed by the array referenced 
  by the variable sArray .
The Stream is a stream of 
  objects , as such pass a 
  Comparator to the Stream max 
  function .
The comparator is an lambda 
  function , which call elem1 
  compareTo method .
The max method returns an Optional .*/
$ ==> Optional[or]

15- Finding the average , and the sum of an array

To find the average or the sum of an array , any of the looping methods can be used .

jshell>

> int iArray[] = {-1, 0, 2 };
/*
Create an array of type 
  int[] , and store a 
  reference to it , in the
  variable iArray .*/
iArray ==> [ -1, 0, 2 ]

> double sum = 0.0 ;
sum ==> 0.0

> double average = 0.0 ; 
average ==> 0.0

> for(int iElem : iArray)
/*
Calculate the sum of the 
  array referenced by the
  variable iArray. */
  sum += iElem;

> sum 
sum ==> 1.0

> average = sum / iArray.length ;
average ==> 0.3333333333333333

In the Stream API , IntStream , LongStream , and DoubleStream provide the average and sum methods which can be used , to calculate the average and sum of an array .

jshell>

> import java.util.Arrays;

> int iArray[] = { -1, 0, 2 }
iArray ==> [ -1, 0, 2 ]

> Arrays.stream(iArray).sum()
$ ==> 1

> Arrays.stream(iArray).average()
$4 ==> OptionalDouble[0.3333333333333333]

16- Reducing an array

The Stream API provide the reduce method , which can be used to iterate over all the elements of a stream to perform a combining computation , and return a single value .

The reduce method can be used to calculate the sum , average , min , and max and other functions over a stream . An Array can be converted to a Stream using the Arrays.stream method .

jshell>

> import java.util.Arrays;
> import java.util.stream.IntStream;
> import java.util.stream.Stream;

> int iArray[] = { 1, -2, 3 };
/*
Create an array of type int[] , 
  containing the elements ,
  1 , -2 and 3 , and store
  a reference of it in the 
  variable iArray .*/
iArray ==> [ 1, -2, 3 ]

> Arrays.stream(iArray).reduce(Integer::sum);
/*
Use Arrays.stream to create
  a sequential stream backed by
  the array referenced by 
  iArray .
Using the reduce function , 
  compute the sum of the 
  elements of the stream , by
  passing the sum function
  of Integer .*/
$ ==> OptionalInt[2]


> String sArray[] = { "hello ", "world" };
sArray ==> [ "hello ", "world" ]
/*
Create an array of type String[] , 
  containing references to the 
  String "hello" and "world" .
Store a reference of this array
  in the variable sArray .*/

> Arrays.stream(sArray).reduce((previous , current)-> previous + current );
/*
use Arrays.stream to create 
  a sequential Stream , backed 
  by the array referenced by 
  the variable sArray.
Pass a lambda function to ,
  reduce. It receives the previous
  computed value , and the current
  iterating element , and return 
  the currently computed value .
reduce returns an Optional .*/
$ ==> Optional[hello world]


> int iArray[][] = { { 1, 2}, { 3, 4 } }
/*
Create an array of type int[][] ,
  and store a reference to it ,
  in the variable iArray .*/

> Arrays.
    stream(iArray).
    reduce(
            (prev, current)-> 
                    IntStream.concat(Arrays.stream(prev) , Arrays.stream(current)).toArray()
        ).
    get()
/*
This expression creates an 
  int[] out of an int[][] .
Use Arrays.stream to create a 
  sequential stream , backed 
  by the array reference by iArray .
Use reduce method , to pass
  a function , which takes a
  previous computed value , and 
  a current iterating value.
The function uses IntStream.concat 
  method , to concatenate the 
  streams created from the previous
  int [] array and the current int [] 
  array , using the Arrays.stream ,
  method. 
  It then create an array of type 
  int [] from this stream .
The reduce functions returns an
  Optional , and we use the get method
  of an Optional to retrieve its 
  value .*/
$ ==> int[4] { 1, 2, 3, 4 }


> int iArray[] = {} ; 
/*
Create an array of type int[]
  , having no elements .
Assign a reference to this array,
  in the variable iArray .*/
iArray ==> [ ]

> Arrays.stream(iArray).reduce(Integer::sum)
/*
Use Arrays.stream to create
  a sequential stream backed 
  by the array referenced by
  iArray.
Pass the Integer::sum function
  to reduce , to perform the 
  summation of the elements of 
  the stream . 
Since no elements are found in
  the Stream , reduce returns 
  an empty optional .
An empty optional , have no value .*/
$ ==> OptionalInt.empty

> Arrays.stream(iArray).reduce(0, Integer::sum)
/*
Instead of getting an empty Optional , 
  when no elements are present in
  the Stream , an initial value ,
  can be passed to reduce . 
If no elements are found , in the 
  stream , the initial value is returned . 
If elements are found in the stream , 
  reduce starts from the provided 
  initial value .*/
$ ==> 0


> int iArray[][] = { { 1, 2 }, { 3, 4 } };
iArray ==> [ [ 1, 2 ], [ 3, 4 ] ]
/*
Create an array of type int[][] , 
  and store a reference to it ,
  in the iArray variable .*/

> Arrays.
    stream(iArray).
    reduce(
            IntStream.empty(),
            (prev, current)-> 
                IntStream.concat(prev , Arrays.stream(current)),
            IntStream::concat
        ).
    toArray()
/*
Use Arrays.stream to create 
  a sequential Stream backed by
  the array referenced by iArray.
Use reduce method , to convert
  this stream which is of type
  int [] , into a stream of type 
  int . 
The first argument to reduce , 
  is the default or initial value.
  It is an empty Stream of type int .
The second argument is a function ,
  that will concat the previous
  value with the current value , 
  using IntStream.concat , 
  returning a stream of int .
  The previous value is of type 
  IntStream , whereas the current
  value of type int []. As such
  Arrays.stream is used to 
  convert it to a Stream of 
  type int .
The last argument to reduce , is 
  a function which will return 
  a value of the type of the 
  default value , which in 
  this case is an IntStream . 
  The function passed is
  IntStream::concat .
An array is created from , 
  the created IntStream elements
  , using the Stream toArray 
  method .*/
$ ==> int[4] { 1, 2, 3, 4 }

17- Converting arrays

A list view can be gotten from an array , by using the Arrays.aslist method . The created list , will have the provided array, as its data store , it will be fixed size , and modification to any will affect the other .

jshell>

> import java.util.List;
> import java.util.Arrays;
> import java.util.Set;
> import java.util.TreeSet;

> Integer iArray[] = new Integer[3] ;
/*
Create an array of type 
  Integer [] , of length 3 , 
  all of its elements contain
  a reference to null . 
Store a reference to this array , 
  in the iArray variable. */
iArray ==> [ null, null, null ]

> List<Integer> iList = Arrays.asList(iArray) ;
/*
Create a fixed sized List , backed 
  by the array reference by the 
  variable iArray. */
iList ==> [null, null, null]

> iList.set(0 , 1 )
/*
Set the first element of the 
  list to 1 .*/
iList ==> [1, null, null]

> iArray
/*
Print the content of the array
  referenced by iArray .*/
iArray ==> [ 1, null, null ]

> Arrays.fill(iArray , 2 ) ;
/*
Fill the array reference by
  iArray with 2 .*/

> iList
/*
Print the content of the list
  reference by iList . */
iList ==> [2, 2, 2]

/*
Once an array is converted to a List , 
  Other collections can be gotten .*/

> Set<Integer> sInteger = new TreeSet<Integer>(iList);
/*
Create a TreeSet from the 
  list referenced by iList . 
A Set contains no duplicate .*/
sInteger ==> [2]

The Arrays.stream method , can be used to create a sequential stream backed by the provided array . A stream can be collected into various Collections , such as List , Set ...

jshell>

> import java.util.Arrays;
> import java.util.stream.Collectors;

> Integer iArray [] = { 1, 2, 2, 1, 0 }
/*
Create an array of type int [] , 
  containing the elements , 
  1 , 2 , 2 , 1 , 0 .
Store a reference to this 
  array in the variable iArray .*/
iArray ==> [ 1, 2, 2, 1, 0 ]

> Arrays.stream(iArray).collect(Collectors.toList());
/*
Use Arrays.stream method to 
  create a sequential stream ,
  backed by the array reference 
  by iArray . 
Use the Stream collect method , 
  by passing to it a Collector .
The collector accumulate the 
  elements of the stream into a 
  List .*/
$ ==> [1, 2, 2, 1, 0]

> Arrays.stream(iArray).collect(Collectors.toSet());
/*
Use Arrays.stream to create 
  a sequential stream backed
  by the array referenced by 
  the iArray variable. 
Use the Stream collect method , 
  to pass a Collector , which 
  collect the elements of the 
  Stream into a Set .*/
$ ==> [0, 1, 2]

> Arrays.stream(iArray).skip(3).collect(Collectors.toCollection(PriorityQueue::new));
/*
Use Arrays.stream method , to
  create a sequential stream , 
  backed by the array referenced
  by the iArray variable.
Use skip , to create a Stream , 
  which skipped three elements 
  of the previous stream . 
Use Collect function , passing to
  it a Collector , which will 
  collect the element of the 
  Stream , into a PriorityQueue .*/
$ ==> [0, 1, 2, 2, 1]

18- Reversing an Array

To reverse an array , one can use this method :

int anArray[] = {1, 2 ,4 };

for(int i = 0 ; i < anArray.length / 2 ; i++ )
{
    int tmp = anArray[i];
    anArray[i] = anArray[anArray.length - i - 1];
    anArray[anArray.length - i - 1 ] = tmp ;
}

/*
anArray ==> [ 4, 2, 1 ]
*/

19- Cartesian product of Two arrays

The Cartesian product of two arrays , can be calculated as follows :

int anArrayOne[] = { 1, 2, 4 } ;

int anArrayTwo[] = { 4, 5, 6 } ;

int aCartesianProduct[][][] = new int[anArrayOne.length][anArrayTwo.length][2];

for (int i = 0 ; i < anArrayOne.length ; i++)
    for(int j = 0 ; j < anArrayTwo.length ; j++)
        aCartesianProduct[i][j] = new int[]{anArrayOne[i],anArrayTwo[j]};

/*
Output : 
[[[1, 4], [1, 5], [1, 6]], [[2, 4], [2, 5], [2, 6]], [[4, 4], [4, 5], [4, 6]]]*/