set.addAll(myArrayList) 不按相同顺序添加列表项

set.addAll(myArrayList) doesn't add the items of list in the same order

无法理解为什么 set.addAll 会添加我的列表并调换顺序。 (我的集合仍然被声明为 LinkedHashSet)

该代码是关于从 SharedPreferences 获取一个 Set-List,将其转换为 ArrayList,将一个项目添加到列表,然后将整个列表添加到 Set。

代码看起来像这样:

 Set<String> set = new LinkedHashSet<String>();
 List<String> stringList = new ArrayList<String>();

 ///

 set = getSharedPrefSet("mySet");
 stringList = new ArrayList<String>(set);
 stringList.add(message);
 set.addAll(stringList);  //this messes up my order
 saveSharedPrefSet("mySet", set);

前两个字符串正确添加(正如我调试的那样)但第三个与第二个交换位置。

输出:

getSharedPrefSet 函数:

Set getSharedPrefSet (String key) {
    sharedPrefs = this.getSharedPreferences("myPreferences", Context.MODE_PRIVATE);

    return sharedPrefs.getStringSet(key, null);
}

解决方法

可以在 How can write code to make sharedpreferences for array in android?

找到一个解决方案

我知道你的问题是什么!即使您将 set 初始化为应该保留项目顺序的 LinkedHashSet,请查看此行,之后:

set = getSharedPrefSet("mySet");

现在,我在这里看不到 getSharedPrefSet 方法的实现,但是查看您提供的屏幕截图我可以看到 set 现在是 HashSet。因此,该方法必须返回 HashSet,因此您丢失了所需的顺序,因为 HashSet 不保留它。

来自 LinkedHashSet 的文档:

Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries.

所以你需要做的是在这里采取不同的方法,因为无论你用什么初始化你的 set 变量,它都会被任何 getSharedPrefSet 方法覆盖 returns(因此初始化无论如何都已过时)。找到另一种解决方法,sharedPrefs.getStringSet 显然 returns 一个正常的 HashSet.