Может кто-нибудь объяснить, как SharedPreferences хранит набор строк

Я пытался сохранить список имен в общих настройках и хотел использовать SharedPreferences putStringSet чтобы мне не понадобилось несколько пар ключ-значение.
Я знаю, что обычный HashSet не гарантирует порядок итерации, поэтому я использовал LinkedHashSet для поддержания порядка итераций в качестве порядка вставки и сохранения его для общих настроек.

При получении одного и того же набора строк я также использовал LinkedHashSet но порядок был не таким, как когда он был первоначально вставлен.

Я решил проблему, просто сохранив имена в разделенной запятыми строкой, а затем разобрал это, так что это не мой вопрос.

Я хотел бы знать, что SharedPreferences делает для набора строк, чтобы он не поддерживал правильный порядок (по крайней мере, не тот, который я хочу)?

Чтобы коротко ответить на ваш вопрос, он не связывает ваш связанный хеш-набор, создавая простой HashSet из ваших значений … с этого момента – без ссылок на порядок.

Из исходного кода:

 public Editor putStringSet(String key, Set<String> values) { synchronized (this) { mModified.put(key, (values == null) ? null : new HashSet<String>(values)); return this; } } 

Вот почему, как и вы, если вы хотите сохранить порядок, который вам нужно сохранить как строку с разделителями (вы использовали кому), а затем разделите разделитель, чтобы получить массив.

Существует один трюк, который я часто использую JSON . Очень легко преобразовать сложные объекты в JSON и сохранить их как простые строки в SharedPreferences .
Для этого вам просто нужно несколько строк кода.

Взгляните на популярные библиотеки JSON такие как GSON и Jackson

Вот класс util, который вы можете использовать для преобразования объекта в JSON и наоборот.

 public class JsonUtils { private JsonUtils() { } public static String convertObjectToJSONString(Object object) { ObjectMapper objectMapper = new ObjectMapper(); String jsonObject = ""; try { jsonObject = objectMapper.writeValueAsString(object); } catch (JsonProcessingException e) { e.printStackTrace(); } return jsonObject; } public static<T> T parseObjectFromString(String json,Class<T> objectClass) { ObjectMapper objectMapper = new ObjectMapper(); T object = null; try { object = objectMapper.readValue(json, objectClass); } catch (IOException e) { e.printStackTrace(); } return object; } } 

Если вы все еще хотите сохранить String Set в общую настройку, это не то, что вы не должны пропустить, это удалить старый набор и вставить новый.

 Set<String> stringSet = sharedPrefs.getStringSet("set-key", new HashSet<String>()); stringSet.add("Hello World"); Editor edit = sharedPrefs.edit(); edit.remove("set-key"); edit.apply(); edit.putStringSet("set-key", stringSet); 

Также вы можете просто использовать простой старый объект ObjectOutputStream для преобразования объекта в byte[] или String а затем сохранить его. Но, как многие люди заметили, это выходит за рамки этого вопроса.