Android
SharedPreferences
ArrayList
Data Storage
Java

Save ArrayList to SharedPreferences

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

SharedPreferences stores primitive values and strings, not arbitrary Java or Kotlin collections. So if you want to save an ArrayList, you need to convert it into something SharedPreferences can persist, usually JSON or, in limited cases, a Set<String>. The important design question is whether the list is really lightweight settings data or whether it should live in a proper database such as Room.

What SharedPreferences Can Store Directly

SharedPreferences supports values such as:

  • 'String'
  • 'int'
  • 'long'
  • 'float'
  • 'boolean'
  • 'Set<String>'

That means an ArrayList is never stored directly. It must be serialized first.

The Common Solution: JSON with Gson

For most simple lists, JSON is the cleanest approach.

kotlin
1import android.content.Context
2import com.google.gson.Gson
3import com.google.gson.reflect.TypeToken
4
5class PrefStore(context: Context) {
6    private val prefs = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
7    private val gson = Gson()
8
9    fun saveNames(names: ArrayList<String>) {
10        val json = gson.toJson(names)
11        prefs.edit().putString("names_key", json).apply()
12    }
13
14    fun loadNames(): ArrayList<String> {
15        val json = prefs.getString("names_key", null) ?: return arrayListOf()
16        val type = object : TypeToken<ArrayList<String>>() {}.type
17        return gson.fromJson(json, type)
18    }
19}

This works for strings, numbers, and custom objects as long as Gson can serialize them.

Saving Custom Object Lists

The same pattern works for more complex items.

kotlin
1data class Task(val id: Int, val title: String)
2
3fun saveTasks(tasks: ArrayList<Task>, prefs: android.content.SharedPreferences) {
4    val json = Gson().toJson(tasks)
5    prefs.edit().putString("tasks", json).apply()
6}
7
8fun loadTasks(prefs: android.content.SharedPreferences): ArrayList<Task> {
9    val json = prefs.getString("tasks", null) ?: return arrayListOf()
10    val type = object : TypeToken<ArrayList<Task>>() {}.type
11    return Gson().fromJson(json, type)
12}

This is fine for small settings-style payloads. It is not a great fit for large, frequently updated domain data.

putStringSet Is More Limited Than It Looks

If the list is only strings, you might consider putStringSet. That can work, but it has a major limitation: sets do not preserve order.

kotlin
val values = setOf("red", "green", "blue")
prefs.edit().putStringSet("colors", values).apply()

If order matters, ArrayList to JSON is safer. Also, putStringSet only helps for strings, not custom objects.

Handle Missing or Bad Data Gracefully

Stored JSON can become invalid after app upgrades or model changes. Deserialization should fail safely.

kotlin
1fun safeLoadTasks(prefs: android.content.SharedPreferences): ArrayList<Task> {
2    return try {
3        loadTasks(prefs)
4    } catch (ex: Exception) {
5        arrayListOf()
6    }
7}

This prevents a corrupted preference value from crashing the app at startup.

Know When to Move to Room or DataStore

A useful rule is:

  • use SharedPreferences for compact settings
  • use DataStore for modern key-value preferences
  • use Room for structured, queryable, evolving data

If the list is large, relational, or frequently modified, SharedPreferences is the wrong storage model even if JSON serialization technically works.

Java Version

If the codebase is Java rather than Kotlin, the same Gson strategy applies.

java
1import android.content.SharedPreferences;
2import com.google.gson.Gson;
3import com.google.gson.reflect.TypeToken;
4import java.lang.reflect.Type;
5import java.util.ArrayList;
6
7public class NamePrefs {
8    private final SharedPreferences prefs;
9    private final Gson gson = new Gson();
10
11    public NamePrefs(SharedPreferences prefs) {
12        this.prefs = prefs;
13    }
14
15    public void save(ArrayList<String> names) {
16        prefs.edit().putString("names", gson.toJson(names)).apply();
17    }
18
19    public ArrayList<String> load() {
20        String raw = prefs.getString("names", null);
21        if (raw == null) return new ArrayList<>();
22        Type type = new TypeToken<ArrayList<String>>() {}.getType();
23        return gson.fromJson(raw, type);
24    }
25}

Common Pitfalls

  • Trying to store an ArrayList directly without serializing it first.
  • Using putStringSet when list order matters.
  • Saving large or frequently updated lists in preferences instead of using a database.
  • Forgetting TypeToken when deserializing generic collection types.
  • Assuming old JSON payloads will keep parsing forever after the model class changes.

Summary

  • 'SharedPreferences cannot store an ArrayList directly.'
  • JSON serialization with Gson is the most common lightweight solution.
  • 'putStringSet is only useful for unordered string collections.'
  • Add safe fallback behavior for corrupted or old serialized data.
  • Move to DataStore or Room when the data stops looking like simple preferences.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.