【问题标题】:Android ArrayList<String> stored not restored back to its saved sorted orderAndroid ArrayList<String> 存储未恢复到其保存的排序顺序
【发布时间】:2020-04-06 16:01:15
【问题描述】:
  1. 我有一个 myArrayList,它将按其保存的排序顺序存储和恢复。但是代码并没有这样做。为什么?

    ArrayList<String> myArrayList
    
    // save:
            SharedPreferences prefs = PreferenceManager
            .getDefaultSharedPreferences(getBaseContext());
    SharedPreferences.Editor edit;
    edit = prefs.edit();
    edit.putStringSet("mydata", new LinkedHashSet<String>(myArrayList));
    edit.commit();
    
        // read:
    myArrayList = new ArrayList<String>(PreferenceManager
            .getDefaultSharedPreferences(getBaseContext()).getStringSet(
                    "mydata", new LinkedHashSet<String>()));
    adapterAppList = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, android.R.id.text1,
            myArrayList);
    
  2. 有没有更好的方法可以存储 myArrayList 的值并恢复到原来保存的排序顺序?

【问题讨论】:

  • 您无法在 SharedPreferences 中保存对象。您可以将对象转换为字符串,然后将其保存并在获取时将字符串转换为对象。
  • 不可能:“无法在 SharedPreferences 中保存对象”,因为我可以取回数据,但不是按照原始顺序
  • 你可以用gson序列化arrayList之类的字符串
  • SharedPreferences 将其作为普通的Set 处理,它本质上没有顺序。它不关心你使用什么实现,但即使你使用的是有序的Set,它也不是。

标签: android sorting arraylist sharedpreferences store


【解决方案1】:

HashSet 不保留订单,它是为了最快找到它。
您可以将列表转换为 json 并保存为字符串。
当您需要它时,您可以将其从 json 转换为 ArrayList 并保持排序。
示例:

String listAsString = new Gson().toJson(arrayList); //list to string
List<String> arrayList = Arrays.asList(new Gson().fromJson(listAsString,String[].class)) //string to list

不要忘记将库添加到 build.gradle:

dependencies {
  implementation 'com.google.code.gson:gson:2.8.6'
}

【讨论】:

    【解决方案2】:

    你可以像字符串一样序列化arrayList:

    1 与 gson

    public ArrayList<String> convertToArrayList(String json) {
        if (TextUtils.isEmpty(json)){
            return null; // or new ArrayList<>()
        }
        Type type = new TypeToken<ArrayList<String>>(){}.getType();
        return new Gson().fromJson(json, type);
    }
    public String convertFromArrayList(ArrayList<String> list) {
        if (list == null){
            return null;
        }
        return new Gson().toJson(list);
    }
    

    2 没有 gson

    public ArrayList<String> convertToArrayList(String st) {
        if (!TextUtils.isEmpty(st)){
            String[] str = st.split(",");
            if (str.length > 0){
                return new ArrayList<>(Arrays.asList(str));
            }
        }
        return null;
    }
    public String convertFromArrayList(ArrayList<String> list) {
        if (list!=null && !list.isEmpty()){
            return TextUtils.join(",", list);
        }
        return null;
    }
    

    【讨论】:

    • convertToArrayList() 如果我传入一个空字符串会中断
    • 当我调用 convertFromArrayList() 时,出现以下错误:(我在 Eclipse 上使用 jar)java.lang.NoClassDefFoundError:解析失败:Lcom/google/gson/Gson;
    • 你需要将Gson lib添加到你的项目repo1.maven.org/maven2/com/google/code/gson/gson/2.8.2
    • 修复了崩溃,因为我使用的是 2.6.2 的副本
    • 当我调用convertFromArrayList(), Gson().toJson(list) 仍然崩溃list 的值为[a1, a2, a3] 没有错误显示。
    【解决方案3】:

    是的,你是对的,订单没有存储在字符串集中,因为它是一个集合(duh)。 当我遇到这个问题时,我得到了序列化解决方案,您可以在其中序列化您的字符串。

    只有在你还没有阅读过序列化的时候才阅读这篇文章,否则请继续阅读我的 hack

    为了按顺序存储数组项,我们可以将数组序列化为单个字符串(通过创建一个新类 ObjectSerializer (从 - www.androiddevcourse.com/objectserializer.html 复制代码,替换除包名))

    在共享首选项中输入数据:

    第 38 行的其余代码 -

    将下一个参数设置为这样,这样如果没有检索到数据,它将返回空数组(我们不能放空字符串,因为容器/变量是数组而不是字符串)

    来我的 Hack :-

    通过在每个项目之间添加一些符号将数组的内容合并为单个字符串,然后在检索时使用该符号将其拆分。 如果您担心拆分,只需查找“在 java 中拆分字符串”。

    [注意:如果您的数组的内容是原始类型,如字符串、int、float 等,这可以正常工作。它适用于具有自己结构的复杂数组,假设是电话簿,但是合并和拆分会变得有点复杂。 ]

    PS:我是android新手,所以不知道它是否是一个好的hack,所以如果你找到更好的hack,请告诉我。

    【讨论】:

      猜你喜欢
      • 2021-12-30
      • 1970-01-01
      • 2015-09-26
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 2015-04-18
      相关资源
      最近更新 更多