I was wondering what the difference between database.getReference("foo/bar/123") and database.getReference("foo").child("bar").child("123") is?
I'm assuming that the later one will load the complete "foo" object whereas database.getReference("foo/bar/123") just loads the "123" object?
Is my assumption correct or what is the correct / most efficient way to only load data of "123"?
The two are equivalent. You can inspect this manually this by printing the toString() format for both References.
References are cheap - there's nothing inefficient about either solution. Neither one has yet loaded any data. A Reference is just a pointer to a location in the database.
It should not make a difference, a reference is not actually accessed when instantiated. This is the most relevant document I can find,
https://firebase.google.com/docs/reference/node/firebase.database.Reference
The docs don't say it explicitly, but requests are only performed when using the .set() or .on() methods
Related
I am not able to clearly understand what is typed array in kotlin. I have seen the fucntion toTypedArray in kotlin. but did not see any proper definition of it like what exactly it does. Can anyone please explain with an example.
Thanks
Arrays are generic data structures because they can contain different types of elements. You can have Array<Int> or Array<String> for instance.
There is no separate concept of "typed" array. The reason for the name of toTypedArray is (I guess) to distiguish it from toArray() which returns an Array<Any?> (without useful type information about its elements, because everything is a Any? in Kotlin).
The reason why those 2 exist is because arrays on the JVM cannot be created without knowing the element type. This means that, in general, you cannot create an arbitrary array generically because generics are erased at runtime so you wouldn't actually know the correct element type at that time. This is why the simple toArray method either returns Array<Any?> or takes an extra array argument. The extra argument allows to either avoid creating the destination array, or at least provides sufficient type information at runtime to create an array of the same type.
In Kotlin, we can go one step further and actually use reified types to use information that we have at compile time to generate more specific code, such as code that create an array of a specific type (not generically, but directly with the correct element type based on the call site information). This is what toTypedArray does by reifying its type parameter.
I have a document on Firestore, from which I read its fields in a fragment. Since it has many fields, I set variables in the Activity that hosts this fragment so that I can pass the data between other fragments. In order to achieve that, I realize that I have to write similar lines of codes over and over again, which got me to thinking if there is a better way.
Two possible solutions that come to my mind:
Structure all these fields in JSON format -> something that wouldn't be suitable in Firestore's document system imo
Put all these fields into a serializable data class which I keep in the activity then pass it around the bundles of fragments -> Seemed to complicated and I would still have to write it.get(foo) as bar for each of the field's of this class' constructor.
Given all these, what is the best approach? Thanks in advance.
You have a several options on how to approach this. There is none that's necessarily better than another. Ultimately, you will pick the one that best suits your needs and preferences.
You can do what you're doing now.
You can go a step further an actually check the types of the values instead of just blindly casting them (which would cause a crash at runtime if they didn't match).
You can provide a Class object to get(String, Class<T>) that can automatically map the fields to properties in a new object of type T, as long as the types also match.
You can call a variety of type-specific versions of get, such as getString()
Ultimately you will have to decide if you are going to trust what you get in the snapshot and allow errors to happen, or trust nothing and check everything. It's up to you.
Why is setValueAt(...) in the public interface of the SparseArray class? I was using it instead of put(...) obviously not getting the result I had in mind.
I came here trying to figure out the same thing. As Prekak Sola mentioned in the comments, setValueAt maps a value on a specific index, while put maps a value on a specific key.
Obviously, that can become confusing, but I think it is a very useful feature, because if you look at the official SparseArray documentation, it is mentioned that the SparseArray is generally slower than a HashMap, because lookups require a binary search and adds and removes require inserting and deleting entries in the array.
So, I guess that in certain cases, it would perform much faster if you iterate over the items in this container using keyAt(int), size(), and obviously all index-related functions, such as setValueAt, instead of using the keys.
I have implemented a standard LRUCache in Android that stores Objects. Each key is a unique ObjectId associated with the Object stored. My problem is that the only way to retrieve an Object from cache is by the ObjectId (no iterator). What would be the best way to implement a getAll() method?
Another option would be to store all the ObjectIds in a list somewhere, so I can iterate over the lists and get all of the Objects - but what would be the best way of holding all of the ObjectIds?
Thanks!
If you're using (or extending) the LruCache that Android provides, it has a snapshot method that returns a map of keys (your ObjectIds) and values (your Objects). You can do something like this:
Map<ObjectIds, Object> snapshot = lruCache.snapshot();
for (ObjectIds id : snapshot.keySet()) {
Object myObject = lruCache.get(id);
}
If you're not using Android's LruCache, then I imagine it would depend on your implementation. (I'd also be curious what motivated you to implement your own instead of subclassing the provided one!)
Using snapshot to get current collection at the moment
lruCache.snapshot().values()
It does not make sense to iterate over the objects in a LRU cache. You can not know which object is still in the cache and which got evicted (you actually can, but that's another story). It sound like you'd probably better off with a different data structure like a Hashmap or so. Nothing will ever get evicted from there.
A common use-case is to have a List of all possible object keys in memory. If you need one, you check if it is in the cache. If not, receive it and add it to the cache.
In the source code of Activity.java, I see some methods bellow :
public View findViewById(int id) {
return getWindow().findViewById(id);
}
and the definition of getWindow method:
public Window getWindow() {
return mWindow;
}
But as the following rules:
Avoid Internal Getters/Setters
In native languages like C++ it's
common practice to use getters (e.g. i
= getCount()) instead of accessing the field directly (i = mCount). This is
an excellent habit for C++, because
the compiler can usually inline the
access, and if you need to restrict or
debug field access you can add the
code at any time.
On Android, this is a bad idea.
Virtual method calls are expensive,
much more so than instance field
lookups. It's reasonable to follow
common object-oriented programming
practices and have getters and setters
in the public interface, but within a
class you should always access fields
directly.
Without a JIT, direct field access is
about 3x faster than invoking a
trivial getter. With the JIT (where
direct field access is as cheap as
accessing a local), direct field
access is about 7x faster than
invoking a trivial getter. This is
true in Froyo, but will improve in the
future when the JIT inlines getter
methods.
so I want to know why android developers not access this mWindow object directly? If the JIT of the current android versions cannot inline the access, getWindow().findViewById(id) will costs more time than mWindow.findViewById(id), and findViewById is a rather frequently used method.
First: you can't access it because it's private.
Why is it private?
As you said, accessing members directly is faster. On the other hand, you are invoking a method that isn't very fast as it will lookup for some view in the view hierarchy. So using a method instead of a direct access will incur in a small overhead in terms of percentage of the total time that it would take to perform that task.
Anyway, I believe that the reason for this is encapsulation.
You are invoking something you don't own (that is the Android SDK). So, you shouldn't make any assumptions of whats happening "in the other side". Simply use this method and expect that it will return the view you want (or null if it doesn't exists).
Maybe the next version of android will use a different method to lookup a view, not calling getWindow(). If you use this method, they (Google/Android) can simply mark the method as deprecated and "forward" your invocation to the newest implementation. If you were calling directly getWindow(), maybe you would be looking for something that is no longer placed in there.
You can't access the mWindow property directly - it's private.
And I wouldn't care about the speed of findViewById, since you only need to call it once for every view in your layout in your onCreate() method and store the views in members of your activity. You do call findViewById only once per view, don't you? ;-)
However, if you really care about these things, you could call getWindow() for yourself, store it into a local variable and call findViewById on it directly. I wouldn't recommend this because all your performance increasements here are not worth the time and anyway will be obsolete with future versions of the JIT.
If you do this I would be very interested in the amount of microseconds you saved. :-)
We have a reason to smile now...
The android documentation which says to avoid internal getters and setters will change soon, supposedly progruard was added to Gingerbread platform which does a fine job of inlining accessor's, please refer to "Avoid Internal Getters/Setters" is bad advice and these two SO posts.
https://stackoverflow.com/a/6716573/892055
https://stackoverflow.com/a/4930538/892055