在首选项中保存和访问后,ArrayList将变为洗牌

时间:2014-01-21 02:18:28

标签: android listview arraylist shuffle

大家好,我最近遇到了一个我无法理解的非常奇怪的问题。我尝试了一些解决办法,但无济于事。

基本上如标题所示,我通过首选项保存了一个ArrayList,但每当我访问ArrayList时,它都会被重新洗牌。

我将它绘制到ListView,如果我有ListView看起来像:

1

2

3

4

5

6

它会回来看起来像

3

2

1

6

5

4

这是onPause和onResume

的代码
 ArrayList<String> todoItems = new ArrayList<String>();

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    SharedPreferences prefs =           
PreferenceManager.getDefaultSharedPreferences(getBaseContext());
    SharedPreferences.Editor edit = prefs.edit();
    edit.putStringSet("TODOITEMS", new HashSet<String>(todoItems));
    edit.commit();
    super.onPause();
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    ArrayList<String> returnedItems = new ArrayList<String>  
 (PreferenceManager.getDefaultSharedPreferences
 (getBaseContext()).getStringSet("TODOITEMS",     
  new HashSet<String>()));
    todoItems.clear();
    for(int i =0; i < returnedItems.size(); i++){
        todoItems.add(returnedItems.get(i));
    }
    aa.notifyDataSetChanged();

  super.onResume();
 }

4 个答案:

答案 0 :(得分:1)

我认为这是因为您将数组保存到HashSet。

根据documentation

  

它不保证集合的迭代顺序;特别是,它不保证订单会随着时间的推移保持不变。

如果要保存已排序的列表,建议您使用SQLiteDatabase。 要么 您可以在从共享首选项中检索列表时对列表进行排序。如果列表非常大,这并不好。

Collections.sort(returnedItems);

答案 1 :(得分:1)

这是因为您使用HashSet来存储值。 HashSet并不保证订单会得到维护。

您应该使用TreeSet代替

结帐Hashset vs Treeset

答案 2 :(得分:1)

您实际上并未保存todoItems ArrayList并加载它。您将todoItems ArrayList转换为HashSet,保存它,然后再次加载并重新构造ArrayList。

在从ArrayList到HashSet的转换中,不维护订单。查看以下两者之间差异的答案:What is the difference between Set and List?

答案 3 :(得分:0)

如前两个答案所述,HashSet不保证保留顺序。

一种可能的解决方案是首先将ArrayList序列化为String,使用putString()保存,然后使用getString()加载它并对其进行反序列化。

查看此答案的后半部分,了解如何执行此操作:Save ArrayList to SharedPreferences