You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin调用Java方法时,如何转换java.util.ArrayList为kotlin.collections.ArrayList?

解决Kotlin接收Java返回的ArrayList类型问题

别担心,这个问题在Kotlin与Java互操作时非常常见,有几种简单且安全的处理方式,我结合你的代码来一步步说明:

一、最推荐:先修正Java代码的泛型(类型安全优先)

你的Java类LoadAllContacts里的loadContacts()方法返回的是原始类型的ArrayList,这不仅在Kotlin里会触发类型不安全警告,也是导致你类型不匹配的核心原因之一。先给Java代码加上泛型约束:

修改后的Java代码片段:

public class LoadAllContacts {
    // 修正为带泛型的集合
    public static ArrayList<HashMap<String, String>> al = null;
    public static final String[] keys = {"name", "number"}; // 补充number字段,匹配你Kotlin代码的取值逻辑
    public static final int[] ids = {R.id.contact_name, R.id.contact_number};

    // 修正方法的返回类型为带泛型的ArrayList
    public ArrayList<HashMap<String, String>> loadContacts() {
        al = new ArrayList<HashMap<String, String>>();
        try {
            cursor_Android_Contacts = contentResolver.query(
                ContactsContract.Contacts.CONTENT_URI, 
                null, null, null, 
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"
            );
        } catch (Exception e) {
            Log.e("error in contact", e.getMessage());
        }

        if (cursor_Android_Contacts.getCount() > 0) {
            if (cursor_Android_Contacts.moveToFirst()) {
                do {
                    // 修正HashMap为带泛型的类型
                    HashMap<String, String> hm = new HashMap<>();
                    String contact_id = cursor_Android_Contacts.getString(
                        cursor_Android_Contacts.getColumnIndex(ContactsContract.Contacts._ID)
                    );
                    String contact_display_name = cursor_Android_Contacts.getString(
                        cursor_Android_Contacts.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)
                    );
                    hm.put(keys[0], contact_display_name);

                    int hasPhoneNumber = Integer.parseInt(
                        cursor_Android_Contacts.getString(
                            cursor_Android_Contacts.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)
                        )
                    );
                    if (hasPhoneNumber > 0) {
                        Cursor phoneCursor = contentResolver.query(
                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                            null,
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " =? ",
                            new String[]{contact_id},
                            null
                        );
                        if (phoneCursor.moveToFirst()) {
                            String phoneNumber = phoneCursor.getString(
                                phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
                            );
                            hm.put(keys[1], phoneNumber); // 存入电话号码,对应Kotlin代码的取值
                        }
                        phoneCursor.close();
                    }
                    al.add(hm);
                } while (cursor_Android_Contacts.moveToNext());
            }
            return al;
        }
        return al;
    }
}

二、Kotlin中直接接收(无需额外转换)

在JVM平台上,kotlin.collections.ArrayList本质上就是java.util.ArrayList的类型别名,两者完全兼容。只要Java代码返回的是带泛型的ArrayList<HashMap<String,String>>,你可以直接赋值:

修改后的Kotlin代码片段:

class ContactAllFragment : Fragment() { // 类名首字母大写,符合Kotlin编码规范
    @BindView(R.id.contacts_lv) lateinit var contact_lv: ListView
    var al = ArrayList<HashMap<String,String>>()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_contact_all, container, false)
        ButterKnife.bind(this, view)

        // 直接接收,无需转换
        al = LoadAllContacts(requireContext().contentResolver, requireContext())
            .loadContacts()

        val adapter = SimpleAdapter(
            context, al, R.layout.listview_style,
            LoadAllContacts.keys, LoadAllContacts.ids
        )
        contact_lv.adapter = adapter // 修正为赋值adapter属性,原代码的adapter()是错误写法

        return view
    }

    @OnItemClick(R.id.contacts_lv)
    fun onItemClick(parent: AdapterView<*>?, position: Int) { // 补全position的类型参数
        val hmElement: HashMap<String,String> = al[position] // Kotlin用[]代替get(),更简洁
        val name = hmElement[LoadAllContacts.keys[0]] ?: "" // 加上空安全处理,避免空指针
        val number = hmElement[LoadAllContacts.keys[1]] ?: ""
    }
}

三、如果暂时不能修改Java代码(兼容原始类型)

如果因为某些原因无法修改Java代码,你可以先做一次安全的类型转换,再转换为Kotlin的ArrayList:

// 先把原始类型的ArrayList转换为带泛型的List,再转为Kotlin ArrayList
val javaList = LoadAllContacts(requireContext().contentResolver, requireContext())
    .loadContacts() as List<HashMap<String,String>>
al = javaList.toCollection(ArrayList())

或者更简洁的写法:

al = (LoadAllContacts(requireContext().contentResolver, requireContext())
    .loadContacts() as ArrayList<HashMap<String,String>>)

注意:这种方式存在类型转换风险,如果Java集合里的元素不是HashMap<String,String>,会抛出ClassCastException,所以还是优先推荐修正Java代码的泛型。


内容的提问来源于stack exchange,提问作者Abhishek Borikar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:25:41