The simplest way to integrate any Java code into RxJava is to use the Callable interface. It's an interface that represents an operation that returns some result and can throw an exception. It's very similar to Runnable; however, Runnable interface doesn't return any value.
To make Callable a part of reactive flow, the .fromCallable() method can be used on Observable:
Observable.fromCallable(() -> someOperation());
If the operation will be long-running, you must subscribe to an Observable on a specific scheduler:
Observable.fromCallable(() -> longRunningOperation())
.subscribeOn(Schedulers.io());
Otherwise, it will run on the current thread by default and will block all the other operations.
Futures are usually used in places where a need to fetch a result of an asynchronous operation is present. The Future waits until the computation finishes, and then it becomes available for retrieval using the .get() method. If the result is not available, the Future will block until it becomes ready.
RxJava provides a method on Observable to consume Futures, such as the following:
Observable.fromFuture(new FutureTask<>(() -> longRunningOperation()))
.fromFuture() is more useful for integration with code that already provides Future as an interface for its long-running operations. If one is trying to adapt the existing code for use with RxJava, it is easier to just use the Callable interface.