【问题标题】:java function definition with object creation带有对象创建的java函数定义
【发布时间】:2012-05-20 03:03:34
【问题描述】:

在下面的代码中,我想了解 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
                            }
                           }    
                    );

【问题讨论】:

  • 这是否意味着排序取决于函数返回的内容?那么如果函数返回 -1、0 或 1,上述行中的排序行为是什么。

标签: java function comparator


【解决方案1】:

这叫做anonymous inner class
它用于将函数作为参数传递,因为 Java 不支持函数指针。

【讨论】:

  • 谢谢。那么这个函数在上面的代码中是做什么的呢?
  • 基本上是回调。它比较两个对象。
  • 所以当花括号中的函数将返回一个值时,该值将被传递
  • @OsmanKhalid:无论调用什么函数。就像任何其他功能一样。在这种情况下,sort() 中的内容。
【解决方案2】:

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

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

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

您可以通过another (overloaded) variant of the sort method 进行操作。这个变体接受第二个参数,它是 Comparator 接口的一个实例。

因此,您必须编写自己的类来实现Comparator,这样它就有自己的compareTo 方法。然后排序方法使用这个compareTo,而不是集合中对象中的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(););

Object Ordering

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

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

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

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

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

【讨论】:

    【解决方案3】:

    你正在做的是定义你自己的类,而不给它一个名字;也就是说,它是一个匿名类。这个类extendsComparator,这意味着它就像Comparator,但有一些改变或额外的东西(当你扩展一个类时,不一定有改变或额外的东西,但扩展没有多大意义如果您不打算更改某些内容,请上一堂课)。

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

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

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

    【讨论】:

      【解决方案4】:

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

      首先:

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

      您的Comparator 根据receiveTime 比较TupleMessage

      其次:

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

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

      【讨论】:

        猜你喜欢
        • 2013-09-19
        • 1970-01-01
        • 2018-03-08
        • 1970-01-01
        • 2017-08-21
        • 1970-01-01
        • 1970-01-01
        • 2011-04-23
        • 1970-01-01
        相关资源
        最近更新 更多