当前位置: 首页 > 面试题库 >

Java Lambda表达式,转换和比较器

赵开诚
2023-03-14
问题内容

我正在浏览Java源代码中的Map接口,并遇到了以下这段代码:

    /**
     * Returns a comparator that compares {@link Map.Entry} in natural order on value.
     *
     * <p>The returned comparator is serializable and throws {@link
     * NullPointerException} when comparing an entry with null values.
     *
     * @param <K> the type of the map keys
     * @param <V> the {@link Comparable} type of the map values
     * @return a comparator that compares {@link Map.Entry} in natural order on value.
     * @see Comparable
     * @since 1.8
     */
    public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
        return (Comparator<Map.Entry<K, V>> & Serializable)
            (c1, c2) -> c1.getValue().compareTo(c2.getValue());
    }

从方法声明中,我知道这是一个通用方法,该方法返回一个Comparator类型,该Comparator类型可以从传递给它的映射条目中推断出来,也可以在该方法中明确提供。

真正让我失望的是返回值。似乎lambda表达式

(c1, c2) -> c1.getValue().compareTo(c2.getValue());

被显式转换为Comparator<Map.Entry<K, V>>。这是正确的吗?

我还注意到,表观演员包括& Serializable。我之前从未见过将接口与类组合在一起的类型,但是在编译器中它看起来像下面的样子:

((SubClass & AnInterface) anObject).interfaceMethod();

尽管以下操作无效:

public class Foo {
    public static void main(String[] args) {
        Object o = new Foo() {
            public void bar() {
                System.out.println("nope");
            }
        };
        ((Foo & Bar) o).bar();
    }   
}

interface Bar {
    public void bar();
}

因此,有两个问题:

  1. 如何将接口添加到应该使用的演员表中?这是否只是强制执行接口方法的返回类型?

  2. 您可以将Lambda表达式强制转换为Comparator吗?他们还能被铸成什么?还是lambda表达式本质上只是一个Comparator?有人可以澄清所有这些吗?


问题答案:

如何将接口添加到应该使用的演员表中?

它具有强制转换的语法,但是实际上是通过类型接口定义要创建的lambda的类型。也就是说,您没有创建对象的实例,然后将其转换为另一种类型。

这是否只是强制执行接口方法的返回类型?

这实际上定义了运行时将构建的lambda类型。有一个LambdaMetaFactory,可在运行时获取此类型,并在类型包括时生成额外的代码Serializable

您可以将Lambda表达式强制转换为Comparator吗?

您只能将引用转换为对象已存在的类型。在这种情况下,您要定义要创建的lambda必须为Comparator。您可以使用只有一种抽象方法的任何类型。

还是lambda表达式本质上只是一个Comparator?

相同的lambda代码可以在不同的上下文和不同的界面中使用(复制+粘贴)而无需更改。Comparator正如您在JDK的许多其他示例中将看到的那样,它不必一定是a

我发现一个有趣的count方法是上的方法Stream



 类似资料:
  • 我在查看接口的Java源代码时,遇到了以下代码片段: 从方法声明中,我得到这是一个通用方法,它返回一种类型的比较器,这种比较器要么是从传递给它的映射条目中推断出来的,要么是在方法中显式提供的。 真正让我恼火的是返回值。看来λ表达式 显式转换为 ?有人能澄清这一切吗?

  • 我正在尝试执行以下操作(cb=CriteriaBuilder): 但我得到以下语法错误: 绑定不匹配:(表达式之间的泛型方法 是否可以转换表达式

  • P.S.如果您将这两行代码作为结果所做的事情添加进去,那将是非常感谢的。

  • 我有下面的类和对象的ArrayList: 我想要的是从我的列表中得到一个字符串和整数地图,其中包含门票中的目的地和我列表中每个目的地的出现次数。我想它会这样开始,但是我不知道如何继续:

  • 我试图将js代码转换为java版本,但对正则表达式有点困惑:在js中,我有一个类似于:testString的表达式。拆分(“/(\w*\d)/g”) 我可以在java中使用什么等效语言?我试着用匹配器得到同样的结果。find()和split函数,但结果不一样。

  • 我还在尝试理解lambda表达式。 我想将这个lambda表达式转换为“普通”表达式: 你们有主意吗? 提前谢谢。