Android:how to store and retrieve Hashmap data in sharedpreferences? - java

I want to store some data like key and value pair in internal storage.
so i am using HashMap to store key,value pair .but i don'get sufficient solution to store and retrieve this HashMap into sharedpreferences.
Please give me some solution.
i am put my code below:
HashMap<String, String> MapListMesasges = new HashMap<String, String>();
MapListMesasges.put(FromName, message.getBody());
preferences = mActivity.getSharedPreferences(
SharePreference_messages_history_name,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
for (Entry<String, String> entry : MapListMesasges
.entrySet()) {
editor.putString(entry.getKey(), entry.getValue());
}
editor.commit();
and retrieve data from Sharedprefernces:
preferences = mActivity.getSharedPreferences(
SharePreference_messages_history_name, Context.MODE_PRIVATE);
for (Entry<String, ?> entry : preferences.getAll().entrySet()) {
MapListMesasges.put(entry.getKey(), entry.getValue().toString());
}
i will also store hashmap in adapter and set into listview.
My main purpose is to store and retrieve data into sharedprefernces and also show data into listview.
Thanks in advance.

The easiest way to store HashMap in Preferences is just convert it to the string and store it.
On the Otherside get that string convert it in HashMap and enjoy.
To Convert String to HashMap & vice-versa check this link.

You can use json for solution.
For example:
**JSON**
{
[
"name1","message1",
"name2","message2"
]
}
Store this entire json string with some key and use same key to retrieve.
Just you need to parse/create JSON. You can use GSON lib for JSON creation/parsing

There's special thing for doing operations like you described and this is SQLite.
But if you really want to store them in SharedPreferences, you can do it.
Your solution almost work. You just need to store keys as well.
StringBuilder b = new StringBuilder();
for (Entry<String, String> entry : MapListMesasges.entrySet()) {
editor.putString(entry.getKey(), entry.getValue());
if(b.length() != 0){
b.append(",");
}
b.append(entry.getKey());
}
editor.putString("KEY_FOR_PREF_KEYS",b.toString());
And to retrieve data use this
String[] keys = preferences.getString("KEY_FOR_PREF_KEYS","").split(",");
for (int i = 0; i < keys.length; i++) {
MapListMesasges.put(keys[i], preferences.getString(keys[i]));
}

Related

Trouble with displaying hashmap

My App: has two activities, one to create two strings (name and message), which are saved into a hashmap, transferred into JSON and saved in a SharedPreference.
The other activity fetches this SharedPreference, transfers it into a hashmap again. Then the map is "read out" by an Iterator.
Supposed to be: My Idea is, that if I do this process several times, the iterator "reads out" all the entries to the hashmap.
Problem: However, only the last input gets displayed.
Question: Why is only the last input displayed? Am I overriding the hashmap or parts of it? And if so, how can I avoid it? Or what else am I doing wrong?
Activity 1:
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put(message, name);
Gson gson = new Gson();
String hashMapString = gson.toJson(map);
SharedPreferences prefs = getSharedPreferences("SP", MODE_PRIVATE);
prefs.edit().putString("hashString", hashMapString).apply();
Activity 2:
Gson gson = new Gson();
SharedPreferences prefs = getSharedPreferences("SP", MODE_PRIVATE);
String storedHashMapString = prefs.getString("hashString", "Error");
java.lang.reflect.Type type = new TypeToken<LinkedHashMap<String, String>>(){}.getType();
LinkedHashMap<String, String> map = gson.fromJson(storedHashMapString, type);
Iterator myIterator = map.keySet().iterator();
while(myIterator.hasNext()) {
String key=(String)myIterator.next();
String value=(String)map.get(key);
Toast.makeText(getApplicationContext(), "Key: "+key+" Value: "+value, Toast.LENGTH_LONG).show();
}
while doing this
prefs.edit().putString("hashString", hashMapString).apply();
you are just saving values of newly created hashmap but old losing values which were saved previously using hashString key
Solution: fetch the old value and save it along with new values
Option one : fetch previous string , convert it to jsonobject then add the values to map
Reference : creating Hashmap from a JSON String
Option two : if you have only string key-value pair then
remove { and } from both new and old map strings then simply combine them and add { and } boundary symbols
String allValues ="{"+((prefs.getString("hashString", "")+hashMapString)
.replace("{","").replace("}",""))+"}";
then later save it
prefs.edit().putString("hashString", allValues).apply();
you are seeing the last input because putString overwrites whatever was there in the first place
https://developer.android.com/reference/android/content/SharedPreferences.Editor.html

How to store key value pairs in SharedPreferences?

I am developing an app that generates passwords randomly. I am adding a "save" feature so that the user can save their passwords in SharedPreferences. (which is not what you are supposed to do with your passwords)
I have an activity called PasswordActivity and in that activity I display the saved passwords.
This is how I save a password: I prompt the user to enter a name/key thingy for the password so that he/she can identify it later. And then I save the key and the password in the SharedPreferences using the following method in a utility class:
public static int savePassword (Context c, String passwordKey, String passwordValue) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
SharedPreferences.Editor editor = prefs.edit ();
boolean duplicateKey = !keys.add (passwordKey);
boolean duplicateValue = !values.add (passwordValue);
if (duplicateKey)
return KEY_DUPLICATE;
if (duplicateValue)
return VALUE_DUPLICATE;
editor.putStringSet (PASSWORD_KEYS, keys).
putStringSet (PASSWORD_VALUES, values).apply ();
return SUCCESS;
}
And I wrote another method to get the passwords and their names. The method returns a HashMap<String, String> as you might have guessed.
public static HashMap<String, String> getPasswords (Context c) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
ArrayList<String> keysList = new ArrayList<> ();
ArrayList<String> valuesList = new ArrayList<> ();
for (String key : keys) {
keysList.add (key);
}
for (String value : values) {
valuesList.add (value);
}
HashMap<String, String> map = new HashMap<> ();
for (int i = 0 ; i < keys.size () ; i++) {
map.put (keysList.get (i), valuesList.get (i));
}
return map;
}
I admit that the code is pretty messy. I first get the things in the two sets and turn them into ArrayLists and add the stuff in the array list to the map and return.
Phew! That was a lot of work!
Now when the user generates a password and saves it, the two sets contain the right things: (These are fake data)
keys:
key1
values:
value1
That's all good. But when I generate another password and save it, the two sets become messy:
keys:
key1
key2
values:
value2
value1
Now when I call the getPasswords method, it will return
{key1, value2}, {key2, value1}
which is incorrect. After looking at the docs, I found out that:
It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
which I guess is the reason that makes the incorrect results.
So I was wondering is there an alternative way to store these passwords and their names?
As you're storing multiple names & passwords, i would suggest a local SQLite database. SharedPreferences are meant for single values, not sets of values.
If you can't be bothered setting up the entire SQLiteOpenHelper and all that raw SQL code, you could take a look at some ORM helpers such as SugarOrm (i currently use this, its EXTREMELY easy to set up and use)
I would recommend a database, such as SQLCipher for Android, so the user can provide a master passphrase for the app, and all the data is stored encrypted on the device.
But, let's pretend that, in order to successfully repel an alien invasion and prevent the wholesale slaughter of countless humans, you have to implement this using SharedPreferences. After that, you will need to fly with a wise-cracking companion in a commandeered alien spacecraft and successfully upload your app into the computer systems of one of the alien mother ships (which, fortunately, happen to be running Android, as Android has remarkable market share across the galaxy).
Either:
Have each key and value be separate entries in the SharedPreferences. After all, SharedPreferences is a key-value store. Use a dedicated preference file for your keys and values (so as not to collide with anything else you might want to store), then you know that all the keys are ones from the user.
Marshal the HashMap into JSON or XML or something and save that as a string, unmarshalling it as needed.

