[英]List.sort with two fields
我在 leetcode 讨论部分看到了这段代码,但我无法理解它。 请在这里帮忙。
HashMap<Character,Integer> map = new HashMap<>();
for(char ch: s.toCharArray()){
map.put(ch,map.getOrDefault(ch,0)+1);
}
List<Character> list = new ArrayList<>(map.keySet());//convert hashmap keys into list
list.sort((x,y) -> map.get(y) - map.get(x));
我无法理解以下行的含义。
list.sort((x,y) -> map.get(y) - map.get(x));
这条短线实际上发生了令人惊讶的事情: list.sort((x,y) -> map.get(y) - map.get(x));
.
List.sort( Comparator comparator )
List.sort
方法将Comparator
object 作为参数。
@FunctionalInterface
如果您查看Comparator
接口,您会看到它由@FunctionalInterface
注释。 引用 Javadoc,“从概念上讲,函数式接口只有一个抽象方法。”。
这段代码:
(x,y) -> map.get(y) - map.get(x)
... 是 lambda 语法,充当该单一抽象方法的实现。
编译器可以推断出这个实现的方法是Comparator
的compare
方法,这是Comparator
上唯一的抽象方法。
Comparator#compare
Comparator#compare
方法返回一个int
integer 数字。 引用 Javadoc:返回的数字表示“负 integer、零或正 integer,因为第一个参数小于、等于或大于第二个。”。
HashMap
中的键值对的值侧的类型为Integer
class。 因此,仅从另一个值中减去一个值Integer
object 是一种看似聪明的方法来确定要由compare
数返回的 integer 数。
但是, 如下所述,这种方法在数学上存在缺陷。 ⚠️
减法可能导致integer 溢出。 最好将比较工作委托给Integer
class: Integer.compare
中的方法。
( x , y ) -> Integer.compare( x , y )
如果对该方法的实现感到好奇,请查看OpenJDK 项目上的开源代码。 摘抄:
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
另一种方法是使用由 static Comparator.comparingInt
方法返回的Comparator
器 object。
[警告:我还没有测试过这段代码。]
list.sort( Comparator.comparingInt( list :: get ) )
那个list:: get
部分是一个方法引用。
此外, map.get(y) - map.get(x)
部分调用auto-boxing 。
每个get
调用都会返回一个 object,类型为Integer
class。 使用减号-
Integer
对象直接没有意义; 不能减去对象。 但是,编译器足够聪明,可以识别Integer
object 可以转换为int
原语。 并且可以减去两个int
基元。
您可以使用 Go 在 IDE 中声明。 (例如 Intellij 中的 Ctrl + B )并查看方法:
sort(Comparator<? super E> c)
所以没有 2 个字段,只有一个,一个比较器,如上一个答案中所述。
如果您将其提取为变量(Intellij 中的 Ctrl + Alt + V),也许它会帮助您阅读清楚。
Comparator<Character> characterComparator = (x, y) -> map.get(y) - map.get(x);
同样在这种情况下,它可以简化为:
Comparator.comparingInt(map::get)
所以排序是:
list.sort(Comparator.comparingInt(map::get));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.