【发布时间】:2019-03-20 18:53:05
【问题描述】:
我正在尝试在 java 中创建一个排序映射(按键的降序排序)。 我试过了
Map<Integer,Integer> map = new TreeMap<>((a,b)->(b-a));
如果我为同一任务编写 Comparator 类,会不会对性能产生任何影响?
【问题讨论】:
-
首先
(a,b)->(b-a)这是错误的;其次,它在引擎盖下(几乎)是一样的,你将永远感受到差异 -
b-a 没有错,因为我希望它按降序排序。我的错 。我应该提到这一点。
-
(a,b)->(b-a)已损坏,因为a和b之间的差异 不适合a和b的值类型。对于Integer,两个值之间的最大差值是Integer.MIN_VALUE和Integer.MAX_VALUE之间的差值,即2³²-1,或者是Integer.MAX_VALUE的两倍。所以你的比较器容易溢出。正确的实现是(a,b)->Integer.compare(b,a)或(a,b)->b.compareTo(a),其作用与Comparator.reverseOrder()相同。底线是,不要试图通过减法实现比较器来变得聪明。 -
我使用了
b-a,因为我所有的整数都是正数,而且b-a比compareTo()方法快。这也很重要,因为我问这个问题是因为我首先想知道在竞争性编码场景中对性能的影响。我想要的是实现一个TreeMap,因为输入大小在Integer.MAX_VALUE - 1000的范围内 -
当所有值都是正数时,这个使用差异的比较器将起作用,但我怀疑您是否曾经针对您声称
(a,b) -> (b-a)比(a,b) -> Integer.compare(b,a)或(a,b) -> b.compareTo(a)更快的说法做出有效的基准测试,resp .Comparator.reverseOrder()。但是,当然,“竞争性编码方案”通常意味着无论如何测量都是无效的,因此较高的初始化成本可能很重要。在这种情况下,在大多数情况下,使用像Comparator.reverseOrder()这样的现有比较器会胜出。
标签: lambda java-8 comparator treemap