如何转换比较器进行比较?
How to convert Comparator to compare?
这是我要获取的代码。
public static final Comparator<Youku> AscDurRevCreationDate =
Comparator.comparing(Youku::getDuration)
.reversed()
.thenComparing(Youku::getDateCreation)
.reversed();
下面的代码是我要将其转换成的代码。但是,我从下面的代码中得到了一些不同的结果。顺便说一句,我在这里使用 Duration 对象。
@Override
public int compare(Youku obj1, Youku obj2) {
Integer duration = obj1.getDuration().compareTo(obj2.getDuration());
Integer dateCreation = obj2.getDateCreation().compareTo(obj1.getDateCreation());
return duration.compareTo(dateCreation );
}
说明
看着你的Comparator
:
public static final Comparator<Youku> AscDurRevCreationDate =
Comparator.comparing(Youku::getDuration)
.reversed()
.thenComparing(Youku::getDateCreation)
.reversed();
您想按持续时间 (getDuration
)、降序而不是升序 (reversed()
) 比较 Youku
s,如果两个持续时间相等,则通过创建打破平局日期(getDateCreation
),降序。
正确的 Comparable
实现如下所示:
@Override
public int compareTo(Youku other) {
int durationResult = Integer.compare(getDuration(), other.getDuration());
durationResult *= -1; // for reversed
if (durationResult != 0) { // different durations
return durationResult;
}
// break ties using creation date
int creationDateResult = Integer.compare(getDateCreation(), other.getDateCreation());
creationDateResult *= -1;
return creationDateResult;
}
或紧凑型:
int durationResult = -1 * Integer.compare(getDuration(), other.getDuration());
return durationResult != 0
? durationResult
: -1 * Integer.compare(getDateCreation(), other.getDateCreation());
基于比较器
或者,您也可以根据您已有的 Comparator
实施该方法:
public static final Comparator<Youku> comparator =
Comparator.comparing(Youku::getDuration)
.reversed()
.thenComparing(Youku::getDateCreation)
.reversed();
...
@Override
public int compareTo(Youku other) {
return comparator.compare(this, other);
}
备注
您的代码尝试未显示 Comparable
实现,而是 Comparator
的手动实现。我想你在那里混淆了什么。
查看您的原始要求,我不得不指出,指定 reversed()
会颠倒 all 所需的顺序,即先前指定的排序顺序。所以假设所有的默认升序排序如下:
public static final Comparator<Youku> comparator =
Comparator.comparing(Youku::getDuration)
.reversed()
.thenComparing(Youku::getDateCreation)
.reversed();
首先按持续时间升序排序,然后按创建时间降序排序,因为第二个 reversed()
颠倒了之前的顺序。因此,要按降序对两者进行排序,请删除第一个 reversed()
.
假设您想按持续时间升序排序,但按创建时间降序排序。那你也可以这样做。
public static final Comparator<Youku> comparator =
Comparator.comparing(Youku::getDuration)
.thenComparing(Youku::getDateCreation, Comparator.reversedOrder());
Comparator.reverseOrder()
只影响当前排序方式
如果您想查看一个简单的示例,请查看以下内容。您可以调整比较器以查看不同的结果。
int[][] vals = { { 30, 6 }, { 40, 7 }, { 40, 8 }, { 10, 1 },
{ 10, 2 }, { 20, 3 }, { 20, 4 }, { 30, 5 }, { 50, 9 },
{ 50, 10 }, { 60, 11 }, { 60, 12 } };
// ascending first, descending second
Comparator<int[]> comp =
Comparator.comparing((int[] a) -> a[0])
.reversed()
.thenComparing(a -> a[1])
.reversed();
Arrays.sort(vals,comp);
for(int[] v : vals) {
System.out.println(Arrays.toString(v));
}
版画
[10, 2]
[10, 1]
[20, 4]
[20, 3]
[30, 6]
[30, 5]
[40, 8]
[40, 7]
[50, 10]
[50, 9]
[60, 12]
[60, 11]
这是我要获取的代码。
public static final Comparator<Youku> AscDurRevCreationDate =
Comparator.comparing(Youku::getDuration)
.reversed()
.thenComparing(Youku::getDateCreation)
.reversed();
下面的代码是我要将其转换成的代码。但是,我从下面的代码中得到了一些不同的结果。顺便说一句,我在这里使用 Duration 对象。
@Override
public int compare(Youku obj1, Youku obj2) {
Integer duration = obj1.getDuration().compareTo(obj2.getDuration());
Integer dateCreation = obj2.getDateCreation().compareTo(obj1.getDateCreation());
return duration.compareTo(dateCreation );
}
说明
看着你的Comparator
:
public static final Comparator<Youku> AscDurRevCreationDate =
Comparator.comparing(Youku::getDuration)
.reversed()
.thenComparing(Youku::getDateCreation)
.reversed();
您想按持续时间 (getDuration
)、降序而不是升序 (reversed()
) 比较 Youku
s,如果两个持续时间相等,则通过创建打破平局日期(getDateCreation
),降序。
正确的 Comparable
实现如下所示:
@Override
public int compareTo(Youku other) {
int durationResult = Integer.compare(getDuration(), other.getDuration());
durationResult *= -1; // for reversed
if (durationResult != 0) { // different durations
return durationResult;
}
// break ties using creation date
int creationDateResult = Integer.compare(getDateCreation(), other.getDateCreation());
creationDateResult *= -1;
return creationDateResult;
}
或紧凑型:
int durationResult = -1 * Integer.compare(getDuration(), other.getDuration());
return durationResult != 0
? durationResult
: -1 * Integer.compare(getDateCreation(), other.getDateCreation());
基于比较器
或者,您也可以根据您已有的 Comparator
实施该方法:
public static final Comparator<Youku> comparator =
Comparator.comparing(Youku::getDuration)
.reversed()
.thenComparing(Youku::getDateCreation)
.reversed();
...
@Override
public int compareTo(Youku other) {
return comparator.compare(this, other);
}
备注
您的代码尝试未显示 Comparable
实现,而是 Comparator
的手动实现。我想你在那里混淆了什么。
查看您的原始要求,我不得不指出,指定 reversed()
会颠倒 all 所需的顺序,即先前指定的排序顺序。所以假设所有的默认升序排序如下:
public static final Comparator<Youku> comparator =
Comparator.comparing(Youku::getDuration)
.reversed()
.thenComparing(Youku::getDateCreation)
.reversed();
首先按持续时间升序排序,然后按创建时间降序排序,因为第二个 reversed()
颠倒了之前的顺序。因此,要按降序对两者进行排序,请删除第一个 reversed()
.
假设您想按持续时间升序排序,但按创建时间降序排序。那你也可以这样做。
public static final Comparator<Youku> comparator =
Comparator.comparing(Youku::getDuration)
.thenComparing(Youku::getDateCreation, Comparator.reversedOrder());
Comparator.reverseOrder()
只影响当前排序方式
如果您想查看一个简单的示例,请查看以下内容。您可以调整比较器以查看不同的结果。
int[][] vals = { { 30, 6 }, { 40, 7 }, { 40, 8 }, { 10, 1 },
{ 10, 2 }, { 20, 3 }, { 20, 4 }, { 30, 5 }, { 50, 9 },
{ 50, 10 }, { 60, 11 }, { 60, 12 } };
// ascending first, descending second
Comparator<int[]> comp =
Comparator.comparing((int[] a) -> a[0])
.reversed()
.thenComparing(a -> a[1])
.reversed();
Arrays.sort(vals,comp);
for(int[] v : vals) {
System.out.println(Arrays.toString(v));
}
版画
[10, 2]
[10, 1]
[20, 4]
[20, 3]
[30, 6]
[30, 5]
[40, 8]
[40, 7]
[50, 10]
[50, 9]
[60, 12]
[60, 11]