我正在尝试使用以下代码将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
在我检索这个集合的部分,它没有抱怨。
答案 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不能互相解释。 希望这可以帮到你。