2

在下面的代码中,我想了解 Collections.sort 函数在做什么。这是什么意思

Collections.sort(list, new Comparator() { a complete java function });

我理解这new Comparator()意味着一个类对象,但是这里的功能块的目的是什么,以及我们在java中称之为什么。

谢谢。

/**
     * Sorts/shuffles the given list according to the current sending queue 
     * mode. The list can contain either Message or Tuple<Message, Connection> 
     * objects. Other objects cause error. 
     * @param list The list to sort or shuffle
     * @return The sorted/shuffled list
     */
    @SuppressWarnings(value = "unchecked") /* ugly way to make this generic */
    protected List sortByQueueMode(List list) {
        switch (sendQueueMode) {

    case Q_MODE_RANDOM:
        Collections.shuffle(list, new Random(SimClock.getIntTime()));
        break;
    case Q_MODE_FIFO:
        Collections.sort(list, 
                new Comparator() {
            /** Compares two tuples by their messages' receiving time */
            public int compare(Object o1, Object o2) {
                double diff;
                Message m1, m2;

                if (o1 instanceof Tuple) {
                    m1 = ((Tuple<Message, Connection>)o1).getKey();
                    m2 = ((Tuple<Message, Connection>)o2).getKey();
                }
                else if (o1 instanceof Message) {
                    m1 = (Message)o1;
                    m2 = (Message)o2;
                }
                else {
                    throw new SimError("Invalid type of objects in " + 
                            "the list");
                }

                diff = m1.getReceiveTime() - m2.getReceiveTime();
                if (diff == 0) {
                    return 0;
                }
                return (diff < 0 ? -1 : 1);
            }
        });
        break;
    /* add more queue modes here */
    default:
        throw new SimError("Unknown queue mode " + sendQueueMode);
    }

    return list;
}

我终于让他理解了比较器。这个简单的例子会有所帮助:

 Collections.sort(ls, new Comparator() 
                           {

                            public int compare(Object o1, Object o2) 
                            {
                            String sa = (String)o1;
                            String sb = (String)o2;

                            int v = sa.compareTo(sb);

                            return v;           

                                // it can also return 0, and 1
                            }
                           }    
                    );
4

4 回答 4

3

这称为匿名内部类
它用于将函数作为参数传递,因为 Java 不支持函数指针。

于 2012-05-20T03:04:45.000 回答
2

Collections.sort方法对作为参数给出的集合进行排序。默认情况下,使用集合的自然顺序。自然顺序由集合中的对象定义。例如,当您有一个Strings 集合时,sort 方法会按字符串的字母顺序对该集合进行排序。该方法如何sort知道它必须按字母顺序排序?它在类中使用了 compareTo 方法StringcompareTo将当前对象 ( this) 与另一个对象进行比较,并决定这两者之间哪个先出现。使用compareTo列表中的所有项目,sort确定正确的顺序。

所以 compareTo 决定了一个对象的自然顺序

如果您想要自然顺序以外的其他顺序怎么办?假设您想按字母倒序对字符串列表进行排序?

您可以通过sort 方法的另一个(重载)变体来做到这一点。此变体接受第二个参数,它是 Comparator 接口的一个实例。

因此,您必须编写自己的实现Comparator的类,这样它就有自己的compareTo方法。然后 sort 方法使用 thiscompareTo而不是compareTo集合中的对象中的 (String)。

所以你说

class MyStringComparator<String> implements Comparator
{
    public int compareTo(String a, String b)
    {
        return a.compareTo(b) * -1; //Reverse the order. 
                                    //The logic can be as complex as your need is
    }
}

接着

MyStringComparator myStringComparator = new MyStringComparator();
Collections.sort(myStringList, myStringComparator);

或者

Collections.sort(myStringList, new MyStringComparator(););

请参阅对象排序

如果MyStringComparator仅将 用于这种情况,您将不想创建一个单独的类,给它一个名称、一个文件等。你所需要的只是一个临时的东西,你可以在排序后忘记。

所以不用写所有的代码,你可以说:

Collections.sort(myStringList, new Comparator()
                               {
                                   public int compareTo(String a, String b)
                                   {
                                       return a.compareTo(b) * -1; 
                                   }
                               }
               );

看,第二个参数是类定义本身。

这称为匿名内部类。一种使用和抛出类,用于这种情况。您将在 Swing 事件处理程序中看到很多匿名内部类。

于 2012-05-20T05:58:31.360 回答
1

这基本上是重新散列其他人所说的话,但我认为可以用更简单的术语来解释。

首先:

Collections.sort接受 a Comparator,它定义了对象应该如何相互比较。一种类型Comparator可能会Integer根据它们的值进行数值比较。另一种类型Comparator可能会String根据其字符按字母顺序进行比较。

您的Comparator比较TupleMessage基于他们的receiveTime.

第二:

Comparator是一个接口,它有一个名为 的方法compare(Object, Object)。Java 允许您以匿名类的形式动态定义接口的具体类

实现接口的匿名类只是“动态地”定义该接口的方法(即在一些其他代码的中间;不在它自己的.class文件中)。您的示例只是动态定义了该compare(Object, Object)方法。

于 2012-05-20T05:32:50.517 回答
1

你正在做的是定义你自己的类,而不给它一个名字;也就是说,它是一个匿名类。这个类extends Comparator,这意味着它就像Comparator,但是有一些改变或额外的东西(当你扩展一个类时,有一些改变或额外的东西不是强制性的,但是如果你不打算扩展一个类并没有多大意义改变些什么)。

在这种情况下,您的匿名类有自己的方法称为compare,它描述了如何比较两个对象并找出哪个对象应该以某种顺序首先出现。

接下来你要做的是从你的类中创建一个对象——new关键字就是这样做的。

最后,您创建的对象被传递给Collections.sort. 不出所料,这会对您的列表进行排序,但这样做是根据您的匿名类所暗示的顺序进行的;也就是说compare,只要它需要决定两个对象中的哪一个应该首先出现在列表中,它就会调用匿名类中的方法。

于 2012-05-20T05:01:36.913 回答