SharedPreferences - CastException: HashSet cannot be passed to TreeSet

I am trying to save TreeSet

in SharedPreferences

using the following code:

        Set<String> chemicalValuesSet = new TreeSet<>();
        chemicalValuesSet.add("id: " + checkForNull(jsonChemicalValues.getString("id")));
        editor.putStringSet(SP_CHEMICAL_VALUES, chemicalValuesSet);
        editor.apply();

      

However, when I try to access this TreeSet

, I get a casting error as if this set is declared as HashSet

.

    SharedPreferences sharedPreferences =
            getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
    TreeSet<String> chemicalValues =
            (TreeSet<String>) sharedPreferences.getStringSet(SP_CHEMICAL_VALUES, null);

      

I have no reason to solve this problem. Also, when I started writing this part, I set the chemicalValuesSet as HashSet

it was getting, and then decided to go with TreeSet

s. This is why I tried cleaning and restarting the project, but still the same problems persist.

However, if I just change the type to HashSet

in the part where I retrieve this set, it works without complaint.

+3


source to share


3 answers


You are just making false assumptions about how SharedPreferences and its editor work. The API never guarantees that the set you get when called getStringSet()

is the same or even the same implementation as the one that is stored when called putStringSet()

. All it says is that you can pass a Set and you can get a Set.



If the API documentation says it returns a Set, then you shouldn't assume that it returns a TreeSet or HashSet. Just that it returns a set. If you absolutely need a TreeSet, create one and copy the elements from the returned Set to the TreeSet.

+3


source


You cannot immediately pass a HashSet to a TreeSet. Instead, you can do one of the following to add all the elements in the HashSet to the TreeSet, but keep in mind, the elements added to the TreeSet will be sorted automatically.

// Passing the collection HashSet to TreeSet
HashSet<String> hashSet = sharedPreferences.getStringSet(SP_CHEMICAL_VALUES, null);
TreeSet<String> chemicalValues = new TreeSet<String>(hashSet);

      



or

// Adding all the values of the HashSet to TreeSet using addAll() API
// This will help to retain the values of TreeSet (if any)
TreeSet<String> chemicalValues = new TreeSet<String>();
...
HashSet<String> hashSet = sharedPreferences.getStringSet(SP_CHEMICAL_VALUES, null);
chemicalValues.addAll(hashSet);

      

0


source


In fact, the returned set is a hash set:

 TreeSet<String> chemicalValues =
        (TreeSet<String>) sharedPreferences.getStringSet(SP_CHEMICAL_VALUES, null);

      

You can check this output in your source code at SharedPreferencesImpl.java

public Set<String> getStringSet(String key, Set<String> defValues) {
    synchronized (this) {
        awaitLoadedLocked();
        Set<String> v = (Set<String>) mMap.get(key);
        return v != null ? v : defValues;
    }
}

      

And you can also get the set type like this:

    chemicalValues.getClass().getSimpleName()

      

HashSet and TreeSet cannot be interpreted to each other. Hope this helps you.

0


source







All Articles