在下面的代码中,我想了解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
}
}
);
答案 0 :(得分:3)
这称为anonymous inner class 它用于将函数作为参数传递,因为Java不支持函数指针。
答案 1 :(得分:2)
Collections.sort
方法对作为参数给出的集合进行排序。默认情况下,使用集合的自然顺序。自然顺序由集合中的对象定义。
例如,当您拥有String
s的集合时,sort方法按字符串的字母顺序对此集合进行排序。 sort
方法如何知道它必须按字母顺序排序?它使用了String
类中的compareTo方法。 compareTo
将当前对象(this
)与其他对象进行比较,并决定哪两个对象首先出现。使用compareTo
对列表中的所有项目sort
确定正确的顺序。
所以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(););
如果仅在这种情况下使用MyStringComparator
,则不希望创建单独的类,为其命名,文件等。你所需要的只是一种暂时的东西,你可以在排序后忘记。
因此,您可以说:
而不是编写所有代码Collections.sort(myStringList, new Comparator()
{
public int compareTo(String a, String b)
{
return a.compareTo(b) * -1;
}
}
);
请参阅,第二个参数是类定义本身。
这称为anonymous inner class。对于这种情况,一种使用和抛出类。您将在Swing事件处理程序中看到许多匿名内部类。
答案 2 :(得分:1)
你正在做的是定义你自己的班级,而没有给它起名字;也就是说,它是一个匿名类。这个类extends
Comparator
,这意味着它就像Comparator
,但是有一些改变或额外的东西(当你扩展一个类时,它不是强制要求改变或额外的东西,但是如果你不想改变某些东西,那么扩展课程没有多大意义。
在这种情况下,您的匿名类有自己的方法compare
,该方法描述了如何比较两个对象并找出哪个对象应按某种顺序首先出现。
您接下来要做的是从您的班级制作一个对象 - new
关键字就是这样做的。
最后,您创建的对象将传递给Collections.sort
。不出所料,这会对您的列表进行排序,但是会按照您的匿名类隐含的顺序进行排序;也就是说,只要需要决定列表中首先出现哪两个对象,它就会在匿名类中调用compare
方法。
答案 3 :(得分:1)
这基本上是对其他人的说法进行了重新编写,但我认为可以用更简单的术语来解释。
首先:
Collections.sort
需要Comparator
,它定义了如何将对象相互比较。一种Comparator
可能会根据其值在数字上对Integer
进行比较。另一种类型Comparator
可能会根据字符的字母顺序比较String
。
您的Comparator
根据Tuple
对Message
和receiveTime
进行了比较。
其次:
Comparator
是一个名为compare(Object, Object)
的方法。 Java允许您以 匿名类 的形式动态定义接口的具体类。
实现接口的匿名类只是“动态”定义该接口的方法(即在其他一些代码的中间;而不是在它自己的.class
文件中)。您的示例只是动态定义compare(Object, Object)
方法。