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.
Related
for (String[] batch : snappyDB.allKeysIterator().byBatch(0))
What does 'size' param mean in byBatch() method?
Without using byBatch you will only have a KeyIterator which does not implement Iterator or Iterable so you can't use it in a loop.
byBatch(n) creates a BatchIterable which is Iterable and an Iterator. It basically just calls next(n) on the KeyIterator when you call next() on it. (Source)
KeyIterator#next(int max) seems to always attempt to fetch max elements from the Database. So I presume you will most likely have max elements in the batch array from your example on each iteration. So it doesn't make much sense to pass 0 as you're doing (not sure if that even works).
Also just reading the README from the GitHub repo reveals some documentation:
Iterable<String[]> byBatch(int size); // Get an iterable of key batch, each batch of maximum [size] keys.
According to SnappyDB documentation, found here:
Iterable<String[]> byBatch(int size);// Get an iterable of key batch, each batch of maximum [size] keys.
So size specifies the maximum number of keys for each batch. However, according to the documentation:
Please note that you should use the byBatch iterable to process all
keys only on large collections. On reasonably small collections, using
the array based APIs (findKeys and findKeysBetween) with the form for
(String key : db.findKeys("android")) is a lot more efficient.
Iterators should only be used to process large collections or for
collection paging view / access.
So make sure that you really need byBatch in your use case.
One string size is about 200 bytes,
and it stores 10~20 size in a daily array.
(Store 10~20 strings of 200bytes, as array type)
I have found a way to convert an array to a string
and store it in SQLite.
However, I do not know it's a good idea
because the size of the string is large.
1.
If large arrays of strings,
is it a good idea to store arrays as a string?
2.
or is there a better way?
I would like advice. Thank you.
You're actually placing your concern onto the wrong part of your database design.
For SQLite, the maximum length of a String is 1 billion bytes, so your worries about your 10-20 strings of 200 bytes each actually isn't considered that large.
There's really no harm in storing your array as a single long String in your database. Especially when it's nowhere close to the maximum limit of a String.
Your database query time won't become longer due to your String being long. The real concern here is the processing you'll be doing on that String to turn it back into an Array. Typically, if the String is extremely long, the real performance hit is when you're flattening the array into a String and when you're transforming that String back into an Array.
However, typically, this is something you'll show a loading indicator for to your users.
For storing an Array into a database, there's really only two ways to do so:
Flatten array into a single String and store the String as TEXT
Create a table meant to store the individual elements of the string, and include a column for a Foreign Key that allows you to associate those rows with the same array. Then you'll store each element of your String arrays as a row in this table.
Depending on what you need, one design is better than the other.
For example, you would normally prefer the second implementation if your app requires you to constantly edit individual elements of an array.
For such an example, it wouldn't make much sense to use the first solution, because this means every time you want to edit the contents of an array, you'll be fetching back the complete array in it's entirety. This is impractical when you only want to fetch or edit a particular portion of that String.
Therefore, in such an example, it is much more practical to store the individual elements of the arrays into individual rows of a Table meant for this type of data. You'll be querying only the row you want and updating only the row you want.
So to answer your questions, there's really only two ways to store your String array as a TEXT type in your SQLite database. Both ways work and the real concern is to consider which solution fits your needs best.
If your app only requires you to store and fetch the array in it's entirety each time, then the single String method might be more preferable.
But if your app requires you to work with individual elements of your array, then using the table method would be more convenient.
According to the previous image
Is it possible to get every child of that matches the value of "11000" in that is inside the array ?
(there might be multiple entries for )
It depends on where you start. From /planes/PaMé7800_..._785/directiones it is definitely possible. But from /planes it is not possible, since you can only query values at a known path under each child.
Essentially your current structure allows you to efficiently find the directiones for each plane, but is does not allow you to efficiently find the planes for a directione. If you want to allow the latter, consider adding an additional data structure for it. For example:
directionesStCPToPlanes
dir11000
PaMé7800_..._785: true
With this additional data structure, you can also look up the inverse relation.
This type of double data storage is quite common and is known as denormalizing the data. For more on this, see:
Many-to-many using Firebase
Many to Many relationship in Firebase
Firebase Query Double Nested
I have an app that generates objects of a class, let's call it X, that is Serializable. I want the user to be able to occasionally save or delete objects of X from his/her list of favorites (a list that can go up to 100 objects).
What is the most appropriate way to persistently store the list of favorites?
In SharedPreferences, storing the whole list as a JSON String
In an SQLite database:-
Storing one item per object, as BLOB's
Storing one item per object, as JSON Strings
In a custom file, storing the whole list as a JSON String
Some other way?
My thoughts are:
Because adding and removing favorites will be occasional, and the list is small, I probably don't need the advantages of a DB when it comes to searching fields in large amounts of data. So I am inclined to maintain a local ArrayList, add and remove items from it, and save it to SharedPreferences (option 1).
It seems odd to save a key-value pair holding an entire list as a JSON String, I'm afraid I might be unaware of some sort of limitation.
Is there a limit to the size of the String I can store in SharedPrefferences?
Is it too problematic that I add or remove objects from my local ArrayList and then save the whole list?
I am agree with your first approach because of It's manage easily and need small storage space.
I am developing an app with Firebase, it is a game in which certain scores are shared between players and can grow without a limit. I tried storing them as a String, but then I could not order them with orderByChild for the leaderboard. How can I handle this problem?
You could store the number as a linked list, with each node in the list representing each digit. Be careful with the order; putting the last number (the ones digit) in the list first, makes math with the linked list easier, while the other direction makes it easier to return the nodes in the list to a number on the screen.
To store integers which are big in size java provides a BigInteger Class to handle those numbers. I will suggeat you to use that first read the concept and then try to findout what you exactly want!
Check this one BigInteger