【问题标题】:Creating generic lambdas in Java在 Java 中创建通用 lambda
【发布时间】:2015-08-23 14:45:26
【问题描述】:

在 java 中,您可以将类型参数添加到静态方法,以创建处理泛型的方法。你可以对 lambdas 做同样的事情吗?

在我的代码中我有

final private static <K,V> Supplier<Map<K, List<V>> supplier=HashMap::new;

我正在尝试将类型参数当作函数,但它不会让我这样做。

如果我这样做:

    final private static Supplier<Map<?, List<?>>> supplier=HashMap::new;

它不接受我尝试使用它的论点。我能做什么?

【问题讨论】:

  • 这不能是一个变量。事实上,像WhateverClassThatSupportsGenerics&lt;?&gt; var = ...;这样声明一个变量是没有用的,除非它是一个方法的参数。
  • 你在哪里尝试使用第二个声明? (您可能已经发现,第一个在语法上是无效的。)
  • 不可能构造有界的通用对象。您的代码行失败的原因相同,new HashMap&lt;Integer, List&lt;?&gt;&gt; 是合法的,但 new HashMap&lt;?, List&lt;?&gt;&gt; 不是。 ? 的意思是“我不知道这个 HashMap 使用什么类型”,但是当你创建一个 HashMap 时,你总是知道你打算在其中放入什么(即使你决定它是 java.lang.Object)。
  • @VGR:感谢“钻石运算符”,该规则已过时。你可以HashMap&lt;?, ?&gt; map=new HashMap&lt;&gt;();而不指定实际的类型参数。虽然这样的地图用处不大……
  • @Holger 有趣。我不知道这是可能的。我一直认为菱形运算符只是一种方便,节省了一些打字时间。

标签: java generics lambda java-8


【解决方案1】:

对此的一种解决方法可能是将方法引用包装到一个方法中,以便目标类型推导在调用站点解析类型:

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class GenericLambda
{
    // Syntactically invalid
    //final private static <K,V> Supplier<Map<K, List<V>> supplier=HashMap::new;

    final private static Supplier<Map<?, List<?>>> supplier=HashMap::new;

    // A workaround
    private static <K,V> Supplier<Map<K, List<V>>> supplier()
    {
        return HashMap::new;
    }


    public static void main(String[] args)
    {
        // Does not work
        //useSupplier(supplier);

        // Works
        useSupplier(supplier());
    }

    private static <K, V> void useSupplier(Supplier<Map<K, List<V>>> s)
    {
        System.out.println(s.get());
    }
}

【讨论】:

  • @NoDataFound 不确定你的意思,但在这里,不需要强制转换(尽管在这种情况下,粗暴的强制转换也可能是安全的,因为所有类型参数都会变成Object)编译...)
  • 虽然写supplier()作为方法参数而不是直接在那个地方写HashMap::new并没有太大的好处……
  • 这意味着所有调用站点都同样同意这种实现类的切换是可以接受的,甚至是有意的。否则,您必须遍历所有地方并验证此假设。虽然从纯粹的面向对象的角度来看,通过单一方法将HashMap::new 更改为LinkedHashMap::new 的可能性听起来像是一个巨大的优势,但在一个我们拥有不仅可以替换的体面的搜索和替换工具的世界中, HashMap::newLinkedHashMap::new 的所有出现但也显示每个地方允许程序员的干预......
  • @Holger:我不确定你在问什么:所有这些都被称为 工厂方法 模式。根据 Lishkov 的说法,所有适用于 HashMap 的东西也适用于 LinkedHashMap。但是,我只是想勾勒出一个解决方法来实现 OP 描述的目标。
  • 不是每个人都一直使用LinkedHashMap而不是HashMap,这一定是有原因的……不过,您只是想勾勒出一个解决方法来实现OP描述的目标,假设这就是 OP 想要的,因为我无法从他为什么尝试他尝试的问题中真正推断出,我只想提一下,我没有看到像 HashMap::new 这样简单地包装表达式的真正好处工厂方法(尤其是 private 之一)。工厂方法并非没有特定目的。但也许 OP 会回来告诉我们更多关于它的信息……
猜你喜欢
  • 2018-07-09
  • 1970-01-01
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 2016-12-09
  • 2019-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多