ArrayList排序函数

时间:2017-06-22 18:01:40

标签: java sorting arraylist

我目前正在尝试制作一个程序来排序整数数组列表而不使用任何API。我搜索了类似的问题,发现问题主要是循环,但我无法在代码中找到问题。

这是我的代码:

import java.util.ArrayList;
import java.util.Collections;

class Distro {
    public static ArrayList<Integer> max_out(ArrayList<Integer>list) {
        ArrayList<Integer>it = new ArrayList<Integer>();            
        final int initial_size = list.size();
        for(int i = 0;i<initial_size;i++) {
            int maxo = Collections.max(list);
            it.add(maxo);
            list.remove(maxo);
        }
        return(it);
    }
}

我收到此错误:

  

线程“main”中的异常java.lang.IndexOutOfBoundsException:索引:43,大小:3
  在java.util.ArrayList.rangeCheck(ArrayList.java:653)
  在java.util.ArrayList.remove(ArrayList.java:492)
  在Grown.main的Distro.max_out(Grown.java:10)(Grown.java:22)*

4 个答案:

答案 0 :(得分:1)

数组的最大索引将比大小小一个,因此您需要减一来查找最后一个元素。 这与您的IndexOutOfBoundsException错误一致。

修复应为list.remove(maxo - 1)

答案 1 :(得分:1)

如果你真的不想使用任何API(因为你正在使用Collections.max()),你可能会这样做:

import java.util.ArrayList;
import java.util.List;

public class Sorting{
    public static void main(String[] args){
      // create an array example
      List<Integer> list = new ArrayList<>();
      // populate it in ascending order
      for(int i=0 ; i<10; i++){
          list.add(i);
      }
      // check its content BEFORE sorting
      System.out.println(list);
      // sort it
      max_out(list);
      // check its content AFTER sorting
      System.out.println(list);
    }

    public static void max_out(List<Integer> list) {
        for(int i = 0 ; i < list.size(); i++){
           for(int j = 0 ; j < list.size() - i - 1; j++){
               if (list.get(j) < list.get(j+1)){ // move to left if it's bigger 
                   int swap  = list.get(j);
                   list.set(j, list.get(j+1));
                   list.set(j+1, swap);
                }
            }
        }
    }

}

<强>测试

Before [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
After  [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

此外,关于您的方法,它适用于我,但我认为问题出在remove()方法中,它有两个版本(重载方法):

  • E remove(int index):删除此列表中指定位置的元素。
  • boolean remove(Object o):从此列表中删除指定元素的第一个匹配项。

由于int maxo中的for-loop是原始类型,因此编译器会认为您要求第一个方法。

您可以做的是将int maxo更改为对象类型Integer,或使用int indexOf(Object o)方法返回第一次出现的索引在此列表中指定元素,如下所示:

list.remove(list.indexOf(maxo));

答案 2 :(得分:1)

我测试了它并且问题不在于您的逻辑,即使您正在迭代list.size()次,您实际上并没有遍历列表本身。

您的代码的问题是您将maxo定义为int而不是Integer。由于调用了list.remove(int x)方法,其中x是元素的索引。如果你将maxo定义为Integer,则会调用list.remove(Object o),删除你原本想要做的maxo值。

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(-1);
list.add(4);
ArrayList<Integer> it = new ArrayList<Integer>();
final int initial_size = list.size();
for(int i = 0;i<initial_size;i++) {
    Integer maxo = Collections.max(list);
    it.add(maxo);
    list.remove(maxo);
}
System.out.println(it);

输出:

[4, 2, -1]

答案 3 :(得分:-1)

当然这会导致错误。

原因1:您正在从主列表中删除元素,同时将其迭代到最终变量中存储的最大大小。在迭代中的某个时刻,它将导致错误。

原因2:您正在从maxo变量定义的索引处删除主列表中的元素,该变量包含最大元素,而不是索引值。

分辨率跟踪列表的大小,并仅删除索引值。

public static ArrayList<Integer> max_out(ArrayList<Integer>list) {
    ArrayList<Integer> it = new ArrayList<Integer>();
    for (int i= 0; i < list.size(); i++) {
        int maxo = Collections.max(list);
        it.add(maxo);
        list.remove(list.indexOf(maxo);
    }
    return it;
}