给定一个大小为k的数组,前n个元素分配了一个非空引用,我将如何返回一个只包含Java中前n个n大小元素的数组?
显然你可以通过创建一个新的k大小的数组然后迭代初始n次,在每次迭代时传输元素然后那将是O(n)操作来做深度复制。
根据我对数组如何存储在内存中的理解,我认为可能只是简单地将数组的长度属性从k更改为n,然后返回初始数组的引用。
作为伪方法:
public Foo[] head(Foo[] arr, int n) {
arr.length = n;
return arr;
}
我想知道是否可以采取任何措施将其作为一个恒定时间操作来生成,但我担心这可能是不可能的,因为Java不支持像指针算术这样的任何东西。
如果这是不可能的,那么提供相同结果的最快方法是什么?
答案 0 :(得分:3)
如果您必须使用原始数组而不是ArrayList
,那么Arrays
就可以满足您的需求。如果查看源代码,这些是获取数组副本的绝对最佳方法。它们确实有很多防御性编程,因为System.arraycopy()
方法会在输入不合逻辑的参数时抛出大量未经检查的异常。
您可以使用Arrays.copyOf()
,它将从第一个Nth
元素复制到新的较短数组。
public static <T> T[] copyOf(T[] original, int newLength)
使用空值复制指定的数组,截断或填充(如果 必要的)所以副本有指定的长度。对于所有指数 在原始数组和副本中都有效,两个数组都会有效 包含相同的值。对于副本中有效的任何索引 但不是原始版本,副本将包含null。这些指数会 当且仅当指定的长度大于。的长度时才存在 原始数组。结果数组与类完全相同 原始阵列。
2770
2771 public static <T,U> T[] More ...copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
2772 T[] copy = ((Object)newType == (Object)Object[].class)
2773 ? (T[]) new Object[newLength]
2774 : (T[]) Array.newInstance(newType.getComponentType(), newLength);
2775 System.arraycopy(original, 0, copy, 0,
2776 Math.min(original.length, newLength));
2777 return copy;
2778 }
或Arrays.copyOfRange()
也可以解决问题:
public static <T> T[] copyOfRange(T[] original, int from, int to)
将指定数组的指定范围复制到新数组中。 范围(from)的初始索引必须介于0和0之间 original.length,包括。原始[from]的值被放入 副本的初始元素(除非来自== original.length或 从==到)。原始数组中后续元素的值为 放入副本中的后续元素。最终的指数 范围(to),必须大于或等于,可以是 大于original.length,在这种情况下null放在所有 索引大于或等于的副本的元素 original.length - 来自。返回数组的长度为 - 从。生成的数组与原始数组完全相同 阵列。
3035 public static <T,U> T[] More ...copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {
3036 int newLength = to - from;
3037 if (newLength < 0)
3038 throw new IllegalArgumentException(from + " > " + to);
3039 T[] copy = ((Object)newType == (Object)Object[].class)
3040 ? (T[]) new Object[newLength]
3041 : (T[]) Array.newInstance(newType.getComponentType(), newLength);
3042 System.arraycopy(original, from, copy, 0,
3043 Math.min(original.length - from, newLength));
3044 return copy;
3045 }
正如您所看到的,这两个都只是System.arraycopy
上的包装函数,具有防御逻辑,您尝试执行的操作是有效的。
System.arraycopy
是复制数组的绝对最快的方式。
答案 1 :(得分:2)
您正在寻找sublist。 (列表而不是数组)
但是,重点始终如一。保存n和数组的值。你已经完成了。你可以使用那些相同的东西,你使用假装不同大小的不同假阵列,只是假装数组大小为n,并使用数组。
虽然你必须,
List<MyClass> subArray = Arrays.asList(array).subList(index, index2);