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

SharedPreferences - CastException: HashSet cannot be cast to TreeSet

我正在尝试使用以下代码将 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 并且检索没有任何问题,之后我决定使用 TreeSets。这就是为什么我尝试清理并重新启动项目,但仍然存在同样的问题。

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

您不能立即将 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);

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

如果 API 文档说它 returns 是一个 Set,您不应该假设它返回的是 TreeSet 或 HashSet。只有它返回一个集合。如果您确实需要 TreeSet,则创建一个并将返回的 Set 中的项目复制到 TreeSet。

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

 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 不能相互解释。 希望对您有所帮助。