Reputation: 1137
I've the following sample code. The application is installed successfully at first time. However, it throws an error on reinstalling.
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>());
}
}
I've pasted the error produced on reinstalling the application below.
Caused by: java.lang.ClassCastException: java.util.HashSet cannot be cast to java.util.LinkedHashSet at com.example.test.MainActivity.onCreate(MainActivity.java:12)
I want to understand why a saved LinkedHashSet
can not be casted back to LinkedHashSet
. And why is it automaically being converted to HashSet
by Android?
Upvotes: 2
Views: 4117
Reputation: 14226
Change your code to use a basic 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>());
Side note: Keep in mind that SharedPreferences.getStringSet()
is available in API11+ only.
The reason why your Set
is converted to a HashSet
can be found in 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;
}
}
Upvotes: 1
Reputation: 2867
@Ibungo, I think you've misunderstood what SharedPreferences
do.
You can NOT ask the prefs to save a LinkedHashSet
set - you can only ask it to save a general Set
. And in return you can get a general Set
after that. There are no guarantees that it'll return the same set implementation as yours.
The preferences are just iterating over the set of items you gave them and writing them to the XML store for your application. Thus when you ask for those items it is reading from the XML and creating a new Set - HashSet
since it is the most commonly used one.
The only reason you might want a LinkedHashSet
, I can think of, is if you want to preserve the insertion order. If this is the case, you might try converting your collection to ArrayList and store it - there is an example here. Alternatively you could save your data to a JSONArray
and store it as a String
.
Upvotes: 8