简体   繁体   中英

Convert RxJava code to Kotlin properly

I am learning both Kotlin and RxJava. I hava such code in Java:

public class MainActivity extends AppCompatActivity {

private HashMap<String, Object> cacheToInsertToDb;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    cacheToInsertToDb = new HashMap<>();

    Observable.interval(1, TimeUnit.SECONDS)
            .take(30) // up to 30 items
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    cacheToInsertToDb.put(aLong+"", aLong);
                    Log.d("Observable", cacheToInsertToDb.values().toString());
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {

                }
            }, new Action() {
                @Override
                public void run() throws Exception {

                }
            });

    Observable.interval(10, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    proceedVlues(cacheToInsertToDb.values());
                    cacheToInsertToDb.clear();
                    Log.d("CLEARED", cacheToInsertToDb.values().toString());
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {

                }
            }, new Action() {
                @Override
                public void run() throws Exception {

                }
            });

}

private void proceedVlues(Collection<Object> values) {
        for(Object v: values){
            if(v instanceof Long){
                Log.d("proceedVlues", v+"");
            }
        }
   }
}

However, when i convert it in AndroidStudio there is bunch of errors in IDE.

Here it is this code in Kotlin, converted in Android Studio:

class MainActivity : AppCompatActivity() {

private var cacheToInsertToDb: HashMap<String, Any>? = null


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    cacheToInsertToDb = HashMap()

    Observable.interval(1, TimeUnit.SECONDS)
            .take(30) // up to 30 items
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Consumer<Long> {
                @Throws(Exception::class)
                override fun accept(aLong: Long?) {
                    cacheToInsertToDb!!.put(aLong!!.toString() + "", aLong)
                    Log.d("Observable", cacheToInsertToDb!!.values.toString())
                }
            }, Consumer { }, Action { })

    Observable.interval(10, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Consumer<Long> {
                @Throws(Exception::class)
                override fun accept(aLong: Long?) {
                    proceedVlues(cacheToInsertToDb!!.values)
                    cacheToInsertToDb!!.clear()
                    Log.d("CLEARED", cacheToInsertToDb!!.values.toString())
                }
            }, Consumer { }, Action { })

}

private fun proceedVlues(values: Collection<Any>) {
    for (v in values) {
        if (v is Long) {
            Log.d("proceedVlues", v.toString() + "")
        }
      }
   }
}

It gives me error underlining "unresolved reference to @Throws" and "'accept' overrides nothig". How can i convert that Java code properly to Kotlin?

You can update your code using safe npe and lambdas. Sometimes the code converted from java to kotlin needs some cosmetic touches.

  .subscribe(object : Consumer<Long> {
                    @Throws(Exception::class)
                    override fun accept(aLong: Long?) {
                        cacheToInsertToDb!!.put(aLong!!.toString() + "", aLong)
                        Log.d("Observable", cacheToInsertToDb!!.values.toString())
                    }
                }, Consumer { }, Action { })

to

.subscribe(Consumer<Long?>{ aLong ->
                    cacheToInsertToDb?.put(aLong?.toString() ?: "", aLong)
                    Log.d("Observable", cacheToInsertToDb?.values.toString())

            }, Consumer { }, Action { })

In kotlin you can replace interfaces implementations, having just one method, for a lambda expression ( doc ).

Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.

That gives you:

.subscribe(
        { item: Long? ->

        },
        { t: Throwable ->

        },
        {//onComplete

        })

also, depending if you are using RxJava2 ( doc ):

RxJava 2.x no longer accepts null values and the following will yield NullPointerException immediately or as a signal

Because of that you are sure you are not receiving a null in your onNext and you can remove the safe-null check ?

.subscribe(
        { item: Long ->

        },
        { t: Throwable ->

        },
        {//onComplete

        })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM