这是我的第一个stackoverflow问题。我已经对此进行了很多搜索。在Hashsets,Treesets,LinkedHashSets,Collections,Stacks(不赞成使用Stack类吗?)……我意识到我可以只使用SQLite,但目前我正想避免这种情况。
I'm working on an app in Android Studio. The app deals with people, listing them and contacting them in different ways. App users can maintain and control three types of lists: recently contacted, blocked, and favorites. These lists are saved as string sets in shared preferences so they survive the app being closed and reopened. The individual strings act as primary keys when the lists are populated using an online database. I am most concerned with the "recently contacted" list because the order of this list matters.
The problem is that as far as I understand, when I declare a string set it is as follows:
Set<String> faveArray = new LinkedHashSet<String>;
As I understand I can only use HashSet, LinkedHashSet, or TreeSet on the right hand side.
Since I used LinkedHashset, I was expecting that when I reopen the app and pull the data back out of sharedpreferences, that the strings would be pulled out starting with the most recently added (LIFO / stack), and therefore when I populate a listview, they will show with the "most recently contacted" person at the top of the list and so on... or at least I was expecting to have some kind of predictable order/behavior that I can work with.
So....... I've attached my code for my shared preferences I/O class.
From my main app, I do something like:
static SharedPrefUTIL sharedPrefUTIL;
sharedPrefUTIL = new SharedPrefUTIL(this);
sharedPrefUTIL.addRecent("derp");
sharedPrefUTIL.addRecent("nerp");
sharedPrefUTIL.addRecent("gerp");
sharedPrefUTIL.addRecent("herp");
At this point, the code
Log.i(TAG, set + " committed to " + key);
in the commit() method of class SharedPrefUTIL Logs:
" [derp, nerp, gerp, herp] committed to recentArray "
Bur after closing and reopening the app, if we perform:
sharedPrefUTIL.toastContents("R");
The result is seemingly random order. <<<< that is my problem.
任何帮助,不胜感激。
package com.secretsoft.booberbunz;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.widget.Toast;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Queue;
import java.util.Set;
import java.util.TreeSet;
/**
* Created by Programming on 2/22/2016.
*/
public class SharedPrefUTIL {
protected static final String TAG = "CXX SharedPrefUTIL";
Context context;
SharedPreferences sharedPreferences;
Set<String> faveArray;
Set<String> blockArray;
Set<String> recentArray;
public static final Set<String> DEFAULT = new HashSet<String>(Arrays.asList("empty"));
public SharedPrefUTIL(Context context){
this.context = context;
// load shared prefs into static arrays (new objects to prevent problems)
sharedPreferences = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
recentArray = new LinkedHashSet<String>(sharedPreferences.getStringSet("recentArray",DEFAULT));
blockArray = new LinkedHashSet<String>(sharedPreferences.getStringSet("blockArray",DEFAULT));
faveArray = new LinkedHashSet<String>(sharedPreferences.getStringSet("faveArray",DEFAULT));
Log.i(TAG, "SharedPrefUTIL instance created");
if (recentArray.contains("empty")) {
recentArray.clear();
Log.i(TAG, "recentArray contains the string -empty- and was cleared");
}
if (blockArray.contains("empty")) {
blockArray.clear();
Log.i(TAG, "blockArray contains the string -empty- and was cleared");
}
if (faveArray.contains("empty")) {
faveArray.clear();
Log.i(TAG, "faveArray contains the string -empty- and was cleared");
}
}
public void toastLength(String type){
if (type == "R"){
String temp = type + " array is this long: " + recentArray.size();
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, temp);
}
else if (type == "B"){
String temp = type + " array is this long: " + blockArray.size();
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, temp);
}
else if (type == "F"){
String temp = type + " array is this long: " + faveArray.size();
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, temp);
}
else {
Log.i(TAG, "invalid type param given to toastLength()");
}
}
public void toastContents(String type){
if (type == "R"){
for (String temp : recentArray) {
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, "recentArray contains: " + temp);
}
}
else if (type == "B"){
for (String temp : blockArray) {
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, "blockArray contains: " + temp);
}
}
else if (type == "F"){
for (String temp : faveArray) {
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, "faveArray contains: " + temp);
}
}
else {
Log.i(TAG, "invalid type param given to toastContents()");
}
}
public void clearList(String type){
if (type == "R"){
recentArray.clear();
commit("recentArray", recentArray);
Toast.makeText(context,"recent list has been cleared.", Toast.LENGTH_LONG);
}
else if (type == "B"){
blockArray.clear();
commit("blockArray", blockArray);
Toast.makeText(context,"blacklist has been cleared.", Toast.LENGTH_LONG);
}
else if (type == "F"){
faveArray.clear();
commit("faveArray", faveArray);
Toast.makeText(context,"favorites have been cleared.", Toast.LENGTH_LONG);
}
else {
Log.i(TAG, "invalid type param given to clearList()");
}
}
public void addRecent(String newRecent){
recentArray.add(newRecent);
commit("recentArray", recentArray);
Log.i(TAG, newRecent + " added to recentArray");
}
public void addBlocked(String newBlocked, String nick){
blockArray.add(newBlocked);
commit("blockArray", blockArray);
Toast.makeText(context, nick + " has been blacklisted!", Toast.LENGTH_SHORT);
}
public void remBlocked(String remBlocked, String nick){
blockArray.remove(remBlocked);
commit("blockArray", blockArray);
Toast.makeText(context, nick + " has been unblocked.", Toast.LENGTH_SHORT);
}
public void addFave(String newFave, String nick){
faveArray.add(newFave);
commit("faveArray", faveArray);
Toast.makeText(context, nick + " added to favorites!", Toast.LENGTH_SHORT);
}
public void remFave(String remFave, String nick){
faveArray.remove(remFave);
commit("faveArray", faveArray);
Toast.makeText(context, nick + " removed from favorites.", Toast.LENGTH_SHORT);
}
public void commit(String key, Set<String> set){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putStringSet(key,set);
editor.commit();
Log.i(TAG, set + " committed to " + key);
}
}
不幸的是,您只是发现了的局限SharedPreferences
。
使用有序哈希时,调用时不会按顺序加载它们getStringSet
。
我发现执行此操作最快,最简单的方法是将数组转换为有序的文本,然后将其保存到SharedPreferences中。Android随附了JSONArray
可以执行此操作的对象。
http://developer.android.com/reference/org/json/JSONArray.html
以下是一些伪代码,可以满足您的要求:
public void saveOrderedCollection(Collection collection, String key){
JSONArray jsonArray = new JSONArray(collection);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, jsonArray.toString());
editor.commit();
}
public Collection loadOrderedCollection(String key){
ArrayList arrayList = new ArrayList;
SharedPreferences.Editor editor = sharedPreferences.edit();
JSONArray jsonArray = new JSONArray(editor.getString(key, "[]"));
for (int i = 0; i < jsonArray.length(); i++) {
arrayList.put(jsonArray.get(i));
}
return arrayList;
}
这是我曾经做过的其他一些文章:
谢谢!我以为这可能是唯一的解决方案。我对JSON很熟悉,因为这就是我从在线数据库中获取数据的方式……我只是在想,因为他们增加了以共享首选项存储集的功能,这是有原因的,例如,它比JSON更有效。
当您使用它时,也许还可以修复字符串比较?只是一个想法。