How to save HashMap to Shared Preferences?

AndroidSharedpreferences

Android Problem Overview


How can I save a HashMap Object into Shared Preferences in Android?

Android Solutions


Solution 1 - Android

I use Gson to convert HashMap to String and then save it to SharedPrefs

private void hashmaptest()
{
    //create test hashmap
    HashMap<String, String> testHashMap = new HashMap<String, String>();
    testHashMap.put("key1", "value1");
    testHashMap.put("key2", "value2");
    
    //convert to string using gson
    Gson gson = new Gson();
    String hashMapString = gson.toJson(testHashMap);
    
    //save in shared prefs
    SharedPreferences prefs = getSharedPreferences("test", MODE_PRIVATE);
    prefs.edit().putString("hashString", hashMapString).apply();
    
    //get from shared prefs
    String storedHashMapString = prefs.getString("hashString", "oopsDintWork");
    java.lang.reflect.Type type = new TypeToken<HashMap<String, String>>(){}.getType();
    HashMap<String, String> testHashMap2 = gson.fromJson(storedHashMapString, type);
    
    //use values
    String toastString = testHashMap2.get("key1") + " | " + testHashMap2.get("key2");
    Toast.makeText(this, toastString, Toast.LENGTH_LONG).show();
}

Solution 2 - Android

I would not recommend writing complex objects into SharedPreference. Instead I would use ObjectOutputStream to write it to the internal memory.

File file = new File(getDir("data", MODE_PRIVATE), "map");    
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(map);
outputStream.flush();
outputStream.close();

Solution 3 - Android

private void saveMap(Map<String,Boolean> inputMap) {
	SharedPreferences pSharedPref = getApplicationContext().getSharedPreferences("MyVariables", Context.MODE_PRIVATE);
	if (pSharedPref != null){
		JSONObject jsonObject = new JSONObject(inputMap);
		String jsonString = jsonObject.toString();
		pSharedPref.edit()
			.remove("My_map")
			.putString("My_map", jsonString)
			.apply();
	}
}

private Map<String,Boolean> loadMap() {
	Map<String,Boolean> outputMap = new HashMap<>();
	SharedPreferences pSharedPref = getApplicationContext().getSharedPreferences("MyVariables", Context.MODE_PRIVATE);
	try {
		if (pSharedPref != null) {
			String jsonString = pSharedPref.getString("My_map", (new JSONObject()).toString());
			if (jsonString != null) {
				JSONObject jsonObject = new JSONObject(jsonString);
				Iterator<String> keysItr = jsonObject.keys();
				while (keysItr.hasNext()) {
					String key = keysItr.next();
					Boolean value = jsonObject.getBoolean(key); 
					outputMap.put(key, value);
				}
			}
		}
	} catch (JSONException e){
		e.printStackTrace();
	}
	return outputMap;
}

Solution 4 - Android

Map<String, String> aMap = new HashMap<String, String>();
aMap.put("key1", "val1");
aMap.put("key2", "val2");
aMap.put("Key3", "val3");

SharedPreferences keyValues = getContext().getSharedPreferences("Your_Shared_Prefs"), Context.MODE_PRIVATE);
SharedPreferences.Editor keyValuesEditor = keyValues.edit();

for (String s : aMap.keySet()) {
    keyValuesEditor.putString(s, aMap.get(s));
}

keyValuesEditor.commit();

Solution 5 - Android

As a spin off of Vinoj John Hosan's answer, I modified the answer to allow for more generic insertions, based on the key of the data, instead of a single key like "My_map".

In my implementation, MyApp is my Application override class, and MyApp.getInstance() acts to return the context.

public static final String USERDATA = "MyVariables";

private static void saveMap(String key, Map<String,String> inputMap){
    SharedPreferences pSharedPref = MyApp.getInstance().getSharedPreferences(USERDATA, Context.MODE_PRIVATE);
    if (pSharedPref != null){
        JSONObject jsonObject = new JSONObject(inputMap);
        String jsonString = jsonObject.toString();
        SharedPreferences.Editor editor = pSharedPref.edit();
        editor.remove(key).commit();
        editor.putString(key, jsonString);
        editor.commit();
    }
}

