在Java中使用递归从和ArrayList中分离奇偶索引

在Java中使用递归从和ArrayList中分离奇偶索引,java,recursion,arraylist,Java,Recursion,Arraylist,作为赋值的一部分,我试图从java中的ArrayList中分离偶数和奇数索引。它必须是一个递归方法。这是我试过的 public ArrayList<Integer> toOddList(ArrayList<Integer> input) { ArrayList<Integer> copiedList = (ArrayList<Integer>) input.clone(); ArrayList<Integer&

作为赋值的一部分,我试图从java中的ArrayList中分离偶数和奇数索引。它必须是一个递归方法。这是我试过的

public ArrayList<Integer> toOddList(ArrayList<Integer> input) {
        ArrayList<Integer> copiedList = (ArrayList<Integer>) input.clone();
        ArrayList<Integer> oddList = new ArrayList<Integer>();
        ArrayList<Integer> evenList = new ArrayList<Integer>();
        int index = (copiedList.size() - 1);      // Sets index to the max size of ArrayList - 1
        if (index <= 0) {
            return oddList;
        }
        if ((index % 2) == 0) {
            evenList.add(copiedList.get(index));  // Adds indexed number to even Arraylist
            copiedList.remove(index);             // Removes index from copiedList
            copiedList = toOddList(copiedList);   // Calls function again
        } else {
            oddList.add(copiedList.get(index));   // Adds indexed number to odd Arraylist
            copiedList.remove(index);             // Removes index from copied List
            copiedList = toOddList(copiedList);   // Call method again
        } return oddList;
    }
公共ArrayList ToodList(ArrayList输入){
ArrayList copiedList=(ArrayList)input.clone();
ArrayList oddList=新的ArrayList();
ArrayList evenList=新的ArrayList();
int index=(copiedList.size()-1);//将索引设置为ArrayList-1的最大大小

如果(index我们可以在您的实现中进行一些优化,您甚至不需要在每个递归调用上创建最终的输出列表,并且使用java谓词类,我们还可以通用出最终的内部方法

请检查实现

  public ArrayList<Integer> buildOddList(ArrayList<Integer> input) {
    ArrayList<Integer> output = new ArrayList<>();
    return buildList(input,0,output,i -> i % 2 != 0 );
  }

  public ArrayList<Integer> buildEvenList(ArrayList<Integer> input) {
    ArrayList<Integer> output = new ArrayList<>();
    return buildList(input,0,output,i -> i % 2 == 0 );
  }

  private ArrayList<Integer> buildList(ArrayList<Integer> input, Integer index, ArrayList<Integer> output, Predicate<Integer> predicate) {

    if (index == input.size()) {
      return output;
    }
    if (predicate.test(index)) {
      output.add(input.get(index));
    }
    return buildList(input,index+1,output,predicate);
  }
public ArrayList buildOddList(ArrayList输入){
ArrayList输出=新的ArrayList();
返回构建列表(输入,0,输出,i->i%2!=0);
}
公共ArrayList buildEvenList(ArrayList输入){
ArrayList输出=新的ArrayList();
返回构建列表(输入,0,输出,i->i%2==0);
}
私有ArrayList构建列表(ArrayList输入、整数索引、ArrayList输出、谓词){
if(index==input.size()){
返回输出;
}
if(谓词测试(索引)){
output.add(input.get(index));
}
返回构建列表(输入、索引+1、输出、谓词);
}

我借用了Jarvis使用索引而不是克隆输入数组的想法。我认为这里的目的是让基本情况表明我们已经到达了列表的末尾,如果没有,我们将当前元素添加到正确的列表中,然后在列表的其余部分调用我们自己,注意增加索引并切换cur的点租赁清单和甲板上的租赁清单。然后方法变为:

//assumes all lists initialized by caller
public void splitList(ArrayList<Integer> input, int index, ArrayList<Integer> current, ArrayList<Integer> onDeck) {
    if (index >= input.size()) { //base case
        return;
    } else { //add the current element and call us on the rest of the list
        current.add(input.get(index));
        splitList(input, index + 1, onDeck, current); //note toggling output list and advancing index
    }
}
修订: 我注意到不必太担心索引,也可以更自然地将“列表的其余部分”作为子列表。我还将其推广到任何类型的列表。因此:

//assumes all lists initialized by caller
public void splitList(List<Integer> input, List<Integer> current, List<Integer> onDeck) {
    if (input.size() == 0) { //base case
        return;
    } else { //add the current element and call us on the rest of the list
        current.add(input.get(0));
        splitList(input.subList(1, input.size()), onDeck, current); //note toggling output list and call on rest of list, if any
    }
}

@vbezhenar你能解释一下为什么要添加吗?我已经运行了,我认为如果它能同样好地应用于字符串列表,那将是一件好事,比如说..如果你不指定泛型类型,它将使用legacy(Java-1.5之前)语法。在现代代码中,您应该避免使用这种语法,例如,IDE会对此代码发出警告。我添加了
,因为原始问题也使用了
。如果您想编写适用于任何类型的泛型代码,您应该编写类似于
public void splitList的代码(List input、List current、List onDeck){…
。在保持类型安全的同时,用Java编写泛型代码是一种合适的方法。例如,可以通过以下方式调用原始函数:
splitList(stringList、integerList、floatList)
,其中
stringList
是一个类型为
List
的变量,诸如此类。它在运行时会失败,这是一件坏事,因为Java是一种类型化语言,它应该可以防止编译时类型不匹配导致的错误。如果您愿意,我将撤消编辑,因为我认为您刚刚忘记添加类型,想要修复它t、 实际上我是在要求学习。我在java doodle上运行的很好,但这是一个宽容的环境。谢谢你向我解释。请让编辑站起来。
//assumes all lists initialized by caller
public void splitList(List<Integer> input, List<Integer> current, List<Integer> onDeck) {
    if (input.size() == 0) { //base case
        return;
    } else { //add the current element and call us on the rest of the list
        current.add(input.get(0));
        splitList(input.subList(1, input.size()), onDeck, current); //note toggling output list and call on rest of list, if any
    }
}
splitList(splitThis, evens, odds);//start with evens because 0 is even