将RxJava Observable转换为RxScala Observable

时间:2016-09-15 07:27:19

标签: rx-java rx-scala rx-javafx

我正在Scala中编写一个小型JavaFx应用程序,我喜欢使用RxScala和RxJavaFx。使用以下代码,我得到 RxJava Observable

JavaFxObservable.fromObservableValue(textfield.textProperty())

显然,正如我在Scala中写的那样,我希望有一个 RxScala Observable。现在我找到了this post,说要么我必须导入隐式转换类JavaConversions._或直接调用toScalaObservable。但是,第一个选项不适用于我,第二个选项看起来很难看:

选项1:

import rx.lang.scala.JavaConversions._
JavaFxObservable.fromObservableValue(textfield.textProperty())
  .map(s => /* do something */)

这不起作用,因为RxJava也提供map运算符,尽管参数的类型在技术上有所不同。

选项2:

import rx.lang.scala.JavaConversions._
toScalaObservable(JavaFxObservable.fromObservableValue(textfield.textProperty()))
  .map(s => /* do something */)

这有效,但老实说,这看起来真的太可怕了!

问题1:我错过了什么,或者这些只是两个选项吗?

我的意思是,要从Java的标准集合转换为Scala的集合(反之亦然),您有两个选项:JavaConvertersJavaConversions。前者引入了关键字asJava / asScala,而后者有点等同于rx.lang.scala.JavaConversions并且隐式地为您进行转换(如果您很幸运!)。通过Google搜索这两者的偏好,很明显大多数人更喜欢JavaConvertersasScala关键字的更明确的隐式转化。

问题2:是否有与JavaConverters类似的结构与RxScala?这会使上面的代码更加清晰,我会说:

import rx.lang.scala.JavaConverters._ // this class doesn't exist!
JavaFxObservable.fromObservableValue(textfield.textProperty())
  .asScala
  .map(s => /* do something */)

3 个答案:

答案 0 :(得分:3)

我会按如下方式编写您的示例:

import rx.lang.scala.JavaConversions._
val texts: Observable[String] = JavaFxObservable.fromObservableValue(textfield.textProperty())
texts.map(s => /* do something */)

其中Observable[String]是Scala Observable。 为val texts提供显式类型可确保隐式转换启动。

为什么没有asScala

这需要另一个隐式包装类(让我们在PreScalaObservable中调用),只有一个名为toScala的方法,所以当你编写myJavaObservable.toScala时,编译器会把它转过来像toPreScalaObservable(myJavaObservable).toScala这样的东西。

有两个包装类会有点混乱。或者如果你非常聪明,你实际上可以将asScala方法放入Scala Observable并将其实现为返回this,并且因为Java Observable没有名为asScala的方法, myJavaObservable.toScala会奏效。但同样,对于初学者而言,这可能相当复杂......

但如果你有更好的想法,或者知道如何简单地提出这个问题,我建议你在RxScala issues中提出一个问题。该项目仍然是0.x而且没有任何内容......; - )

答案 1 :(得分:0)

为什么需要将RXJava转换为RXScala ?, RXScala具有RXJava所具有的所有功能。 例如

ZIP:

  @Test def zip(): Unit = {
    addHeader("Observable zip")
    Observable.just("hello")
      .zip(Observable.just(" scala"))
      .zip(Observable.just(" world!"))
      .map(s => s._1._1.concat(s._1._2).concat(s._2).toUpperCase)
      .subscribe(s => println(s));
  }

MERGE:

  @Test def merge(): Unit = {
    addHeader("Observable merge")
    Observable.just("hello")
      .merge(Observable.just(" scala"))
      .merge(Observable.just(" world!"))
      .reduce((s, s1) => s.concat(s1))
      .map(s => s.toUpperCase).subscribe(s => println(s))
  }

FLATMAP:

  @Test def flatMap(): Unit = {
    addHeader("Flat Map")
    val text = "number mutated in flatMap::"
    val list = getList
    Observable.from(list)
      .flatMap(n => Observable.just(n) //--> New pipeline
        .map(n => text.concat(String.valueOf(n))))
      .map(s => s.toUpperCase())
      .subscribe(s => println(s))
  }

我会从头开始对你说实话。 如果您想了解更多运算符示例https://github.com/politrons/reactiveScala

答案 2 :(得分:0)

这个问题是RxScala项目this pull request的起点。

可以通过导入rx.lang.scala.JavaConverters来使用原始问题中提出的语法。

import rx.lang.scala.JavaConverters._
JavaFxObservable.fromObservableValue(textfield.textProperty())
  .asScala
  .map(s => /* do something */)

同样,可以使用Observable将Scala Observable转换为Java asJava

另请参阅预期用途的examples