仅获取Java中数组的一部分?


275

我在Java中有一个整数数组,我只想使用其中的一部分。我知道在Python中您可以执行类似array [index:]的操作,它会从索引返回数组。在Java中可能会发生这种情况。

Answers:


444

Java中数组的长度是不可变的。因此,您需要将所需的部分复制为新数组。
使用java.util.Arrays类中的copyOfRange方法:

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

startIndex是要复制的范围的初始索引,包括端点。
endIndex是要复制的范围的最终索引(不包括)。(此索引可能位于数组之外)

例如:

   //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)

似乎有尺寸限制?只有这样才行:Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)因为我不想使用Integer.MAX_VALUE而不是255,以防万一我不想获得真实长度
Aquarius Power

@AquariusPower的大小限制是数组的大小,它可以大于255。您不能提供endIndex大于作为第一个参数传递的数组的大小。因此,如果要完整副本,请创建一个引用此数组的变量,然后使用Arrays.copyOfRange(var, 0, var.length)Arrays.copyOf(var, var.length)
elias

我必须为stacktrace子数组创建一个本地var,但是我发现这可行!!!Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
水瓶座力量

小心点ArrayIndexOutOfBoundsException
elias

1
还有另一个问题。如果我需要将长度为500K的字符串数组拆分为250K的子数组,该怎么办。这些方法接受interegr其最大出在65000
毗Dahatonde

31

您可以将数组包装为列表,然后请求它的子列表。

MyClass[] array = ...;
List<MyClass> subArray = Arrays.asList(array).subList(index, array.length);

22

是的,您可以使用Arrays.copyOfRange

它做同样的事情(请注意有一个副本:您无需更改初始数组)。


2
就是说,如果您不想进行显式复制,则需要使用@ K-ballo的答案中概述的ListsubList
Louis Wasserman 2012年

那就对了。Java没有现代语言提供的数组切片功能。
DenysSéguret2012年

我不确定是否可以那样说,但是...是的,Java不提供数组切片。(也就是说,这种方法有一些优点:减少内存泄漏的可能性,通过避免额外的字段来减少阵列开销,等等。您可以选择其中一种。)
Louis Wasserman 2012年

是的,您又是对的(而且我没有尝试发动火焰战争;))。切片会使GC非常复杂。当Java尝试用Strings 进行基于对象的隐式切片时,它更加证明这是危险的
DenysSéguret2012年

11

你可以试试:

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); 

有关系统信息,请参见javadoc


3
我只是喜欢这实际上是如何实际实现Arrays.copyOf()和Arrays.copyOfRange()的方式(无边界检查),但是它没有获得任何投票,而尽管System.arraycopy约会,但开销稍高的实用程序方法包装器还是投票了回到1995
。– Dave

1
我想对于某些人来说它看起来还不够“现代”。
戴夫

我喜欢上学,没有光彩的钟声,只是所需的机器。像C中的memcpy一样
StvnBrkdll

但是使用arrays.copyOfRange()可以提高可读性,并显着减少错误的可能性。
Florian F

7

如果您使用的是Java 1.6或更高版本,则可以Arrays.copyOfRange用来复制数组的一部分。从javadoc:

将指定数组的指定范围复制到新数组中。范围(从)的初始索引必须介于零和之间original.length(含)。处的值original[from]放置在副本的初始元素中(除非from == original.lengthfrom == to)。来自原始数组中后续元素的值将放入副本中的后续元素中。范围(to)的最终索引(必须大于或等于from)可以大于original.length,在这种情况下,该最终索引false将放置在副本中所有索引大于或等于的元素中original.length - from。返回数组的长度为to - from

这是一个简单的例子

/**
 * @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]);
    }

}



-2

您可以subList(int fromIndex, int toIndex)对整数arr 使用method,如下所示:

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 + " ");
    }
}

输出将是:2 3

请注意,该subList(int fromIndex, int toIndex)方法在它收到的第二个变量(var2-1)上执行负1,我不知道确切的原因,但是那是发生了什么,也许是为了减少超过数组大小的机会。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.