362

I have an array of Integers in Java, I would like use only a part of it. I know in Python you can do something like this array[index:] and it returns the array from the index. Is something like this possible in Java.

Giacomo
  • 551
  • 2
  • 4
  • 16
Borut Flis
  • 15,715
  • 30
  • 92
  • 119

8 Answers8

591

The length of an array in Java is immutable. So, you need to copy the desired part into a new array.

Use copyOfRange method from java.util.Arrays class:

int[] newArray = Arrays.copyOfRange(oldArray, startIndex, endIndex);

startIndex is the initial index of the range to be copied, inclusive.
endIndex is the final index of the range to be copied, exclusive. (This index may lie outside the array)

E.g.:

   //index   0   1   2   3   4
int[] arr = {10, 20, 30, 40, 50};
Arrays.copyOfRange(arr, 0, 2);          // returns {10, 20}
Arrays.copyOfRange(arr, 1, 4);          // returns {20, 30, 40}
Arrays.copyOfRange(arr, 2, arr.length); // returns {30, 40, 50} (length = 5)
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
elias
  • 15,010
  • 4
  • 40
  • 65
  • there seems to be a size limit? only this works: `Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)` as instead of 255 I cannot use Integer.MAX_VALUE, in case I dont want to get the real length – Aquarius Power Nov 17 '16 at 01:01
  • @AquariusPower the size limit is the array size, and it can be bigger than 255. You just cannot provide an `endIndex` bigger than the size of the array passed as the first argument. So, if you want a full copy, create a variable referring to this array and use `Arrays.copyOfRange(var, 0, var.length)` or `Arrays.copyOf(var, var.length)` – elias Nov 17 '16 at 11:18
  • I would have to create a local var for the stacktrace sub-array, but I found that this works!!! `Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)` – Aquarius Power Nov 17 '16 at 20:15
  • Be careful about `ArrayIndexOutOfBoundsException`. – elias Nov 18 '16 at 13:29
  • What will happen if startIndex == endIndex, say Arrays.copyofRange(arr, 0, 0) ? – LookIntoEast Aug 06 '17 at 19:37
  • If `startIndex == endIndex`, a zero length array will be returned. – elias Aug 07 '17 at 18:04
  • 1
    there is another problem. What if I need to split the string array of length say 500K into the subarrays of 250K. These method accepts interegr which max out at 65000. – Vishnu Dahatonde Oct 10 '17 at 10:20
  • 1
    Integer in Java is max 2^31-1, not 2^16. – Mark Rotteveel Nov 25 '18 at 21:40
  • 1
    @elias , just the answer I was looking for. Thanks. – Sakhawat Hossain Apr 20 '20 at 08:23
39

You could wrap your array as a list, and request a sublist of it.

MyClass[] array = ...;
List<MyClass> subArray = Arrays.asList(array).subList(index, array.length);
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
K-ballo
  • 80,396
  • 20
  • 159
  • 169
26

Yes, you can use Arrays.copyOfRange

It does about the same thing (note there is a copy : you don't change the initial array).

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 2
    That said, if you don't want to make an explicit copy, you'll need to use a `List` and a `subList` as outlined in @K-ballo's answer. – Louis Wasserman Jun 12 '12 at 17:48
  • That's right. Java doesn't have the array slicing facilities that more modern languages offer. – Denys Séguret Jun 12 '12 at 17:50
  • I'm not sure if I'd put it that way, but...yes, Java doesn't offer array slicing. (That said, there are some advantages to this approach: reduced possibilities for memory leaks, reduced array overhead by avoiding the extra fields, etc. You could go either way.) – Louis Wasserman Jun 12 '12 at 17:51
  • Yes, you're right again (and I didn't try to start a flame war ;) ). Slicing makes GC very complex. And when Java did try object based implicit slicing in Strings [it made it more evident that this was dangerous](http://stackoverflow.com/questions/10951812/java-not-garbage-collecting-memory/10951867#10951867). – Denys Séguret Jun 12 '12 at 18:03
19

You can try:

System.arraycopy(sourceArray, 0, targetArray, 0, targetArray.length);// copies whole array

// copies elements 1 and 2 from sourceArray to targetArray
System.arraycopy(sourceArray, 1, targetArray, 0, 2); 

See javadoc for System.

StvnBrkdll
  • 3,924
  • 1
  • 24
  • 31
  • 3
    I just love how this is exactly how Arrays.copyOf() and Arrays.copyOfRange() are actually implemented (sans bounds checks) and yet it gets no votes whilst the slightly higher overhead utility method wrappers rack up the votes despite System.arraycopy dating back to 1995. – Dave Apr 23 '18 at 13:34
  • 2
    I guess it just doesn't look "modern" enough for some. – Dave Apr 23 '18 at 13:35
  • I like going old school, no shiny bells and whistles just the required machinery. Like memcpy in C – StvnBrkdll Apr 23 '18 at 13:55
  • 2
    But using arrays.copyOfRange() increases readability and reduces significantly the possibility of bugs. – Florian F Feb 23 '20 at 09:45
8

If you are using Java 1.6 or greater, you can use Arrays.copyOfRange to copy a portion of the array. From the javadoc:

Copies the specified range of the specified array into a new array. The initial index of the range (from) must lie between zero and original.length, inclusive. The value at original[from] is placed into the initial element of the copy (unless from == original.length or from == to). Values from subsequent elements in the original array are placed into subsequent elements in the copy. The final index of the range (to), which must be greater than or equal to from, may be greater than original.length, in which case false is placed in all elements of the copy whose index is greater than or equal to original.length - from. The length of the returned array will be to - from.

Here is a simple example:

/**
 * @Program that Copies the specified range of the specified array into a new 
 * array.
 * CopyofRange8Array.java 
 * Author:-RoseIndia Team
 * Date:-15-May-2008
 */
import java.util.*;
public class CopyofRange8Array {
    public static void main(String[] args) {
       //creating a short array
       Object T[]={"Rose","India","Net","Limited","Rohini"};
        // //Copies the specified  short array upto specified range,
        Object T1[] = Arrays.copyOfRange(T, 1,5);
        for (int i = 0; i < T1.length; i++) 
            //Displaying the Copied short array upto specified range
            System.out.println(T1[i]);
    }

}
Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
4

Check out copyOfRange; and example:

int[] arr2 = Arrays.copyOfRange(arr,0,3);
Gabor
  • 7,352
  • 4
  • 35
  • 56
dcp
  • 54,410
  • 22
  • 144
  • 164
1
public static int[] range(int[] array, int start, int end){
        int returner[] = new int[end-start];
        for(int x = 0; x <= end-start-1; x++){
            returner[x] = array[x+start];
        }
        return returner;
    }

this is a way to do the same thing as Array.copyOfRange but without importing anything

Persons123
  • 11
  • 3
-3

You can use subList(int fromIndex, int toIndex) method on your integers arr, something like this:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(2);
        arr.add(3);
        arr.add(4);
        List<Integer> partialArr = arr.subList(1, 3);

        // print the subArr
        for (Integer i: partialArr)
            System.out.println(i + " ");
    }
}

Output will be: 2 3.

Note that subList(int fromIndex, int toIndex) method performs minus 1 on the 2nd variable it receives (var2 - 1), i don't know exactly why, but that's what happens, maybe to reduce the chance of exceeding the size of the array.

A. Ab
  • 35
  • 1
  • 5