private static Map<String,String> loadMap(String key){
    Map<String,String> outputMap = new HashMap<String,String>();
    SharedPreferences pSharedPref = MyApp.getInstance().getSharedPreferences(USERDATA, Context.MODE_PRIVATE);
    try{
        if (pSharedPref != null){
            String jsonString = pSharedPref.getString(key, (new JSONObject()).toString());
            JSONObject jsonObject = new JSONObject(jsonString);
            Iterator<String> keysItr = jsonObject.keys();
            while(keysItr.hasNext()) {
                String k = keysItr.next();
                String v = (String) jsonObject.get(k);
                outputMap.put(k,v);
            }
        }
    }catch(Exception e){
        e.printStackTrace();
    }
    return outputMap;
}

Solution 6 - Android

map -> string

val jsonString: String  = Gson().toJson(map)
preferences.edit().putString("KEY_MAP_SAVE", jsonString).apply()

string -> map

val jsonString: String = preferences.getString("KEY_MAP_SAVE", JSONObject().toString())
val listType = object : TypeToken<Map<String, String>>() {}.type
return Gson().fromJson(jsonString, listType)

Solution 7 - Android

You could try using JSON instead.

For saving

try {
    HashMap<Integer, String> hash = new HashMap<>();
    JSONArray arr = new JSONArray();
    for(Integer index : hash.keySet()) {
        JSONObject json = new JSONObject();
        json.put("id", index);
        json.put("name", hash.get(index));
        arr.put(json);
    }
    getSharedPreferences(INSERT_YOUR_PREF).edit().putString("savedData", arr.toString()).apply();
} catch (JSONException exception) {
    // Do something with exception
}

For getting

try {
    String data = getSharedPreferences(INSERT_YOUR_PREF).getString("savedData");
    HashMap<Integer, String> hash = new HashMap<>();
    JSONArray arr = new JSONArray(data);
    for(int i = 0; i < arr.length(); i++) {
        JSONObject json = arr.getJSONObject(i);
        hash.put(json.getInt("id"), json.getString("name"));
    }
} catch (Exception e) {
    e.printStackTrace();
}

Solution 8 - Android

