如何编写一个通用方法,在数组中插入元素?

3
我有一个输入数组 [3, 5, 12, 8],我想要一个输出数组(输入不能被改变),与输入数组相同,但是在5和12之间插入元素7,插入到输入数组的索引2处。
这是我目前拥有的代码。我注释掉了一些无法编译的代码,并添加了一些在尝试某种方法时出现的问题:
public static <O>ArrayList<O> addToSet(O[] in,O add,int newIndex){
//    O obj = (O) new Object(); //this doesnt work
//    ParameterizedType obj = (ParameterizedType) getClass().getGenericSuperClass(); // this is not even recognized
    ArrayList<O> out = multipleOfSameSet(obj, in.length);
    if (newIndex > in.length){
        out = new ArrayList<>(newIndex+1); // also noticed that initializing an ArrayList 
        //like this throws an IndexOutOfBoundsException when i try to run out.get(),
        // could someone explain why??  
        out.set(newIndex, add);
    }
    int j = 0;
    int i = 0;
    while(j<in.length+1){
        if (j==newIndex){
            out.set(j, add);
        } else if(i<in.length){
            out.set(j, in[i]);
            i++;
        }
        j++;
    }
    return out;
}

数组的组件类型可以是String、Integer甚至是JPanel。


@SLaks不能做什么?在我的方法内初始化对象? - kbluue
那是要做什么的? - Raffaele
@Raffaele 它应该创建一个输入对象的数组,并指定特定索引的内容。 - kbluue
如果您有一个空构造函数,add.getClass().newInstance() 应该可以工作。 - EpicPandaForce
1
out.set(newIndex, add) 无法工作,因为 new ArrayList<>(newIndex + 1) 分配了一个具有 newIndex + 1 元素空间的 ArrayList,但它是空的;你不能随意在中间设置索引。你必须先用 newIndex 元素填充 ArrayList;你不能为大于当前大小的索引 set 元素。 - Louis Wasserman
显示剩余3条评论
2个回答

1
这是代码的通用版本。
@SuppressWarnings("unchecked")
public <T> T[] insertInCopy(T[] src, T obj, int i) throws Exception {
    T[] dst = (T[]) Array.newInstance(src.getClass().getComponentType(), src.length + 1);
    System.arraycopy(src, 0, dst, 0, i);
    dst[i] = obj;
    System.arraycopy(src, i, dst, i + 1, src.length - i);
    return dst;
}

但是您可能希望专门处理基本类型的方法。我的意思是,泛型和数组不太搭配 - 所以您将遇到int类型的问题,并需要使用包装类型:

@Test
public void testInsertInTheMiddle() throws Exception {
    Integer[] in = {3, 5, 12, 8};
    Integer[] out = target.insertInCopy(in, 7, 2);
    assertEquals(out, new Integer[] {3, 5, 7, 12, 8});
}

我理解了。我甚至不知道有关于arraycopy的事情。它将会非常有用。关于使用包装类型(比如Integer而不是int),我猜类型转换应该可以解决这个问题。非常感谢你。 - kbluue
我的意思是,也许你会觉得处理包装器很烦琐。如果这是库代码,请至少考虑为int和double编写类似的方法。另外,如果它解决了你的问题,请点赞并接受这个答案。 - Raffaele

0

你可以这样做。

static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
    for (T o : a) {
        c.add(o);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接