繁体   English   中英

List.sort 有两个字段

[英]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,“从概念上讲,函数式接口只有一个抽象方法。”。

Lambda

这段代码:

(x,y) -> map.get(y) - map.get(x)

... 是 lambda 语法,充当该单一抽象方法的实现。

编译器可以推断出这个实现的方法是Comparatorcompare方法,这是Comparator上唯一的抽象方法。

Comparator#compare

Comparator#compare方法返回一个int integer 数字。 引用 Javadoc:返回的数字表示“负 integer、零或正 integer,因为第一个参数小于、等于或大于第二个。”。

HashMap中的键值对的值侧的类型为Integer class。 因此,仅从另一个值中减去一个值Integer object 是一种看似聪明的方法来确定要由compare数返回的 integer 数。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM