温馨提示:本文翻译自stackoverflow.com,查看原文请点击:java - Can't Control Order of String Set in Shared Preferences
android java preferences shared lifo

java - 无法控制共享首选项中字符串集的顺序

发布于 2020-03-27 11:52:19

这是我的第一个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);
}




}

查看更多

查看更多

提问者
Boober Bunz
被浏览
18
29 2018-10-18 01:43

不幸的是,您只是发现了的局限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;
}

这是我曾经做过的其他一些文章:

是否可以在Android上向SharedPreferences添加数组或对象

在共享首选项中如何在Android应用程序中存储字符串数组