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

Boo*_*unz 5 java android shared preferences lifo

这是我的第一个stackoverflow问题.我在这上面做了很多谷歌搜索.在Hashsets,Treesets,LinkedHashSets,Collections,Stacks(Stack类被弃用?)......我意识到我可以使用SQLite,但我暂时试图避免这种情况.

我正在使用Android Studio中的应用程序.该应用与人打交道,列出并以不同方式与他们联系.应用用户可以维护和控制三种类型的列表:最近联系,阻止和收藏.这些列表在共享首选项中保存为字符串集,因此它们可以在应用程序关闭和重新打开后继续存在.当使用在线数据库填充列表时,各个字符串充当主键.我最关心的是"最近联系的"列表,因为这个列表的顺序很重要.

问题是,据我所知,当我声明一个字符串集时,它如下:

Set<String> faveArray = new LinkedHashSet<String>;
Run Code Online (Sandbox Code Playgroud)

据我所知,我只能在右侧使用HashSet,LinkedHashSet或TreeSet.

因为我使用了LinkedHashset,所以当我重新打开应用程序并从共享偏好中拉出数据时,我会期望从最近添加的(LIFO /堆栈)开始拉出字符串,因此当我填充listview时,他们将与列表顶部的"最近联系"人员展示等等......或者至少我期待有某种可预测的顺序/行为,我可以使用.

所以.......我已经为我的共享首选项I/O类附加了我的代码.

从我的主应用程序,我做了类似的事情:

static SharedPrefUTIL sharedPrefUTIL;

sharedPrefUTIL = new SharedPrefUTIL(this);

sharedPrefUTIL.addRecent("derp");
sharedPrefUTIL.addRecent("nerp");
sharedPrefUTIL.addRecent("gerp");
sharedPrefUTIL.addRecent("herp");
Run Code Online (Sandbox Code Playgroud)

此时,代码

Log.i(TAG, set + " committed to " + key);
Run Code Online (Sandbox Code Playgroud)

在类SharedPrefUTIL日志的commit()方法中:

"[derp,nerp,gerp,herp]致力于最近的阵营"

关闭并重新打开应用程序后,如果我们执行:

sharedPrefUTIL.toastContents("R");
Run Code Online (Sandbox Code Playgroud)

结果似乎是随机顺序.<<<<这是我的问题.

任何帮助非常感谢.

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);
}




}
Run Code Online (Sandbox Code Playgroud)

小智 11

不幸的是,你只是发现了一个限制SharedPreferences.

当您使用orderd哈希时,它不会在您调用时加载它们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;
}
Run Code Online (Sandbox Code Playgroud)

以下是我过去做过的其他一些帖子:

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

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