简体   繁体   English

如何将 HashMap 保存到共享首选项?

[英]How to save HashMap to Shared Preferences?

如何将HashMap 对象保存到 Android 中的共享首选项中?

I would not recommend writing complex objects into SharedPreference.我不建议将复杂的对象写入 SharedPreference。 Instead I would use ObjectOutputStream to write it to the internal memory.相反,我会使用ObjectOutputStream将其写入内部存储器。

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

I use Gson to convert HashMap to String and then save it to SharedPrefs我使用GsonHashMap转换为String然后将其保存到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();
}

I have written a simple piece of code to save map in preference and load the map from preference.我编写了一段简单的代码来优先保存地图并从首选项加载地图。 No GSON or Jackson functions required.不需要 GSON 或 Jackson 函数。 I just used a map having String as key and Boolean as a value.我只是使用了一个以 String 作为键和 Boolean 作为值的映射。

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();
    Editor editor = pSharedPref.edit();
    editor.remove("My_map").commit();
    editor.putString("My_map", jsonString);
    editor.commit();
  }
}

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

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" .作为 Vinoj John Hosan 答案的衍生,我修改了答案以允许基于数据的键进行更通用的插入,而不是像"My_map"这样的单个键。

In my implementation, MyApp is my Application override class, and MyApp.getInstance() acts to return the context .在我的实现中, MyApp是我的Application覆盖类, MyApp.getInstance()用于返回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;
}

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)

You could try using JSON instead.您可以尝试改用 JSON。

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();
}
String converted = new Gson().toJson(map);
SharedPreferences sharedPreferences = getSharedPreferences("sharepref",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("yourkey",converted).commit();

You can use this in a dedicated on shared prefs file (source: https://developer.android.com/reference/android/content/SharedPreferences.html ):您可以在专用的共享首选项文件中使用它(来源: https : //developer.android.com/reference/android/content/SharedPreferences.html ):

getAll得到所有

added in API level 1 Map getAll () Retrieve all values from the preferences.在 API 级别 1 中添加 Map getAll() 从首选项中检索所有值。

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.返回 Map 返回包含表示首选项的键/值对列表的映射。

Using PowerPreference . 使用PowerPreference

Save Data 保存数据

HashMap<String, Object> hashMap = new HashMap<String, Object>();
PowerPreference.getDefaultFile().put("key",hashMap);

Read Data 读数据

HashMap<String, Object> value = PowerPreference.getDefaultFile().getMap("key", HashMap.class, String.class, Object.class);

The lazy way: storing each key directly in SharedPreferences懒惰的方法:将每个键直接存储在 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:对于狭窄的用例,当您的地图只有不超过几十个元素时,您可以利用 SharedPreferences 的工作方式与地图非常相似的事实,并将每个条目存储在自己的键下:

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 (ie context.getSharedPreferences("myMegaMap") ) you can also get all keys with prefs.getAll()如果您使用自定义首选项名称(即context.getSharedPreferences("myMegaMap") ),您还可以使用prefs.getAll()获取所有键

Your values can be of any type supported by SharedPreferences: String , int , long , float , boolean .您的值可以是 SharedPreferences 支持的任何类型: Stringintlongfloatboolean

using File Stream使用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

You don't need to save HashMap to file as someone else suggested.您不需要像其他人建议的那样将 HashMap 保存到文件中。 It's very well easy to save a HashMap and to SharedPreference and load it from SharedPreference when needed.保存 HashMap 和 SharedPreference 并在需要时从 SharedPreference 加载它非常容易。 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:其中mUsageStatsMap定义为:

HashMap<String, T>
 

The following code will read the hash map from saved shared preference and correctly load back into mUsageStatsMap :以下代码将从保存的共享首选项中读取哈希映射并正确加载回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.关键在类型 typeMyType 中,它用于 * gson.fromJson(json, typeMyType)* 调用。 It made it possible to load the hash map instance correctly in Java.它使得在 Java 中正确加载哈希映射实例成为可能。

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:- 1) 创建 HashMap 并添加如下数据:-

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

2) Write it to shareprefrences editor like :- 2) 将其写入 shareprefrences 编辑器,例如:-

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 3)读取数据,例如:-在您希望读取它的新类中

   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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM