我正在运行一个示例来了解 Java 中比较器的行为。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class HDTV {
private int size;
private String brand;
public HDTV(int size, String brand) {
this.size = size;
this.brand = brand;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
class SizeComparator implements Comparator<HDTV> {
@Override
public int compare(HDTV tv1, HDTV tv2) {
int tv1Size = tv1.getSize();
int tv2Size = tv2.getSize();
System.out.println("Comparing :: "+tv1.getBrand()+" AND : "+tv2.getBrand());
if (tv1Size > tv2Size) {
return 1;
} else if (tv1Size < tv2Size) {
return -1;
} else {
return 0;
}
}
}
public class HelloWorld {
public static void main(String[] args) {
HDTV tv1 = new HDTV(55, "Samsung");
HDTV tv2 = new HDTV(60, "Sony");
HDTV tv3 = new HDTV(42, "Panasonic");
ArrayList<HDTV> al = new ArrayList<HDTV>();
al.add(tv1);
al.add(tv2);
al.add(tv3);
Collections.sort(al, new SizeComparator());
for (HDTV a : al) {
System.out.println(a.getBrand());
}
}
}
输出是
比较::索尼和:三星
比较::松下和:索尼
比较::松下和:索尼
比较::松下和:三星
松下
三星
Sony
为什么要比较两个对象Panasonic
and Sony
连续2次??
我认为不需要这样做。
如果这是 Java 7 或更高版本,则它使用 TimSort。 TimSort 首先运行输入并检测或收集 32 个或更多元素的升序运行(在此实现中)。看countRunAndMakeAscending在源代码中。
运行时间超过 32 的时间暂时保留。通过将后续元素执行二进制插入排序到当前运行中,可以延长小于 32 的运行,直到其长度至少为 32 个元素。看binarySort在源代码中。
(合并排序方法仅在收集 >= 32 次运行后才会完成。由于您的输入只有 3 个元素,因此整个排序是使用二进制插入排序完成的,并且不进行合并。)
What countRunAndMakeAscending
所要做的就是通过比较相邻元素来检测游程。首先将索尼与三星进行比较,然后将松下与索尼进行比较。结果是长度为 2 的游程,[三星,索尼]。
Next, binarySort
通过采用下一个元件(松下)并将其插入正确的位置来延长此运行时间。进行二分搜索来找到那个地方。 2 组的中点是位置 1,即索尼,因此将松下与索尼进行比较。 (这是重复比较。) 松下比索尼少,所以接下来比较松下和三星,确定合适的插入点。现在我们的游程长度为 3。
由于整个输入的长度为3,因此经过四次比较后排序完成。
发生重复比较的原因是countRunAndMakeAscending
and binarySort
是单独的排序阶段,恰好第一阶段的最后一次比较与第二阶段的第一次比较相同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)