如何根据大小对数字的arylylist进行排序?

时间:2014-10-31 20:32:29

标签: java

编辑:我应该指定我不能使用内置的排序算法。

我有一个有理数的arraylist,我想通过将数字从最高到最低的顺序添加到一个新的arraylist中来排序。目前我的输出只是arraylist的第一个有理数。我做错了什么,怎么才能让它发挥作用?

public static Collection<Rational> sort(List<Rational> list){
    List<Rational> sortedList = new ArrayList<Rational>();

    for (Iterator<Rational> it = list.iterator(); it.hasNext(); ) {
        Rational currentValue = it.next();

        // Look into sortedList the position where currentValue should go into
        Rational pos = null;
        for (int i=0;i<sortedList.size();i++) { 
             // Compare currentValue with sortedList.get(i) 
             // to know if i is the right position for currentValue. 
             // If it is, assign it to pos
            if(currentValue.compareTo(sortedList.get(i)) > 0){
                pos = (sortedList.get(i));
            }
            else if((currentValue.compareTo(sortedList.get(i)) == 0)){
                pos = (sortedList.get(i));
            }
            else if(currentValue.compareTo(sortedList.get(i)) < 0){
                pos = (sortedList.get(i));
            }
         }
         sortedList.add(pos);
     }
     return sortedList;
}

5 个答案:

答案 0 :(得分:1)

使用JDK中提供的工具,您可以这样做:

private static final Comparator<Rational> INVERSE_RATIONAL
    = new Comparator<Rational>()
    {
        @Override
        public int compare(final Rational a, final Rational b)
        {
            return b.compareTo(a);
        }
    }

// ...

public static Collection<Rational> sort(final List<Rational> list)
{
    // Note: supposes Java 7
    final List<Rational> ret = new ArrayList<>(ret);
    Collections.sort(ret, INVERSE_RATIONAL);
    return ret;
}

编辑 @Makoto正确指向Collections.reverse(),这使上述代码更加简单:

// No need for a custom Comparator...
public static Collection<Rational> sort(final List<Rational> list)
{
    // Note: supposes Java 7
    final List<Rational> ret = new ArrayList<>(ret);
    Collections.sort(ret);
    Collections.reverse(ret);
    return ret;
}

答案 1 :(得分:1)

由于您的元素似乎是Comparable,您可以做两件事:

  • 使用Collections.sort按升序(从最低到最高)对其进行排序,
  • 然后使用Collections.reverse来撤消订单。

这两项操作都会修改列表。如果这是不合需要的,请将列表的内容复制到中间列表并进行修改。

Collections.sort(sortedList);
Collections.reverse(sortedList);

您可以将内容复制到中间列表中,并将其改变:

List<Rational> sortedList = new ArrayList<Rational>();
for(Rational rational : list) {
    sortedList.add(rational);
}
Collections.sort(sortedList);
Collections.reverse(sortedList);

答案 2 :(得分:0)

创建自己的Comparator实现。通过这种方式,如果排序需要根据上下文而改变,则可以定义任意数量的比较器。

public static Comparator<Rational> comparator = new Comparator<Rational>() {
    @Override
    public int compare ( Rational o1, Rational o2 ) {
        // Sort logic here
    }
};

public static Collection<Rational> sort( List<Rational> list ) {
    List<Rational> sortedList = new ArrayList<Rational>(list);
    Collections.sort( sortedList, comparator );
    return sortedList;
}

答案 3 :(得分:0)

你应该使用Collections.sort快速,高效,你可以指望它没有错误。您的代码有一些错误,例如:

// Look into sortedList the position where currentValue should go into
Rational pos = null;

在这里你说它的位置是正确的,但你有一个Rational对象,你应该有一个int值。对于插入排序,您需要浏览列表,直到找到放置对象的正确位置。所以在这里我们遍历列表,直到找到对象的好位置,然后我们在该位置添加该对象。


你的内循环应如下所示:

// Look into sortedList the position where currentValue should go into
int pos = 0;
for (int i=0;i<sortedList.size();i++) { 
     // Compare currentValue with sortedList.get(i) 
     // to know if i is the right position for currentValue. 
     // If it is, assign it to pos
    if(currentValue.compareTo(sortedList.get(i)) > 0) {
        // For lowest to highest sort, uncomment this
        //pos = i+1;
    }
    else if((currentValue.compareTo(sortedList.get(i)) == 0)){
        pos = i;
    }
    else if(currentValue.compareTo(sortedList.get(i)) < 0){
        // For highest to lowest.
        pos = i+1;
    }
 }
 sortedList.add(pos, currentValue);

有更好的方法可以编写此代码,但我将其保留为尽可能接近您的代码。

答案 4 :(得分:0)

编辑:在内循环中将i更正为j

以前的答案提供了最好的&#34;如何解决这个问题。但是,如果您想知道如何解决问题的原始问题,可以通过以下方法让原始代码像您希望的那样工作。我还将迭代器更改为索引语法,以便两个列表以相同的方式处理,以获得更易读的代码。其他方法可以使sortedList使用迭代器。如果您更改比较&gt; 0比较&lt; 0,你得到逆序。

public static Collection<Rational> sort(List<Rational> list){
  List<Rational> sortedList = new ArrayList<Rational>();

  for (int i=0;i < rationalList.size();i++) {
     Rational currentValue = rationalList.get(i);

     int pos = sortedList.size(); // default is to the end of the list
     for (int j=0;j<sortedList.size();j++) {
        int comparison = currentValue.compareTo(sortedList.get(j))
        //this is the right position if the currentValue is greater or equal 
        //to the sorted value at this position
        if(comparison > 0 || comparison == 0){
           pos = j;
           break;
        }
     }
     sortedList.add(pos, currentValue);
  }
  return sortedList;
}

您原始代码的问题是:

1)你没有找到正确位置的int索引值,你有理性位置,感觉有点怪异 2)在您的sortedList检查阶段,您调用了pos =(sortedList.get(i));无论比较是什么 3)您将pos本身的值添加到sortedList:sortedList.add(pos);

所以更正是:

1)我们正在寻找当前sortedList中正确位置的int索引值 2)我们只对位置感兴趣,其中新值大于或等于该位置的当前排序值 3)我们将currentValue只放入sortedList中,通过比较找到我们找到的特定索引。默认位置在最后。