2017-10-10 92 views
0

我正在学习Kotlin和RxJava。我在JAVA这样的代码:将RxJava代码正确转换为Kotlin

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+""); 
      } 
     } 
    } 
} 

但是,当我在AndroidStudio转换它在IDE中有一堆的错误。

这是该代码在科特林,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() + "") 
     } 
     } 
    } 
} 

它给了我的错误,强调“未解决的引用抛出:”和“‘接受’压倒理智最多”。我如何将Java代码正确转换为Kotlin?

回答

1

在科特林可以更换接口实现方式中,仅具有一个方法,用于lambda表达式(doc)。

就像Java 8一样,Kotlin支持SAM转换。这意味着只要接口方法的参数类型与Kotlin函数的参数类型相匹配,Kotlin函数文字就可以用一个非默认方法自动转换为Java接口的实现。

这就给了你:

.subscribe(
     { item: Long? -> 

     }, 
     { t: Throwable -> 

     }, 
     {//onComplete 

     }) 

还取决于如果您正在使用RxJava2(doc):

RxJava 2.X不再接受空值和下面将产生 NullPointerException立即或作为信号

因此,你确定你是不是在你的onNext接收空,你可以删除安全空检查?

.subscribe(
     { item: Long -> 

     }, 
     { t: Throwable -> 

     }, 
     {//onComplete 

     }) 
1

您可以使用安全的npe和lambda来更新您的代码。有时候,从java转换到kotlin的代码需要一些化妆品触摸。

.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 { }) 

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

      }, Consumer { }, Action { })