简体   繁体   English

Scala 功能1<t,u> 变成 Function1<object,object> 在 Java</object,object></t,u>

[英]Scala Function1<T,U> becomes Function1<Object,Object> in Java

I am trying to use the Deequ library from Java, and am having issue using the following method:我正在尝试使用 Java 中的 Deequ 库,但使用以下方法时遇到问题:

  def hasCompleteness(
      column: String,
      assertion: Double => Boolean,
      hint: Option[String] = None)
    : CheckWithLastConstraintFilterable = {
    addFilterableConstraint { filter => completenessConstraint(column, assertion, filter, hint) }
  }

In particular, for the assertion, I need to pass in a Function1<Double, Boolean>特别是,对于断言,我需要传入一个Function1<Double, Boolean>

So I use the following code to create an assertion function in Java:所以我使用下面的代码在Java中创建一个断言function:

public static Function1<Double, Boolean> atLeast(double thresholdPercentage) {
  return new scala.compat.java8.functionConverterImpls.FromJavaFunction<>((Double actualPercentage) -> actualPercentage >= thresholdPercentage);
}

Simple enough, right?很简单,对吧?

Only, my Java Class now won't compile because the signature of the hasCompleteness method, when viewed from Java is that the assertion parameter is a Function1<Object, Object> .只是,我的 Java Class 现在无法编译,因为hasCompleteness方法的签名,从 Java来看,断言参数是一个Function1<Object, Object> Thus I see the following error:因此,我看到以下错误:

Required type: Function1<Object, Object>
Provided: Function1<Double, Boolean>

If I change my atLeast method to return an unparametrized Function1 the issue goes away, but this feels like an ugly kludge.如果我更改我的atLeast方法以返回未参数化的Function1问题就会消失,但这感觉就像一个丑陋的杂物。

Am I condemned to losing the type params when using this method from Java?使用 Java 中的这种方法时,我是否注定会丢失类型参数? Or is there something perhaps wrong with my IntelliJ / Gradle setup causing this weird behavior?还是我的 IntelliJ / Gradle 设置可能有问题导致这种奇怪的行为?

That seems how Scala compiler translates "primitive" Scala types (remember, Double here is scala.Double and not java.lang.Double ). That seems how Scala compiler translates "primitive" Scala types (remember, Double here is scala.Double and not java.lang.Double ). Eg Scala declarations例如 Scala 声明

  var d: Double => Boolean;
  var s: String => String;

produce (as shown by javap):产生(如javap所示):

  public abstract scala.Function1<java.lang.Object, java.lang.Object> d();
  public abstract scala.Function1<java.lang.String, java.lang.String> s();

Note how Double and Boolean both translate to Object , but String is preserved请注意如何DoubleBoolean都转换为Object ,但String被保留

peterz detailed exactly what happens under the hood.彼得兹详细描述了幕后发生的事情。

Sounds like what you need is an explicit conversion from the primitive double Java predicate ( java.util.function.DoublePredicate ) to the scala.Double Scala predicate ( Double => Boolean ). Sounds like what you need is an explicit conversion from the primitive double Java predicate ( java.util.function.DoublePredicate ) to the scala.Double Scala predicate ( Double => Boolean ).

Scala actually offers one such conversion called FromJavaDoublePredicate . Scala 实际上提供了一种称为FromJavaDoublePredicate的转换。 The code does not require explicit Double cast anymore:该代码不再需要显式Double强制转换:

  /* some scala file */
  def hasCompleteness(
      x: Double,
      f: Double => Boolean
  ): Unit = println(f(x))

  /* some java file */
  public static FromJavaDoublePredicate atLeast(double thresholdPercentage) {
      return new scala.compat.java8.functionConverterImpls.FromJavaDoublePredicate(
        actualPercentage -> actualPercentage >= thresholdPercentage);
  }

  FromJavaDoublePredicate f = atLeast(3.0);
  Test.hasCompleteness(5, f);  // true

PS. PS。 From what I saw, you chose scala-java8-compat , so I assumed you use an earlier version of Scala.从我所见,您选择了scala-java8-compat ,所以我假设您使用的是 Scala 的早期版本。 Their maintainers state:他们的维护者 state:

If you are using Scala 2.13 or newer only, then don't use this library!如果您仅使用 Scala 2.13 或更新版本,请不要使用此库! Use the classes under scala.jdk instead;改用scala.jdk下的类; they were added to the standard library in 2.13.它们在 2.13 中被添加到标准库中。

So for Scala 2.13.x I recommend using the FromJavaDoublePredicate case class in the FunctionWrappers object instead.因此,对于 Scala 2.13.x,我建议在FunctionWrappers object 中使用FromJavaDoublePredicate案例 class 。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能将Scala的Function1隐式转换为java.util.function.Function? - Why can't I implicit convert Scala's Function1 to java.util.function.Function? Java中的finagle-Function,Function1等 - finagle in java - Function, Function1 etc 获取 Akka stream 代码错误“主”线程 java.lang.NoClassDefFoundError: scala/Function1$class - Error getting Akka stream code Exception in thread “main” java.lang.NoClassDefFoundError: scala/Function1$class 如何解决Function1中的Function1(上下文)不能应用于() - How to solve Function1 (Context) in Function1 cannot be applied to () Java 相当于 Kotlin 的 Function0 和 Function1 是什么? - What is Java equivalent to Function0 and Function1 of Kotlin? 如何在Java中实现Function1(其compose和andThen方法)? - How to implement a Function1 in Java (its compose and andThen methods)? 当我在ScalaIDE中运行代码时,为什么会出现`java.lang.NoClassDefFoundError:scala / Function1`? - Why do I get `java.lang.NoClassDefFoundError: scala/Function1` when I run my code in ScalaIDE? 为什么 vavr 的 Function1 不接受 Seq<parent> class 接受序列<child> ?</child></parent> - Why won't vavr's Function1 accepting Seq<Parent> class accept Seq<Child>? Kotlin 找不到符号 Function1 构建错误 - Kotlin cannot find symbol Function1 build error 如何在Spark 2.3的数据集中开发Function1 / MapFunction接口的实现 <Row> 被突变 - How to develop implementation of the Function1/MapFunction interfaces in Spark 2.3 where the Dataset<Row> are mutated
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM