Java 在两个数组列表之间交替。

Java 在两个数组列表之间交替。,java,arraylist,Java,Arraylist,我很难让它运行。我不确定到目前为止我所拥有的是否在正确的轨道上。我不太确定是哪里给了我一个越界错误 以下是说明: 编写一个名为interleave的方法,该方法接受两个整数a1和a2的数组列表作为参数,并在交替索引处将a2的元素插入a1。如果列表长度不等,则较长列表的其余元素将保留在a1的末尾。例如,如果a1存储[10,20,30],a2存储[4,5,6,7,8],则交织调用(a1,a2);应将a1更改为存储[10,4,20,5,30,6,7,8]。如果a1存储了[10,20,30,40,50]

我很难让它运行。我不确定到目前为止我所拥有的是否在正确的轨道上。我不太确定是哪里给了我一个越界错误

以下是说明:

编写一个名为interleave的方法,该方法接受两个整数a1和a2的数组列表作为参数,并在交替索引处将a2的元素插入a1。如果列表长度不等,则较长列表的其余元素将保留在a1的末尾。例如,如果a1存储[10,20,30],a2存储[4,5,6,7,8],则交织调用(a1,a2);应将a1更改为存储[10,4,20,5,30,6,7,8]。如果a1存储了[10,20,30,40,50],a2存储了[6,7,8],则交织调用(a1,a2);将a1更改为存储[10,6,20,7,30,8,40,50]

