I have to implement the classification of somehting like Hashmap with two keys and a value, let's say Hashmap<K1, K2, V>, where the two keys are integers and the value is a generic MyObject defined by me.
I read this, this, and this post, and I also know that guava project offers the table interface, but I don't want to use external libraries (if not strictly necessary) to keep my project smaller as possible.
So I decided to use SparseArrays: I thought that this was the better choice because my keys are int and are not necessarily starting from zero and increasing.
I do this initializing:
SparseArray<SparseArray<MyObject>> myObjectSparseArray = new SparseArray<SparseArray<MyObject>>();
Now let's go to the point. Can I do this kind of operation:
MyObject myObject = new MyObject();
myObjectSparseArray.get(3).put(2,myObject);
or should I do something like:
MyObject myObject = new MyObject();
myObjectSparseArray.put(3, new SparseArray<MyObject>());
myObjectSparseArray.get(3).put(2,myObject)
In other words: Do I initialize both SparseArrays with this single line?
SparseArray<SparseArray<MyObject>> myObjectSparseArray = new SparseArray<SparseArray<MyObject>>()
Do you think there are better implementations for my case?
If you have two keys and one value, I would just use a normal HashMap or SparseArray and will combine those two keys into one value.
Let's say you have one key which is String and one which is Long so your map key will be:
(strKey + longKey).hashCode(). You can use it as Integer and save it into SparseArray or as String and use HashMap.
Having tow nested SparseArray is against the purpose of having SparseArray in the first place since you will allocate a new SparseArray for each unique first key in your key pairs.
A good solution for that would be by using hashmap and use a key object that takes two int values (Point for example) or an object that you define that simply holds two keys.
Related
In java a TreeMap is used for dictionaries where keys are kept sorted.
On android, an ArrayMap is used as a "memory-efficient" HashMap where (I infer) keys are kept sorted because
lookups require a binary search and adds and removes require inserting and deleting entries in the array
Memory Usage:
...this container is intended to better balance memory use...
It keeps its mappings in an array data structure -- an integer array of hash codes for each item, and an Object array of the key/value pairs. This allows it to avoid having to create an extra object for every entry put in to the map.
...it will shrink its array as items are removed from it...
We can reasonably conclude that ArrayMap is inappropriate for holding ~1000+ items:
For containers holding up to hundreds of items, the performance difference is not significant, less than 50%.
Note that this implementation is not intended to be appropriate for data structures that may contain large numbers of items.
What are additional costs/benefits of using one over the other generally?
is android's ArrayMap implementation thread-safe (thus slower)?
is there a way to affect the sorting in an ArrayMap?
are there similar data structures in Guava?
etc..
ArrayMap is not thread-safe, as stated in the documentation.
The sorting is always by ascending order of the keys hashcode. You can control the order by overriding hashCode() in the implementation of the key class. Beware of collisions.
ArrayMap allows accessing its keys and values directly by index like an ArrayList and can be iterated on very efficiently.
ArrayMap has the smallest memory consumption of the two. Both have a complexity of O(log n) for retrieval. Insertions and deletions are in theory a bit slower for ArrayMap because they are similar to inserting or deleting an element in the middle of an ArrayList: technically it's O(n) but it's using a single call to System.arrayCopy() to move all values at once very quickly. So if you need to modify the map very often, ArrayMap is probably not the best choice but for all other use cases it's very capable.
I have a list of objects that I needed to sort by category and also alphabetically. My idea was to take my ArrayList, convert it to a HashMap so that I could use a key to organize my data by category, and then createe a treemap to naturally alphabetize the data. It works, and I am not certain of a better/more efficient way of doing this. My TreeMap has the following structure:
TreeMap<String, ArrayList<CustomModel>>
How do I access the list of values from this treemap? I understand that I can get a specific value, if it were a String for example like the following:
for (Map.Entry<String, String> entry : treemap.entrySet()) {
Log.i(TAG, "key= " + entry.getKey());
Log.i(TAG, "value= " + entry.getValue());
}
However, what if you have a list of values? How do I retrieve everything within that list? Seems like I need another conversion.
It seems like you already have this solved. Entry.value() will return the ArrayList, instead of the String type. Try enumerating this and then logging each value
I got the answer. There are a couple of ways of doing this. You can retrieve an object from your list, or the entire list object.
1) Object From List
You need a key to do this option. Get the key using keySet()
Object key = treemap.keySet().toArray()[index];
Object value = treemap.get(key);
2) Entire List Object
ArrayList<CustomModel> alCustomModel = (ArrayList<CustomModel>) treemap.values().toArray()[index];
Some notes about this, is that you are retrieving the list of CustomModels per position. Use whichever methodology makes sense to you. Cheers!
I want to append two different hash map pairs on a particular node one with key value both being String and other String and Array List. But problem is Later one is replacing first one in Fire base database. what should i do? I cant use push() all the time.Link of my code. Please help
You can achieve this if you generate a unique random key. This can be done using push() method.
As we know, in the case of HashMap, it replaces the old value with the new one.
Don't forget to use updatechildren() method, and not setValue() method directly on the refrence when you want to update data.
Hope it helps.
Just use 1 Map<String, Object> instead of 2 different ones.
then you put all the data in that single map, string, arraylist
I need some idea of how randomaly give each button[i] on of the values R.id.buttonj_mg.
(one to one function...).
I don't know how to do it since R.id.button1_mg is not a string, so I can't do somethink like R.id.button+j+_mg when j chossen randomaly..
This is the situation now:
button[1]= (Button)findViewById(R.id.button1_mg);
button[2]= (Button)findViewById(R.id.button2_mg);
button[3]= (Button)findViewById(R.id.button3_mg);
button[4]= (Button)findViewById(R.id.button4_mg);
button[5]= (Button)findViewById(R.id.button5_mg);
button[6]= (Button)findViewById(R.id.button6_mg);
button[7]= (Button)findViewById(R.id.button7_mg);
button[8]= (Button)findViewById(R.id.button8_mg);
button[9]= (Button)findViewById(R.id.button9_mg);
button[10]= (Button)findViewById(R.id.button10_mg);
button[11]= (Button)findViewById(R.id.button11_mg);
button[12]= (Button)findViewById(R.id.button12_mg);
button[13]= (Button)findViewById(R.id.button13_mg);
button[14]= (Button)findViewById(R.id.button14_mg);
button[15]= (Button)findViewById(R.id.button15_mg);
button[16]= (Button)findViewById(R.id.button16_mg);
You could use a collection to store your ints as Integers and then use the Java Collection class shuffle() method on those objects. Then you could remove them one by one from the Collection in each one of your buttons.
List<Integer> resources = new ArrayList<Integer>();
...
resources.add(R.id.button1);
...
Collections.shuffle(resources);
One solution is to create the buttons and their ids in the code instead of taking them from resources, look at https://stackoverflow.com/a/11615356/987358. Then you can store them easily in a collection as another answer suggests.
Another solution is the Java reflection API which allows to retrieve the values of the ids using strings of the id names.
I am attempting to set up a simple Morse encoder using a hashmap in android. Putting values in the hashmap seems pretty straightforward like so:
HashMap<String, String> translate = new HashMap<String, String>();
//initializing translate
translate.put("A",".-");
//same for all letters of alphabet and numbers
However I am having difficulty finding an effective way to utilize the data of the key values for export to another method. I plan to use these values in a string method and simply display it on the phone screen for the user when they type a letter. For example, if they type in "A" the hash map will be queried for "A" and return a ".-". I have never worked with hashmaps before and can't find a suitable example.
Any help on how to access these keys within an android environment will be appreciated!
Use HashMap.get(), so:
translate.get("A"); // returns ".-"
The object returned is exactly the same as the object supplied in the 2nd argument to put(). So if you put a URL in (and the Map is suitably typed) you will get the same URL instance returned from get().
HashMap has keySet and entrySet(). You may start from here. Here is javadoc for complete list of methods in HashMap. Here is an example on how to use those methods.