2017-07-18 313 views
1

该代码在Java中工作,但在转换为Kotlin时不再有效。它抛出一个IndexOutOfBoundsException从列表中抛出抛出异常时抛出IndexOutOfBoundsException:Java-> Kotlin

这里是原始的Java:

grid_view.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
      String selectedItem = ((TextView) view.findViewById(R.id.tag_name)).getText().toString(); 
      for (int j = 0; j < itemList.size(); j++){ 
       String tempString = itemList.get(j); 
       if(tempString.equals(selectedItem)) { 
        Log.d("Update", "Removing: " + selectedItem); 
        itemList.remove(j); 
       } 
      } 
     } 
    }); 

这是新科特林:

grid_view!!.onItemClickListener = AdapterView.OnItemClickListener { _, _, _, _ -> 
      val selectedItem = (tag_name as TextView).text.toString() 
      itemList.indices.forEach { 
       val tempString = itemList[it] 
       if (tempString == selectedItem) { 
        Log.d("Update", "Removing: " + selectedItem) 
        itemList.removeAt(it) 
       } 
      } 
    } 

回答

3

由于indices在第一时间被初始化,所以forEach操作indices后从未改变您从List删除元素,但size()是用Java改变,例如:

//       v--- `size` is changed after remove item from List 
for (int j = 0; j < itemList.size(); j++){ 
    //... 
} 

对于科特林易变的操作,请使用 MutableCollection#removeIf/MutableCollection#removeAll代替,例如:

itemList.removeIf { it == selectedItem } // java-8 

itemList.removeAll { it == selectedItem } // Kotlin 

存在的Java代码错误的逻辑,例如:

for (int j = 0; j < itemList.size(); j++){ 
    String tempString = itemList.get(j); 
    if(tempString.equals(selectedItem)) { 
     itemList.remove(j--); 
     //    ^
     // you should minus the current j, if don't the next is skipped 
    } 
} 
+0

谢谢,这个例外不再被抛出。但是,它仍然不像以前那样行事。无论grid_view中哪个项目被点击,第一项都被删除。日志语句显示selectedItem始终是第一个。 – Roc47HS

+0

@ Roc47HS嗨,我不擅长英语。请说清楚,先生。 :) –

+0

抱歉,不清楚。 grid_view应该在点击某个项目时将其从列表和grid_view中移除。这就是它在原始Java代码中的表现。现在在Kotlin中,即使我点击grid_view中的第二个或第三个项目,它也会删除第一个项目。 – Roc47HS