Android HashSet无法强制转换为LinkedHashSet

时间:2013-09-13 06:05:39

标签: java android sharedpreferences hashset linkedhashset

我有以下示例代码。应用程序第一次安装成功。 但是,它会在重新安装时抛出错误。

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LinkedHashSet<String> planets = new LinkedHashSet<String>();
        planets.add("Earth");
        SharedPreferences prefs = getPreferences(0);
        prefs.edit().putStringSet("planets", planets).commit();
        prefs = getPreferences(0);
        planets = (LinkedHashSet<String>) prefs.getStringSet("planets", new  LinkedHashSet<String>());
    }
}

我已粘贴重新安装以下应用程序时产生的错误。

Caused by: java.lang.ClassCastException: java.util.HashSet cannot be cast to java.util.LinkedHashSet at com.example.test.MainActivity.onCreate(MainActivity.java:12)

我想了解为何无法将已保存的LinkedHashSet投放回LinkedHashSet。为什么Android会自动将其转换为HashSet

2 个答案:

答案 0 :(得分:6)

@Ibungo,我认为你误解了SharedPreferences做了什么。 你不能要求prefs保存LinkedHashSet集 - 你只能要求它保存一般Set。作为回报,你可以在那之后获得一般Set。无法保证它将返回与您相同的集合实现。

首选项只是迭代您给出的项目集,并将它们写入应用程序的XML存储区。因此,当您要求提供这些项目时,它会从XML中读取并创建一个新的集合 - HashSet,因为它是最常用的集合。

我可以想到,您可能需要LinkedHashSet的唯一原因是您是否要保留广告订单。如果是这种情况,您可以尝试将集合转换为ArrayList并存储它 - 有一个示例here。或者,您可以将数据保存到JSONArray并将其存储为String

答案 1 :(得分:1)

更改您的代码以使用基本的HashSet

HashSet<String> planets = new LinkedHashSet<String>();
planets.add("Earth");
SharedPreferences prefs = getPreferences(0);
prefs.edit().putStringSet("planets", planets).commit();
prefs = getPreferences(0);
planets = prefs.getStringSet("planets", new  LinkedHashSet<String>());

附注:请注意,SharedPreferences.getStringSet()仅适用于API11 +。

Set转换为HashSet的原因可在Android's source code中找到:

public Editor putStringSet(String key, Set<String> values) {
    synchronized (this) {
        mModified.put(key,
            (values == null) ? null : new HashSet<String>(values));
        return this;
    }
}