据我所知,Comparator.comparingInt()
应该按升序排序,Comparator.comparingInt().reversed
应该按降序排序。但是我发现了一种相反的情况。
用一个例子可以更好地解释这一点。以下是我的代码。
金额等级:
class Amount
{
int lineNum;
int startIndex;
Double value;
//Getters , setters and toString.
}
主要方法:
public static void main( String[] args )
{
List<Amount> amounts = new ArrayList<>();
amounts.add( new Amount( 1.0, 5, 10 ) ); //LINE_NUM 5
amounts.add( new Amount( 3.0, 9, 30 ) );
amounts.add( new Amount( 2.0, 3, 40 ) );
amounts.add( new Amount( 9.0, 5, 20 ) ); //LINE_NUM 5
amounts.add( new Amount( 6.0, 1, 50 ) );
amounts.add( new Amount( 4.0, 5, 20 ) ); //LINE_NUM 5
System.out.println( ".............BEFORE SORTING.........." );
amounts.forEach( System.out::println );
amounts.sort(
Comparator.comparingInt( Amount::getLineNum ) //NOTE THIS
. .thenComparingInt( Amount::getStartIndex ).reversed()
.thenComparingDouble( Amount::getValue ) );
System.out.println( "\n\n.............AFTER SORTING.........." );
amounts.forEach( System.out::println );
}
我想要金额列表按lineNum升序,startIndex降序和值升序排序。
所以我的期望是这样。
.............排序后........(预期)
金额[lineNum = 1,startIndex = 50,值= 6.0]
金额[lineNum = 3,startIndex = 40,value = 2.0]
金额[lineNum = 5,startIndex = 20,value = 4.0]
金额[lineNum = 5,startIndex = 20,value = 9.0]
金额[lineNum = 5,startIndex = 10,value = 1.0]
金额[lineNum = 9,startIndex = 30,value = 3.0]
.............排序后........(实际)
金额[lineNum = 9,startIndex = 30,value = 3.0]
金额[lineNum = 5,startIndex = 20,value = 4.0]
金额[lineNum = 5,startIndex = 20,value = 9.0]
金额[lineNum = 5,startIndex = 10,value = 1.0]
金额[lineNum = 3,startIndex = 40,value = 2.0]
金额[lineNum = 1,startIndex = 50,值= 6.0]
除了lineNum顺序,其他一切都正确。金额按排序,按lineNumber降序排序,而我希望它按升序排序。
当我将Comparator更改为以下内容时,结果与预期的一样
amounts.sort(
Comparator.
comparingInt( Amount::getLineNum ).reversed()
.thenComparingInt( Amount::getStartIndex ).reversed()
.thenComparingDouble( Amount::getValue ) );
这很奇怪,因为
comparingInt( Amount::getLineNum ).reversed()
应该按行号降序对金额进行排序。我注意到的另一件事是,与StartIndex进行比较可以正常工作。但是不是按lineNumber的部分进行比较。
有人可以解释吗?
最佳答案
如果将每个呼叫放在一行上,则更容易理解发生了什么:
Comparator.comparingInt(Amount::getLineNum)
.thenComparingInt(Amount::getStartIndex)
.reversed()
.thenComparingDouble(Amount::getValue)
该
reversed()
返回一个比较器,该比较器将反转其调用的比较器的结果……这是“首先比较行号,然后比较起始索引的比较器”。这不像只是放在前面的thenComparingInt()
调用的作用域中,这就是您以前的格式使它看起来像的样子。您可以这样做:
Comparator.comparingInt(Amount::getLineNum)
.thenComparing(Comparator.comparingInt(Amount::getStartIndex).reversed())
.thenComparingDouble(Amount::getValue)
在这一点上,只是开始索引比较被逆转了。