You can use this in a dedicated on shared prefs file (source: https://developer.android.com/reference/android/content/SharedPreferences.html):

> getAll > > added in API level 1 Map getAll () Retrieve all values from > the preferences. > > Note that you must not modify the collection returned by this method, > or alter any of its contents. The consistency of your stored data is > not guaranteed if you do. > > Returns Map Returns a map containing a list of pairs > key/value representing the preferences.

Solution 9 - Android

String converted = new Gson().toJson(map);
SharedPreferences sharedPreferences = getSharedPreferences("sharepref",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("yourkey",converted).commit();

Solution 10 - Android

The lazy way: storing each key directly in SharedPreferences

For the narrow use case when your map is only gonna have no more than a few dozen elements you can take advantage of the fact that SharedPreferences works pretty much like a map and simply store each entry under its own key:

Storing the map
Map<String, String> map = new HashMap<String, String>();
map.put("color", "red");
map.put("type", "fruit");
map.put("name", "Dinsdale");


SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// OR use a specific pref name
// context.getSharedPreferences("myMegaMap");

for (Map.Entry<String, String> entry : map.entrySet()) {
    prefs.edit().putString(entry.getKey(), entry.getValue());
}
Reading keys from the map
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// OR use a specific pref name
// context.getSharedPreferences("myMegaMap");
prefs.getString("color", "pampa");

In case where you use a custom preference name (i.e. context.getSharedPreferences("myMegaMap")) you can also get all keys with prefs.getAll()

> Your values can be of any type supported by SharedPreferences: String, int, long, float, boolean.

Solution 11 - Android

using File Stream

fun saveMap(inputMap: Map<Any, Any>, context: Context) {
    val fos: FileOutputStream = context.openFileOutput("map", Context.MODE_PRIVATE)
    val os = ObjectOutputStream(fos)
    os.writeObject(inputMap)
    os.close()
    fos.close()
}

fun loadMap(context: Context): MutableMap<Any, Any> {
    return try {
        val fos: FileInputStream = context.openFileInput("map")
        val os = ObjectInputStream(fos)
        val map: MutableMap<Any, Any> = os.readObject() as MutableMap<Any, Any>
        os.close()
        fos.close()
        map
    } catch (e: Exception) {
        mutableMapOf()
    }
}

fun deleteMap(context: Context): Boolean {
    val file: File = context.getFileStreamPath("map")
    return file.delete()
}

Usage Example:

var exampleMap: MutableMap<Any, Any> = mutableMapOf()
exampleMap["2"] = 1
saveMap(exampleMap, applicationContext) //save map

exampleMap = loadMap(applicationContext) //load map

Solution 12 - Android

You don't need to save HashMap to file as someone else suggested. It's very well easy to save a HashMap and to SharedPreference and load it from SharedPreference when needed. Here is how:
Assuming you have a

class T

and your hash map is:

HashMap<String, T>

which is saved after being converted to string like this:

       SharedPreferences sharedPref = getSharedPreferences(
            "MyPreference", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putString("MyHashMap", new Gson().toJson(mUsageStatsMap));
    editor.apply();

where mUsageStatsMap is defined as:

HashMap<String, T>
 

The following code will read the hash map from saved shared preference and correctly load back into mUsageStatsMap:

Gson gson = new Gson();
String json = sharedPref.getString("MyHashMap", "");
Type typeMyType = new TypeToken<HashMap<String, UsageStats>>(){}.getType();
HashMap<String, UsageStats> usageStatsMap = gson.fromJson(json, typeMyType);
mUsageStatsMap = usageStatsMap;  

The key is in Type typeMyType which is used in * gson.fromJson(json, typeMyType)* call. It made it possible to load the hash map instance correctly in Java.

Solution 13 - Android

I know its a little too late but i hope this could be helpfull to any one reading..

so what i do is

1) Create HashMapand add data like:-

HashMap hashmapobj = new HashMap();
  hashmapobj.put(1001, "I");
  hashmapobj.put(1002, "Love");
  hashmapobj.put(1003, "Java");

2) Write it to shareprefrences editor like :-

SharedPreferences sharedpreferences = getSharedPreferences(MyPREFERENCES,Context.MODE_PRIVATE);
    Editor editor = sharedpreferences.edit();
    editor.putStringSet("key", hashmapobj );
    editor.apply(); //Note: use commit if u wan to receive response from shp

3) Reading data like :- in a new class where you want it to be read

   HashMap hashmapobj_RECIVE = new HashMap();
     SharedPreferences sharedPreferences (MyPREFERENCES,Context.MODE_PRIVATE;
     //reading HashMap  from sharedPreferences to new empty HashMap  object
     hashmapobj_RECIVE = sharedpreferences.getStringSet("key", null);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjibysthomasView Question on Stackoverflow
Solution 1 - AndroidpenduDevView Answer on Stackoverflow
Solution 2 - AndroidKirill RakhmanView Answer on Stackoverflow
Solution 3 - AndroidVinoj John HosanView Answer on Stackoverflow
Solution 4 - AndroidhovanessyanView Answer on Stackoverflow
Solution 5 - AndroidKyle FalconerView Answer on Stackoverflow
Solution 6 - AndroidEvgen ButView Answer on Stackoverflow
Solution 7 - AndroidJonas BorggrenView Answer on Stackoverflow
Solution 8 - AndroidsiviView Answer on Stackoverflow
Solution 9 - Androiduser11022957View Answer on Stackoverflow
Solution 10 - AndroidccpizzaView Answer on Stackoverflow
Solution 11 - AndroidزيادView Answer on Stackoverflow
Solution 12 - Androidus_davidView Answer on Stackoverflow
Solution 13 - AndroidTPXView Answer on Stackoverflow