In Apiumhub we work with controlerless architecture called Pure MVP a lot ( We named it MVPP ), which is based on the concepts of composition of functions and investment of dependencies. You can find more information about it in these articles: MVPP in iOS, MVPP on Android).
In today’s article we will talk about java vs kotlin and compare how we did things before the arrival of Kotlin, and how we have improved the readability of our code thanks to them.
Java vs Kotlin
Lambdas and functions as parameters
To link the events of the view with those of the service, instead of exposing the Observable directly so that the other party can do the subscription, we expose methods that receive functions as parameters; functions that will be executed when an event occurs either in the view or in the service, such as:
//KOTLIN
interface View {
fun requestData(func: (isPaginating: Boolean) -> Unit)
fun onDataLoaded(newData: Data)
}
interface Service {
fun getData(isPaginating: Boolean)
fun onDataLoaded(func: (data: Data) -> Unit)
}
class Presenter(view: View, service: Service) {
init {
view.requestData {
service.getData(it)
}
service.onDataLoaded {
view.onDataLoaded(it)
}
}
}
A similar implementation in Java would be like this:
//JAVA
public interface View {
void requestData(Consumer func);
void onDataLoaded(Data newData);
}
public interface Service {
void getData(boolean isPaginating);
void onDataLoaded(Consumer func);
}
public class Presenter {
Presenter(final View view, final Service service) {
view.requestData(service::getData);
service.onDataLoaded(view::onDataLoaded);
}
}
The main difference between these implementations ( java vs kotlin ) is the fact that in Java we need to use the Consumer class to pass a function as a parameter (in this case a function that receives an input parameter of Boolean type and does not return anything). If we wanted this function that we passed as a parameter to return something, we would have to change Consumer to Function, and if we didn’t want to have an input parameter, we would have to use Supplier instead. But the thing does not end here, if instead of having one parameter, we would like to have two, we need to use BiFunction or BiConsumer. But if we would like to have three instead of two, Java does not provide us with a solution as we might expect (TriFunction or TriConsumer), or we build it by ourselves or we use Function > or Function , U>. Any of the solutions is definitely less readable and more complicated to define and implement than that provided by Kotlin, where this option is integrated into the language itself.
The .apply operator
When we have to instantiate a Fragment, Android makes us do it through a static method in which we will build a Bundle where we write the arguments that we want to pass to the Fragment. This is because this Bundle is stored by the operating system in order to rebuild this Fragment in case it is destroyed.
In Java we would need to do something like this:
static MyFragment newInstance(String arg1, String arg2) {
MyFragment fragment = new MyFragment();
Bundle arguments = new Bundle();
arguments.putString(ARG_1_KEY, arg1);
arguments.putString(ARG_2_KEY, arg2);
fragment.setArguments(arguments);
return fragment;
}
While in Kotlin, using the .apply operator, we would do something like this:
companion object {
fun newInstance(arg1: String, arg2: String): MyFragment {
return MyFragment().apply {
arguments = Bundle().apply {
putString(ARG_1_KEY, arg1)
putString(ARG_2_KEY, arg2)
}
}
}
}
While there is no difference in the number of lines between the two snippets, in Kotlin it is not necessary to keep references to the Fragment or the Bundle, and we can also narrow the scope of each part of the code, since we know that within each .apply we are writing code in which this will refer to the object on which we have made the .apply
- Internal modifier: Another point in favor of Kotlin with respect to Java is the internal visibility modifier, which gives us visibility to a class, method, interface, etc … bounded to the module in which it is located. This is especially interesting if we don’t want to put under test a functionality that we do not want to expose outside of our module, making it public.
- Coroutines: Another new benefit that Kotlin gives us (although it is still experimental in version 1.1) are coroutines. A coroutine is nothing more than a block of code that executes asynchronously with respect to the thread from which it was invoked. We can think that the threads are already there, but there are several differences.
- With a Thread, the operating system is in charge of managing the execution of it, suspend it, resume it, change context, etc … These operations are heavy and if we try to launch a high number of threads, for example, a million, our processor will collapse and spend more time changing from one thread to another than executing the code we want it to execute. This is because a Thread that we instantiate in Java (or Kotlin) corresponds to a Thread of the operating system (either physical or virtual), and therefore it is the scheduler of the operating system that is in charge of prioritizing which thread should be executed in every moment.
- However, a coroutine does not have a correspondence with an operating system thread, but it is the language itself (in this case the JVM) that is responsible for executing each of the coroutines and switching between them when necessary. In an example of documentation of Kotlin we can see this situation in which the instantiation of one million Threads and one million coroutines is compared:
val c = AtomicInteger()
for (i in 1..1_000_000)
thread(start = true) {
c.addAndGet(i)
}
println(c.get())
val c = AtomicInteger()
for (i in 1..1_000_000)
launch {
c.addAndGet(i)
}
println(c.get())
The results of the experiment are that it is definitely faster to use coroutines than threads, although this is not a comparison as such between Java and Kotlin, we can compare a functionality widely used in Java (Threads) with a functionality implemented in Kotlin (Coroutines)
These are just some of the changes that Kotlin brings us with respect to Java and that make our lives easier when developing applications for the JVM.
If you are interested in knowing more about knowing more about Java vs Kotlin, I highly recommend you to subscribe to our monthly newsletter by clicking here.
If you found this article about Java vs Kotlin interesting, you might like…
iOS Objective-C app: sucessful case study
Mobile app development trends of the year
Banco Falabella wearable case study
Viper architecture advantages for iOS apps
The post Java vs Kotlin appeared first on Apiumhub.