2

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

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。为什么它会自动HashSet被Android转换为?

4

2 回答 2

8

@Ibungo,我认为您误解了SharedPreferences该做什么。您不能要求首选项保存一LinkedHashSet组 - 您只能要求它保存一个将军Set。作为回报,您可以Set在那之后获得一位将军。不能保证它会返回与您相同的集合实现。

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

我能想到的你可能想要 a 的唯一原因LinkedHashSet是,如果你想保留插入顺序。如果是这种情况,您可以尝试将您的集合转换为 ArrayList 并存储它 - 这里有一个示例。或者,您可以将数据保存到 aJSONArray并将其存储为String.

于 2013-09-13T07:05:41.270 回答
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你转换为a的原因HashSet可以在Android的源码中找到:

public Editor putStringSet(String key, Set<String> values) {
    synchronized (this) {
        mModified.put(key,
            (values == null) ? null : new HashSet<String>(values));
        return this;
    }
}
于 2013-09-13T06:08:07.223 回答