how to implement below data structure in java using collection framework

I have below data structure like this
Country,StateID1 where StateID1 contains "City1","City2","City3" etc
Country,StateID2 where StateID2 contains "City1","City2","City3" etc
I know i can't use HashMap to implement above data structure because if i add StateID2 to same Country StateID1 will be replace with StateID2
for eg
map.put("1","1111");
map.put("1","2222");
output
key:value
1:2222`
i am facing hard time to figure out how to do this. I need some support from you guys
You need some wrapping object for storing your 'state' data. Then you can have a structure like this: Map<String, List<StateBean>>. This way you can handle a list of state for every country.
If data are just Strings use Map<String, List<String>>
You can have a Map<String, Set<String>>.
Store the StationIDs in an ArrayList object and add those object in a HashMap using key-value pair .. where key is the Country against the StationId ArrayList Object.
StateID1 = ["City1","City2"] // ArrayList
StateID2 = ["City1","City2"]
We could have the map as Country,ListOfStates
ListOfStates could be a list that contains StateIds
Or StateIds as a Map with StateId as key and list of cities as value
You could create a class for the same.
class YourClass
{
String country;
State state;
}
class State
{
Set<String> cities;
}
You can then use this class as a data structure. You don't really need to use Collections framework for the same.
OR
If you really want to do it using Collections, then you can use a combination of Country and StateId as the key, and the list of cities as the value in a Map. For ex:
String country = "1";
String state = "1";
String separator = "-" // You could use any separator
String key = country + separator + state;
Set<String> cities = new HashSet<String>();
cities.add("1");
cities.add("2");
Map<String, Set<String>> map = new HashMap<>();
map.put(key, cities);
So your key would be 1-1 and value would be 12.
Use can Data Structure map < String,vector < String >> , map < class T,vector < class U > >

Same key - Different Value with a HashMap

I'll start with what I want to achieve
Intention
The software parses XML-Data in a for-loop. The for-loop which handles the data will go until 50 (because I'm getting 50 different results). What I did at first was, that the doInBackground-method parses the whole XML data and saves it into TextViews and displays it. But now I wanted to add a splash-screen that gets displayed as long the data loads.
The XML-File is built up like any other normal XML-file, so when I go through a for-loop the keys are always the same, but the values differ.
Approaches
What I already did was to create an multidimensional array, but unfortunately you can't use Strings as an index. That's what the Map is for. This was my approach
stringArray[i]["source"] = sourceString;
Well, then I tried it with a Map. But the problem with the map was, that when the new key came again, it would just overwrite the previous key-value pair.
So I figured out I would use a HashMap with a String Collection. I handled it like this;
First I created the HashMap
public HashMap <String, Collection<String>> hashMap = new HashMap<String, Collection<String>>();
Then I put data in the HashMap for each key.
hashMap.put("source" , new ArrayList<String>());
This is what I have done in the for-loop
hashMap.get("source").add(new String(((Node) sourceList.item(0)).getNodeValue()));
Then, when finished, the onPostExecute-method starts a new intent and passes the hashMap.
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Intent i = new Intent(SplashScreen.this, MainActivity.class);
i.putExtra("hashMap", hashMap);
startActivity(i);
finish();
}
And in my MainActivity I'm doing this to get the data
Intent intent = getIntent();
HashMap<String, String> hashMap = (HashMap<String, String>)intent.getSerializableExtra("hashMap");
rankingDate = new TextView(this);
rankingDate.setText("RankingDate: " + hashMap.get("rankingDate"));
layout.addView(rankingDate);
But this results in a ClassCastException : `ArrayList cannot be cast to java.lang.String" in this line
source.setText("source: " + hashMap.get("source"));
I guess it's because hashMap.get("source") contains all values of the source data. So I tried to save all the data in a String Array. But this didn't work, but I don't know why. Eclipse tells me that Type mismatch: cannot convert from String to String[]
Any advice? I'm dying to solve this problem.
You got a typo:
HashMap<String, String> hashMap = (HashMap<String, String>)intent.getSerializableExtra("hashMap");
should be:
HashMap<String, Collection<String>> hashMap = (HashMap<String, Collection<String>>)intent.getSerializableExtra("hashMap");
#Eng.Fouad answer is correct, you have an error in the casting.
You might consider using a MultiMap rather than a map of collections:
http://guava-libraries.googlecode.com/svn/tags/release03/javadoc/com/google/common/collect/Multimap.html
Use a list of maps.
You can call list.get(index).get("source") and get the result later.
semi pseudocode:
List<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>
foreach(entry in document)
map = new HashMap<String,String>();
foreach(xml in entry)
map.put(xml,xml.value)
end
list.put(index++,map)
end
Your casting your hashmap incorrectly in your main activity.
Try this:
HashMap<String, Collection<String>> hashMap = (HashMap<String, Collection<String>>)intent.getSerializableExtra("hashMap");
Hope this helps :)

