SharedPreferences - CastException:无法将HashSet强制转换为TreeSet

时间:2015-08-03 05:42:32

标签: android sharedpreferences classcastexception

我正在尝试使用以下代码将TreeSet存储在SharedPreferences中:

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

然而,当我尝试访问TreeSet时,我收到了投射错误,就好像这个集合被声明为HashSet

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

我无法解决这个问题。另外,当我开始编写这部分时,我将 chemicalValuesSet 设置为HashSet并且没有任何问题地进行检索,之后我决定使用TreeSet s。这就是我尝试清理并重新启动项目的原因,但仍然存在同样的问题。

但是,如果我只是将类型更改为HashSet 在我检索这个集合的部分,它没有抱怨。

3 个答案:

答案 0 :(得分:3)

您只是对SharedPreferences及其编辑器的工作方式做出错误的假设。 API永远不会保证调用getStringSet()时获得的Set与调用putStringSet()时存储的Set相同,甚至是相同的实现。它说的是你可以传递一个Set,并且你可以得到一个Set。

如果API文档说它返回一个Set,你不应该假设它返回一个TreeSet或一个HashSet。只是它正在返回一个Set。如果您绝对需要TreeSet,则创建一个TreeSet并将项目从返回的Set复制到TreeSet。

答案 1 :(得分:0)

您无法立即将HashSet强制转换为TreeSet。 相反,您可以执行以下任一操作将HashSet中的所有项目添加到TreeSet中,但请记住,添加到TreeSet中的项目将自动排序。

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

// 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);

答案 2 :(得分:0)

实际上,返回的集合是一个哈希集:

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

您可以在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;
    }
}

你也可以得到这样的集合类型:

    chemicalValues.getClass().getSimpleName()

HashSet和TreeSet不能互相解释。 希望这可以帮到你。