Reputation: 93
I've read some other questions on this topic , but my case is different as it encompasses three java classes.
First I've an adapter for recycler view which is sending me the name of the course clicked through an intent
in onClick()
.
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);
}
}
}
Just to reiterate , here is the intent:
@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);
}
In CourseList.java
, I want to show the topics related to the clicked course. So, making use of recyclerview
and storing the topics related to each course (List<String>
) in a 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));
}
}
My HashMap courses.get()
returns a java.lang.Object
but the constructor of CourseAdapter.java
requires a java.util.List<java.lang.String>
.
So, I'm typecasting at this line:
List<String> b = (List<String>) courses.get(a);
But my app is crashing with the runtime error:
java.lang.ClassCastException: java.lang.String[] cannot be cast to java.util.List
Here is CourseAdapter.java
(Adapter for CourseList.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);
}
}
}
Upvotes: 0
Views: 8548
Reputation: 109547
A type safe courses
looks like:
Map<String, String[]> courses = new HashMap<>();
If you do not use parameters <>
then the compiler switches off the generic typing, as ancient pre-generics java style.
As courses.get(a)
returns a String[]
, you can shovel them into the list as:
List<String> b = new ArrayList<>();
Collections.addAll(b, courses.get(a));
Alternatively and shorter, but the list wraps the array, so you cannot add/remove, and set will alter the array (I understood you just want to iterate over it):
List<String> b = Arrays.asList(courses.get(a));
This also shows why you should use interfaces (List, Map) instead of implementing classes (ArrayList, HashMap) - as you did with HashMap
-. as asList
returns just a List<String>
.
Upvotes: 1
Reputation: 2576
... how can you NOT see it!?
HashMap courses = new HashMap<String,String[]>();
List<String> b = (List<String>) courses.get(a);
Let me show some detail what this does:
HashMap courses = new HashMap<String,String[]>();
String[] temp = courses.get(a);
List<String> b = (List<String>) temp;
Now why does a cast from String[]
to List<String>
fail? Because one is a List, and the other one is an Array.
Either use
HashMap<String,List<String>> courses = new HashMap<>();
List<String> b = courses.get(a);
or do
HashMap<String,String[]> courses = new HashMap<>();
String[] b = courses.get(a);
, no casting necessary.
Upvotes: 1