Can you reference a java variable from a string?

Hi I have a strange question about java. I will leave out the background info so as not to complicate it. If you have a variable named fname. And say you have a function returning a String that is "fname". Is there a way to say reference the identifier fname via the String "fname". The idea would be something like "fname".toIdentifier() = value but obviously toIdentifier isn't a real method.
I suppose a bit of background mite help. Basically I have a string "fname" mapped to another string "the value of fname". And I want a way to quickly say the variable fname = the value of the key "fname" from the map. I'm getting the key value pair from iterating over a map of cookies in the form . And I don't want to do "if key = "fname" set fname to "value of fname" because I have a ton of variables that need to be set that way. I'd rather do something like currentkey.toIdentifer = thevalue. Weird question maybe I'm overlooking a much easier way to approach this.
Why don't you just use a simple hashmap for this?
Map<String, String> mapping = new HashMap<String, String>();
mapping.put("fname", "someValue");
...
String value = mapping.get(key); //key could be "fname"
In a way you're describing what reflection is used for:
You refer to an object's fields and methods by name.
Java Reflection
However, most of the time when people ask a question like this, they're better off solving their problem by re-working their design and taking advantage of data structures like Maps.
Here's some code that shows how to create a Map from two arrays:
String[] keyArray = { "one", "two", "three" };
String[] valArray = { "foo", "bar", "bazzz" };
// create a new HashMap that maps Strings to Strings
Map<String, String> exampleMap = new HashMap<String, String>();
// create a map from the two arrays above
for (int i = 0; i < keyArray.length; i++) {
String theKey = keyArray[i];
String theVal = valArray[i];
exampleMap.put(theKey, theVal);
}
// print the contents of our new map
for (String loopKey : exampleMap.keySet()) {
String loopVal = exampleMap.get(loopKey);
System.out.println(loopKey + ": " + loopVal);
}
Here's a link to the JavaDoc for Map.

Categories