评论者:ajoberstar
以下是在我(链接:[在这里](https://github.com/ajoberstar/ike.cljj/blob/master/src/main/clojure/ike/cljj/function.clj) 文本:ike.cljj)库中的另一种方法。它使用MethodHandles(即java.lang.invoke包)而不是常规反射。我不确定我是否在抽象类上测试过这个方法。
用法看起来与Ghadi发布的类似
`
(defsam my-sam
java.util.function.Predicate
[x]
(= x "it matched"))
(-> (Stream/of "not a match" "it matched")
(.filter my-sam)
(.collect Collectors/toList)
(-> (IntStream/range 0 10)
(.filter (sam* java.util.function.IntPredicate odd?))
(.collect Collectors/toList)
`
它使用[这里](https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandleProxies.html#asInterfaceInstance-java.lang.Class-java.lang.invoke.MethodHandle-) 文本:MethodHandleProxies.asInterfaceInstance) 创建一个代理实例的接口,该实例调用一个Clojure函数的方法。它不尝试验证参数数量,它只是将其作为varargs委托给IFn.applyTo(ISeq)。不确定它是否是最有效的,但它对我来说是有效的。
我认为[这里](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/invoke/MethodHandles.html) 的LambdaMetaFactory可能是满足这种用例的首选方法。但我发现要确切地了解如何使用它有困难,所以我没有深入研究。
我在我的方法(以及Ghadi的方法)中有主要的函数问题,你必须明确地提供你要代理的接口。Java lambdas和Groovy Closures可以针对期望SAM的方法使用,它只是根据方法期望的内容进行转换。理想情况下,这将由Clojure支持。
而不是必须这样做:
`
(-> (IntStream/range 0 10)
(.filter (sam* java.util.function.IntPredicate odd?))
(.collect Collectors/toList)
`
我想这样做:
`
(-> (IntStream/range 0 10)
(.filter odd?)
(.collect Collectors/toList)
`