繁体   English   中英

Java的Collections.sort如何覆盖要排序的List

[英]How does Java's Collections.sort overwrite the List to be sorted

我正在为学校编写一段代码,我们正在实现排序算法,但算法运行正常,我只是想一想为什么一行代码不能像我期望的那样工作。

调用代码如下所示:

List<Integer> l = new LinkedList<Integer>();
l.add(new Integer(10));
l.add(new Integer(28));
l.add(new Integer(4));
l.add(new Integer(35));
l.add(new Integer(9));

ArraySort.sort(l);
System.out.println(l);

Collections.sort(l);
System.out.println(l);

我稍后会把代码放到我们的类中,但问题是:为什么Collections.sort会用新的排序列表覆盖列表,而我们的却没有?

sort方法工作正常,但只是不更新​​调用类中列表l的值。 我只是很好奇Collections如何做到这一点,解决方案是简单地从ArraySort.sort返回一个List并执行l = ArraySort.sort但这看起来不太好!

这是实际排序的代码:

public static void sort(List l) {
    mergeSort(l);
}

private static List mergeSort(List l) {
    if (l.size() <= 1) {
        return l;
    }
    List left = new LinkedList();
    List right = new LinkedList();
    int middle = l.size() / 2;
    for (int i = 0; i < middle; i++) {
        left.add(l.get(i));
    }
    for (int i = middle; i < l.size(); i++) {
        right.add(l.get(i));
    }

    left = mergeSort(left);
    right = mergeSort(right);

    l = merge(left, right);
    return l;
}

private static List merge(List left, List right) {
    List result = new LinkedList();
    while (left.size() > 0 || right.size() > 0) {
        if (left.size() > 0 && right.size() > 0) {
            if ((int) left.get(0) <= (int) right.get(0)) {
                result.add(left.get(0));
                left.remove(0);
            } else {
                result.add(right.get(0));
                right.remove(0);
            }
        } else if (left.size() > 0) {
            result.add(left.get(0));
            left.remove(0);
        } else if (right.size() > 0) {
            result.add(right.get(0));
            right.remove(0);
        }
    }
    return result;
}

希望有人可以为我清除这一点。

它不会,它只会更改列表内容。

来源

 public static <T extends Comparable<? super T>> void sort(List<T> list) {
     Object[] a = list.toArray();
     Arrays.sort(a);
     ListIterator<T> i = list.listIterator();
     for (int j=0; j<a.length; j++) {
         i.next();
         i.set((T)a[j]);
     }
 }

您不需要返回List对象,但这不会导致错误。

请注意,您要为list参数指定一个新列表

l = merge(left, right);

Java按值传递,而不是通过引用传递,因此从方法返回时它没有任何影响。 您必须实际修改传递给方法的列表对象,而不是为其分配新值。


您是否考虑过在Java中查看实现以进行比较?

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Collections.java#Collections.sort%28java.util.List%29

想法是改变这个:

l = merge(left, right);
return l;

进入此(不确定订单是否保留 - 我想它是):

l.clear();
l.addAll(merge(left, right)); //no need to return the list, it is the same

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM