Overview
Copying a portion of an array is a very common operation that every developer come across. In this article, we will see traditional imperative style and modern declarative style code with lambda and streams API.
Imperative Approach
- Java has a deep route in imperative style programming. Hence for Java developers, it’s very natural to write the below code to copy a certain portion of an original array. Just iterating over elements and filtering out only elements that are needed and writing down to the final array.
private static int[] copyArray(){
int[] numbers = {1,2,3,4,5,6,7};
int[] subArray = new int[numbers.length-3];
int j =3;
for (int i=0;i<subArray.length;i++){
subArray[i] = numbers[j+i];
}
System.out.println(Arrays.toString(subArray));
return subArray;
}
Many of us often forget that there is a convenient method provided inside the java Arrays library for us copyOfRange. This method can be used to copy a portion of the array by supplying to and from the index.
private static int[] copyArray1(){
int[] numbers = {1,2,3,4,5,6,7};
int[] subArray = Arrays.copyOfRange(numbers,3,numbers.length);
System.out.println(Arrays.toString(subArray));
return subArray;
}
Declarative Approach
- Since Java 8 and beyond we can conveniently use streams API to copy a portion of the array.
- In the below code, we can are streaming int[] and only filtering out values that are greater than 3 and finally copying to the array.
private static void copyArray2(){
int[] numbers = {1,2,3,4,5,6,7};
// copy with values
int[] subArray = Arrays.stream(numbers).filter(a-> a>3).toArray();
System.out.println(Arrays.toString(subArray));
}
- The above code is a copy part of an array based on values, but we can also copy based on an index. Below code we are streaming Intstream from i=0; i=len(array).
- Generally in imperative code, we write for loop from a start index to an end index and iterate over each element. A similar thing we can do using Intstream and get access to the index element.
// copy with index
int[] subArray1 = IntStream
.range(0, numbers.length)
.filter(i -> i > 3)
.map(a->numbers[a]).toArray();
System.out.println(Arrays.toString(subArray1));
Although the above method works, we have another approach where we can use AtomicInteger to copy part of an array. It has a method called getAndIncrement which essentially provides an index and increments it by 1.
// copy with index
AtomicInteger atomicInteger = new AtomicInteger();
int[] subArray2 = Arrays.stream(numbers).filter(i -> atomicInteger.getAndIncrement() > 3).toArray();
System.out.println(Arrays.toString(subArray2));
Conclusion
In this article, we discussed how can we copy part of the java array using imperative and declarative styles. I would prefer declarative style code as it makes my code more readable and less verbose.
Bonus Tip
- If you want to upskill your Java, you should definitely check out this bestseller course
It was an amazing blog post. Thank you for sharing with us…
Glad you liked it!