private static void interleave(ArrayList<Integer> a1,
        ArrayList<Integer> a2) {

    int i = a1.size();
    int j = a2.size();

    if (i < j) { // a1 is shorter than a2
        for (int k = 0; k < a1.size(); k++) { // before k passes a1 size
            a1.add(k+1, a2.get(k));
        }

        for (int l = a1.size(); l < a2.size(); l++) {
            a1.add(a1.size(), a2.get(l));
        }

    } else if (i > j) { // a1 is longer than a2
        for (int k = 1; k < a2.size(); k++) {
            a1.add(k+1, a2.get(k));
        }

    } else { // they are equal length
        for (int k = 1; k < a2.size(); k++) {
            a1.add(k+1, a2.get(k));
        }
    }
}
私有静态无效交织(ArrayList a1,
阵列列表a2){
int i=a1.size();
int j=a2.size();
如果(ij){//a1比a2长,则为else
对于(int k=1;k
这应该行得通

private static void interleave(ArrayList<Integer> a1, ArrayList<Integer> a2) {
    int i = -1;
    for(Integer elem: a2) {
        if(i < a1.size()-1) {
            i += 2;
        } else {
            i += 1;
        }
        a1.add(i, elem);
    }
}

public static void main(String[] args) throws Exception {

    ArrayList<Integer> a1 = new ArrayList<>(Arrays.asList(10, 20, 30));
    ArrayList<Integer> a2 = new ArrayList<>(Arrays.asList(4, 5, 6, 7, 8));

    interleave(a1, a2);
    System.out.println(a1);
}
私有静态无效交织(ArrayList a1,ArrayList a2){
int i=-1;
用于(整数元素:a2){
如果(i
编辑:我必须承认,这段代码实际上是一个非常糟糕的解决方案,因为它对于长列表来说会非常慢。每次将一个元素添加到a1时,列表的很大一部分都必须移动一个位置。 因此,按照“MadProgrammer”的建议,这里有一个更好、更快的方法

private static void interleave(ArrayList<Integer> a1, ArrayList<Integer> a2) {
    ArrayList<Integer> r = new ArrayList<>(a1.size() + a2.size());

    for(int i = 0, j = 0; i < a1.size() || j < a2.size(); i++, j++) {
        if(i < a1.size()) r.add(a1.get(i));
        if(j < a2.size()) r.add(a2.get(j));
    }
    a1.clear();
    a1.addAll(r);
}
私有静态无效交织(ArrayList a1,ArrayList a2){
ArrayList r=新的ArrayList(a1.size()+a2.size());
对于(inti=0,j=0;i
这应该行得通

private static void interleave(ArrayList<Integer> a1, ArrayList<Integer> a2) {
    int i = -1;
    for(Integer elem: a2) {
        if(i < a1.size()-1) {
            i += 2;
        } else {
            i += 1;
        }
        a1.add(i, elem);
    }
}

public static void main(String[] args) throws Exception {

    ArrayList<Integer> a1 = new ArrayList<>(Arrays.asList(10, 20, 30));
    ArrayList<Integer> a2 = new ArrayList<>(Arrays.asList(4, 5, 6, 7, 8));

    interleave(a1, a2);
    System.out.println(a1);
}
私有静态无效交织(ArrayList a1,ArrayList a2){
int i=-1;
用于(整数元素:a2){
如果(i
编辑:我必须承认,这段代码实际上是一个非常糟糕的解决方案,因为它对于长列表来说会非常慢。每次将一个元素添加到a1时,列表的很大一部分都必须移动一个位置。 因此,按照“MadProgrammer”的建议,这里有一个更好、更快的方法

private static void interleave(ArrayList<Integer> a1, ArrayList<Integer> a2) {
    ArrayList<Integer> r = new ArrayList<>(a1.size() + a2.size());

    for(int i = 0, j = 0; i < a1.size() || j < a2.size(); i++, j++) {
        if(i < a1.size()) r.add(a1.get(i));
        if(j < a2.size()) r.add(a2.get(j));
    }
    a1.clear();
    a1.addAll(r);
}
私有静态无效交织(ArrayList a1,ArrayList a2){
ArrayList r=新的ArrayList(a1.size()+a2.size());
对于(inti=0,j=0;i
我看到已经有了任何公认的答案,但我认为在这种情况下,使用带有适当索引变量的
for
循环将比在数组和集合上工作的
for
循环更方便。例如,看看随着时间的推移这种进展会发生什么
a2
总是一样的:
[4 5 6 7 8]
,应该插入
a1
的元素索引是
0,1,2,3,4
。现在,第一个元素(
4
)应该插入到
a1
1
位置。之后,需要在位置
3
插入下一个元素(
5
)。然后需要将
6
插入位置
5
。一般来说,
a2
i
th元素需要插入
a1
中的
i*2+1
位置。这将一直保持,直到
i*2+1
大于
a1
中的元素数,或者
a2
中的元素用完为止。考虑到这一点,在插入所有早期元素之后,将
a2
i
第th个元素插入
a1
的适当索引是
Math.min(i*2+1,l1.size())
,因为在
l1.size()
处添加只会将一个元素添加到列表的末尾

我同意,但既然已经有了一个完整实现的答案,我想将
for
for每个
循环的索引进行对比,我将在这里包括代码。更新的
交织
方法是

public static <T> List<T> interleave( final List<T> l1, final List<T> l2 ) {
    for ( int i = 0; i < l2.size(); i++ ) {
        l1.add( Math.min( i*2+1, l1.size()), l2.get( i ));
    }
    return l1;
}
在进一步考虑这个问题之后,我认为这里有一些关于使用
列表迭代器的话要说。它使一些迭代和插入代码变得更干净,特别是因为使用
ListIterator
插入代码发生在迭代光标之前。它也不需要任何复杂的索引算法。下面是一个使用
列表迭代器的实现:

public static <T> List<T> interleaveWithIterators( final List<T> l1, final List<T> l2 ) {
    // Get an iterator for the l1, and position it after the first element
    // or at the end, if there's no first element.
    final ListIterator<T> it1 = l1.listIterator();
    if ( it1.hasNext() ) { it1.next(); } 

    // Get an iterator for l2.  While there are elements remaining in l2, 
    // keep adding them to l1 by calling it1.add().  While there are elements
    // in l1, this also requires pushing it1 forward by one element on each iteration.
    final ListIterator<T> it2 = l2.listIterator();
    while ( it2.hasNext() ) {
        it1.add( it2.next() );
        if ( it1.hasNext() ) { it1.next(); }
    }
    return l1;
}

我看到已经有了任何公认的答案,但我认为在这种情况下,使用带有适当索引的
for
循环
private static void interleave(ArrayList<Integer> 
a1, ArrayList<Integer> a2) {
int i = -1;
for(Integer elem: a2) {
    if(i < a1.size()-1) {
        i += 2;
    } else {
        i += 1;
    }
    a1.add(i, elem);
}
}

public static void main(String[] args) throws Exception {

ArrayList<Integer> a1 = new ArrayList<>(Arrays.asList(10, 20, 30));
ArrayList<Integer> a2 = new ArrayList<>(Arrays.asList(4, 5, 6, 7, 8));

interleave(a1, a2);
System.out.println(a1);
}
public static LinkedList<Integer> alternate(LinkedList<Integer> list1, LinkedList<Integer> list2){
    List<Integer> newList = new LinkedList<Integer>();
    Iterator<Integer> itr1 = list1.iterator();
    Iterator<Integer> itr2 = list2.iterator();
    while (itr1.hasNext() || itr2.hasNext()){
        if (itr1.hasNext()){
            newList.add(itr1.next());
        }
        if (itr2.hasNext()){
            newList.add(itr2.next());
        }
    }
    return newList;
}