2

I'm new to android and recently I was trying to extract data from firebase into recyclerview/cardview to display data in vertical layout, it is showing the error of converting Hashmap to Arraylist, where code is:

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    new GetDataFromFirebase().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

// Read from the database
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference myRef = database.getReference("0XtzzDme");

    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            ArrayList<String> values = (ArrayList<String>) dataSnapshot.getValue();
            recyclerView.setAdapter(new RecyclerViewAdapter(values));
        }

        @Override
        public void onCancelled(DatabaseError error) {
            // Failed to read value
            System.out.println("Failed to read value." + error.toException());
        }
    });
}

and the recyclerviewadapter

    class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    private ArrayList<String> values;
    RecyclerViewAdapter(ArrayList<String> values) {
       this.values = values;
  }

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

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.name.setText(values.get(position));
}

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

class ViewHolder extends RecyclerView.ViewHolder {
    private TextView name;
    ViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.list_item_text);
    }
  }
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
user3921943
  • 91
  • 1
  • 2
  • 8
  • 5
    Because they can't, they are not the sames type of data. One is a Map, the other is a List – AxelH Feb 07 '17 at 12:11
  • there's isn't any code for hashmap that's why i posted the question here – user3921943 Feb 07 '17 at 12:15
  • 3
    @user3921943; That's the point. `dataSnapshot.getValue()` returns a `HashMap` while you're trying to deal with it as an `ArrayList`. That's like saying you bought a bird while it's actually a cow; It's not going to work... – 0xDEADC0DE Feb 07 '17 at 12:20

7 Answers7

7

As stated by the Firebase API, DataSnapshot.getValue() can return any of:

  • Boolean
  • String
  • Long
  • Double
  • Map<String, Object>
  • List<Object>

In case of your error it obviously returns a Map instead of the expected List.

To solve this problem you should rewind why you expect a List at that point and why a Map could possibly be returned. Maybe the fact that a Map is returned is an error already.

However, no matter to what conclusion you come, you will most probably have to write something like:

Object value = dataSnapshot.getValue();
if(value instanceof List) {
    List<Object> values = (List<Object>) value;
    // do your magic with values
}
else {
    // handle other possible types
}
Izruo
  • 2,246
  • 1
  • 11
  • 23
  • @AxelH DataSnapShot doesn't has generics, only a few of its methods. – Tom Feb 07 '17 at 12:38
  • @Tom, indeed, only just notice now that this was only used with `getValue(Class type)` so generic is only used here... – AxelH Feb 07 '17 at 12:42
  • Yes, and that's a totally different piece of cake, because that method is some sort of default struct builder. As it says in the documentation, it marshalls an instance of a class whose implementation is basically equivalent to the expected struct. Hence, there's no chance to get a `List` out of it. – Izruo Feb 07 '17 at 12:45
  • I think Izruo has put his finger on the problem "..maybe the fact that a Map is returned is an error already.." Why is a (presumably) simple JSON file from Firebase being returned as a Map. I am having the same problem and the database is comprised of Strings. – PhilipS Jan 27 '18 at 07:52
  • @Izruo How can we loop the object to get the values – Lahari Areti May 04 '18 at 04:10
4

Please use below Code to convert HashMap to ArrayList ,You can change String to File in your case.

//Creating a HashMap object

    HashMap<String, String> map = new HashMap<String, String>();

    //Getting Collection of values from HashMap

    Collection<String> values = map.values();

    //Creating an ArrayList of values

    ArrayList<String> listOfValues = new ArrayList<String>(values);
Chetan Joshi
  • 5,582
  • 4
  • 30
  • 43
2

Convert you Hashmap to Array list like that..

List<String> list = new ArrayList<String>(theHashMap.values()); //Most likely dataSnapshot.getValues()
AxelH
  • 14,325
  • 2
  • 25
  • 55
Abhishek Singh
  • 9,008
  • 5
  • 28
  • 53
2

HashMap and ArrayList are two completely different data types.

HashMap is an Implementation of the Map interface which stores key:value pairs

ArrayList is an Implementation of the List interface which stores a list of items

There are tons of Threads on SO how to convert a Map to a list (e.g. here).

Community
  • 1
  • 1
dipdipdip
  • 2,326
  • 1
  • 21
  • 31
1

it is showing the error of converting Hashmap to Arraylist

There is no converting in your code, and that is exactly the problem. You're trying to cast an HashMap as an ArrayList, which it isn't. Possible reading Possible reading 2

Converting one would be done by:

ArrayList<String> values = new ArrayList<>((HashMap<String, Object>) dataSnapshot.getValue()).values();
Mehmet K
  • 2,805
  • 1
  • 23
  • 35
  • I'm assuming dataSnapshot.getValue() returns an HashMap (because of the error wording) – Mehmet K Feb 07 '17 at 12:15
  • @Tom So dataSnapshot is the HashMap itself? – Mehmet K Feb 07 '17 at 12:20
  • Was looking at his code to see if the type was actually there :) – Mehmet K Feb 07 '17 at 12:26
  • Instead of using this cast, you could use the `getValues(Class valueType)` method, this would be cleaner ( I believe ) – AxelH Feb 07 '17 at 12:35
  • Wouldn't that still require the knowledge of the types of the HashMap? – Mehmet K Feb 07 '17 at 12:39
  • http://stackoverflow.com/questions/37688031/class-java-util-map-has-generic-type-parameters-please-use-generictypeindicator So `getValues(Map.class)` or alike won't work. also https://firebase.google.com/docs/reference/android/com/google/firebase/database/DataSnapshot.html#getValue(com.google.firebase.database.GenericTypeIndicator) – Mehmet K Feb 07 '17 at 12:40
1

The most likely answer is that the items stored in the database are objects with a public property, not basic strings or other base data types.

It's hard to know unless you can show what is getting put into the database.

For example, if you have a an object

class Item {
  private String text;
  public String getText();
  public void setText(String);
}

then you'll likely get out a map with a single key "text" and the corresponding value from getText()

If you have an item stored which has an array of strings

class Example {
  private list<String> items;
  public String getItem(int);
  public int getItemCount()
}

then your snapshot might contain a map with a key "item" and the value of that might be the list of strings that you're expecting.

have a Google of Java bean conventions it might help.

Chunko
  • 352
  • 1
  • 8
0

val arr = ArrayList(hashmap.values)

  • 1
    It looks like you have not yet taken the [tour] nor visited the [help]. Answers containing a single line of code are considered poor quality and may be down-voted or deleted. Especially since the code you posted does not compile. (I am assuming that it is Java code.) Maybe you could explain what `hashmap.values()` returns and why that value can be passed as a parameter to constructor of class `ArrayList`. – Abra Aug 27 '23 at 11:00