java.lang.ClassCastException: java.lang.String[] 无法转换为 java.util.List

java.lang.ClassCastException: java.lang.String[] cannot be cast to java.util.List

我读过一些关于这个主题的其他问题,但我的情况不同,因为它包含三个 java 类.

首先,我有一个用于回收器视图的适配器,它向我发送通过 onClick() 中的 intent 单击的课程名称。

CustomAdapter.java:

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

import static androidx.core.content.ContextCompat.startActivity;

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
    private List<String> data;
    private List<Integer> d2;
    private Context c;
    public CustomAdapter (Context c , List<String> data,List<Integer> data2){
        this.c = c;
        this.data = data;
        this.d2 = data2;
    }

    @Override
    public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_view, parent, false);
        return new ViewHolder(rowItem);
    }

    @Override
    public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
        holder.textView.setText(this.data.get(position));
        holder.tv2.setText(Integer.toString(this.d2.get(position)));

    }

    @Override
    public int getItemCount() {
        return this.data.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private TextView textView,tv2;

        public ViewHolder(View view) {
            super(view);
            view.setOnClickListener(this);
            this.textView = view.findViewById(R.id.textview);
            this.tv2 = view.findViewById(R.id.textview2);
        }

        @Override
        public void onClick(View view) {
// I'm passing the name of the course which the user clicked at to CourseList.java
            Intent i = new Intent(c, CourseList.class);
            i.putExtra("course",textView.getText().toString());
            c.startActivity(i);
        }
    }
}

重申一下,原意如下:

  @Override
        public void onClick(View view) {
// I'm passing the name of the course which the user clicked at to CourseList.java
            Intent i = new Intent(c, CourseList.class);
            i.putExtra("course",textView.getText().toString());
            c.startActivity(i);
        }

CourseList.java中,我想显示与点击课程相关的主题。因此,利用 recyclerview 并将与每门课程 (List<String>) 相关的主题存储在 HashMap<String,String[]>.

CourseList.java:

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class CourseList extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle saved){
        super.onCreate(saved);
        setContentView(R.layout.activity_reg);
        Bundle extras = getIntent().getExtras();
        HashMap courses = new HashMap<String,String[]>();
        courses.put("Negotiation",new String[]{"Common ground", "Carpet"});
        courses.put("Pyschology",new String[]{"Happy", "No"});
        courses.put("Joke",new String[]{"Map", "Sarcasm"});
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        String a = extras.getString("course");
        List<String> b = (List<String>) courses.get(a);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(new CourseAdapter(CourseList.this, b));
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));


    }
}

我的 HashMap courses.get() returns 一个 java.lang.Object 但是 CourseAdapter.java 的构造函数需要一个 java.util.List<java.lang.String>。 所以,我在这一行进行类型转换:

List<String> b = (List<String>) courses.get(a);

但我的应用因运行时错误而崩溃:

java.lang.ClassCastException: java.lang.String[] cannot be cast to java.util.List

这里是 CourseAdapter.javaCourseList.java 的适配器):

CourseAdapter.java:

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

import static androidx.core.content.ContextCompat.startActivity;

public class CourseAdapter extends RecyclerView.Adapter<CourseAdapter.ViewHolder> {
    private List<String> data;
    private Context c;
    public CourseAdapter (Context c , List<String> data){
        this.c = c;
        this.data = data;
    }

    @Override
    public CourseAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View rowItem = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_view, parent, false);
        return new ViewHolder(rowItem);
    }

    @Override
    public void onBindViewHolder(CourseAdapter.ViewHolder holder, int position) {
        holder.textView.setText(this.data.get(position));

    }

    @Override
    public int getItemCount() {
        return this.data.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private TextView textView,tv2;

        public ViewHolder(View view) {
            super(view);
            view.setOnClickListener(this);
            this.textView = view.findViewById(R.id.textview);
        }

        @Override
        public void onClick(View view) {
            Intent i = new Intent(c, RegistrationActivity.class);
            c.startActivity(i);
        }
    }
}

...怎么看不到!?

    HashMap courses = new HashMap<String,String[]>();
    List<String> b = (List<String>) courses.get(a);

让我详细说明一下它的作用:

    HashMap courses = new HashMap<String,String[]>();
    String[] temp = courses.get(a);
    List<String> b = (List<String>) temp;

现在为什么从 String[]List<String> 的转换失败了?因为一个是List,一个是Array。

要么使用

    HashMap<String,List<String>> courses = new HashMap<>();
    List<String> b = courses.get(a);

或做

    HashMap<String,String[]> courses = new HashMap<>();
    String[] b =  courses.get(a);

,无需转换。

类型安全 courses 看起来像:

Map<String, String[]> courses = new HashMap<>();

如果您不使用参数 <>,那么编译器将关闭泛型类型,作为古老的 pre-generics java 风格。

作为courses.get(a)returns一个String[],你可以把它们铲到列表中:

List<String> b = new ArrayList<>();
Collections.addAll(b, courses.get(a));

或者更短,但是列表包裹了数组,所以你不能 add/remove,set 会改变数组(我知道你只是想迭代它):

List<String> b = Arrays.asList(courses.get(a));

这也说明了为什么您应该使用接口(List、Map)而不是实现 类(ArrayList、HashMap)——就像您对 HashMap 所做的那样。作为 asList returns 只是一个 List<String>.