gpt4 book ai didi

java - 通用数组复制的问题

转载 作者:行者123 更新时间:2023-12-02 00:44:31 26 4
gpt4 key购买 nike

目标

<小时/>

我正在创建一个 Java 类,它将增强数组的可用性,例如 addremovecontains 方法。我认为最好的解决方案是创建一个具有类型参数 T 的类(称为 ArrayPP)。这样,用户就可以像与相同类型的数组进行交互一样轻松地与 ArrayPP 对象进行交互。

问题

<小时/>

我很快发现诸如 add 这样的方法需要创建一个单独的数组,并最终将目标数组 tT 数组更改为 转换为 Object 数组。正如您可能猜到的,这完全破坏了可用性,当我尝试做类似的事情

File[] f = new File[0];
ArrayPP<File> appF = new ArrayPP(f);
appF.add(saveFile);
f = appF.toArray();

程序抛出

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.io.File;

因为 add 方法必须将数组更改为 Object 数组,因为 Java 编译器不允许您创建通用数组( T[] t = new T[0]; 不好,但 T[] t = (T[]) new Object[0]; 没问题)。我从逐行调试中知道,上面的代码将数组 t 保留在本例中,作为 File 的 n 数组,直到 的第 4 行>add 方法被调用。 有没有人有一个解决方案可以使数组t保持为T数组而不是Object数组?

示例代码

<小时/>

下面是我的类(class)的一个非常淡化的版本。

public class ArrayPP<T>
{
T[] t;

/**
* Creates a new Array++ to manage the given array.
* <h3>Analogy:</h3>
* <tt>ArrayPP&lt;String&gt; s = new ArrayPP(args);</tt><br/>
* is analogous to<br/>
* <tt>String s[] = args;</tt>
* @param array The array to be managed
*/
public ArrayPP(T[] array)
{
t = array;
}

/**
* Appends a value to the end of the array
* @param val the value to be appended
* @return the resulting array.
*/
public ArrayPP add(T val)
{
T[] temp = (T[]) new Object[t.length + 1];
System.arraycopy(t, 0, temp, 0, t.length);
temp[temp.length - 1] = val;
t = (T[])temp;
return this;
}

/**
* Returns the array at the core of this wrapper
* @return the array at the core of this wrapper
*/
public T[] toArray()
{
return t;
}
}

可能的解决方案?

<小时/>

在查看了有关泛型数组的其他问题后,我想我有一个解决方案:

而不是

  /**
* Appends a value to the end of the array
* @param val the value to be appended
* @return the resulting array.
*/
public ArrayPP add(T val)
{
T[] temp = (T[]) new Object[t.length + 1];
System.arraycopy(t, 0, temp, 0, t.length);
temp[temp.length - 1] = val;
t = (T[])temp;
return this;
}

这行得通吗?

  /**
* Appends a value to the end of the array
* @param val the value to be appended
* @return the resulting array.
*/
public ArrayPP<T> add(T val)
{
t = java.util.Arrays.copyOf(t, t.length + 1);
t[t.length - 1] = val;
return this;
}

最佳答案

原则上,您无法轻松创建泛型类型(或类型变量)的数组。

如果您有一个类对象,则可以使用反射,或者如果您有一个示例数组,则可以使用 java.util.Arrays 类中的方法来创建(更长/更短)副本。但无论如何,它都不优雅。

ArrayList 类在内部简单地使用 Object[] 来存储其元素,并且仅在 get/set/add/toArray 上进行转换。你的类在哪些方面比 ArrayList 做得更好?

<小时/>

编辑:

我建议要么简单地委托(delegate)给 ArraysList,要么像 ArrayList 那样进行实现,在内部使用 Object[],并在必要时在输出上进行转换。

如果你真的想在内部拥有一个正确类型的数组,这是可能的 - 但正如我所说,它会变得很难看。

add 方法仍然是最简单的情况:

  /**
* Appends a value to the end of the array
* @param val the value to be appended
* @return the resulting array.
*/
public ArrayPP add(T val)
{
T[] temp = Arrays.copyOf(t, t.length+1);
temp[t.length] = val;
t = temp;
return this;
}

当您想在中间添加或删除时,您必须将其与 arraycopy 结合起来。

关于java - 通用数组复制的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5372168/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com