Sunday, 17 May 2020

lateinit Vs by lazy

Both "lateinit" and "by lazy" are Kotlin Property initializers.

lateinit:
  • Use it with mutable variable [var]
  • Allowed with only non-nullable data types
  • This modifier is not allowed on properties of primitive types
  • It is a promise to compiler that the value will be initialized in future.
  • If you try to access lateinit variable without initializing it then it throws UnInitializedPropertyAccessException.
by lazy:
  • Lazy initialization was designed to prevent unnecessary initialization of objects.
  • Your variable will not be initialized unless you use it.
  • It is initialized only once. Next time when you use it, you get the value from the memory.
  • It is thread safe (It initializes in the thread where it is used for the first time. Other threads use the same value stored in the cache).
  • The variable can only be val.
  • The variable can only be non-nullable.

Monday, 27 April 2020

Kotlin Generic function & Infix

Generics are the powerful features that allow us to define classes, methods and properties which are accessible using different data types while keeping a check of the compile-time type safety.

A generic type is a class or method that is parameterized over types. We always use angle brackets (<>) to specify the type parameter in the program.

Advantages of generic –
  1. Type casting is evitable- No need to typecast the object.
  2. Type safety- Generic allows only single type of object at a time.
  3. Compile time safety- Generics code is checked at compile time for the parameterized type so that it avoids run time error
Infix:  This is the Kotlin keyword used before the function and this enables us to call the methods without any dot and parenthesis.  This increase the code readability in a general way (as like as speaking language :-) ).

Rules for the Infix:
  1. All Infix functions are need to be Extension function.
  2. It must accept only one param and no default value is permitted.
  3. It must have "infix" keyword before to the function.  
Lets see some code Snippet: 
  1. Just created a demo data class 
  2. Two Generic and extension functions (Extension of List) and in that one of them is infix, you can see the above rules is applied.  
data class Demo(val id: String, val name: String)

fun <T> List<T>.updateObjWith(other: List<T>) = this + other

infix fun <T> List<T>.updateWith(other: List<T>) = this + other

Calling the non-infix generic function:
  1. Here you can see the list objects created for different types
  2. Updated the object with the some more contents using the updateObjWith(<T?) method 
fun main() {
    val myPlaces = listOf<String>("Chennai", "Puducherry")
    val myPlayers = listOf<Demo>(Demo("123EAX", "Ragavan"), Demo("989XEA", "Rajeevan"))
    val myNumbers = listOf<Int>(1, 2, 3, 4, 5)

    val updatedPlayers: List<Demo> = myPlayers.updateObjWith(listOf(Demo("325EUV", "Manirathnam")))
    updatedPlayers.forEach { println(it) }

    val updatedPlaces: List<String> = myPlaces.updateObjWith(listOf("Madurai"))
    updatedPlaces.forEach { println(it) }

    val updatedNumbers = myNumbers.updateObjWith(listOf(10, 9, 8, 7, 6))
    updatedNumbers.forEach { println(it) }
}

Calling via Infix function: Code will be in more readable form.

fun main() {
    val myPlaces = listOf<String>("Chennai", "Puducherry")
    val myPlayers = listOf<Demo>(Demo("123EAX", "Ragavan"), Demo("989XEA", "Rajeevan"))
    val myNumbers = listOf<Int>(1, 2, 3, 4, 5)

    val updatedPlayers = myPlayers updateWith listOf(Demo("325EUV", "Manirathnam"))
    updatedPlayers.forEach { println(it) }

    val updatedPlaces = myPlaces updateWith listOf("Madurai")
    updatedPlaces.forEach { println(it) }

    val updatedNumbers = myNumbers updateWith listOf(10, 9, 8, 7, 6)
    updatedNumbers.forEach { println(it) }
}

Sunday, 5 April 2020

Singleton - Java vs Kotlin

Singleton is a widely used design pattern in our programming, because the single instance or object reference has been used to accessing their properties and that instance remains through out the  application session.

Now we can see how it will be implemented in Java and Kotlin.

Singleton Using Java:

public final class Singleton {
    private static final Singleton INSTANCE = new Singleton();
    public String property1;

    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }

    public String getInfo() {
        return "SingleInfo";
    }
}

Points to be remembered on creating the Singleton class using Java.
  1. Class need to be final, in order to avoid this class to be inheritance by other.
  2. Constructors are need to be private
  3. private, static and final instance have to instantiated.
Accessing the properties and methods will be as follows.

String property1 = Singleton.getInstance().property1;
String info = Singleton.getInstance().getInfo();

Singleton in Kotlin: Here it is very crazy in kotlin, the below things does the job.

object Singleton {
    var property1: String? = null
    val info: String
        get() = "SingleInfo"
}


val property = Singleton.property1
val info = Singleton.info

Happy Coding :-)

Monday, 27 January 2020

Sunday, 15 September 2019

Kotlin Code to break forEach inline loops

In General we are unable to break the forEach inline loops.  Please check the below tries and see the proper way to do so.

1
2
3
4
5
6
7
8
9
 var data = listOf<String>("Dev", "Prd", "Test", "Sbx", "demo")
    data.forEach {
        if (it.equals("Prd")) {
            println("I'm Selected $it")
            return
        }
        println("I'm in the list $it")
    }
    println("Done")

the above code produces the below output, if we use "return" on the line 5 we will be getting the below output, because that will abundantly break and come out of the method.  You can see the "Done" is not printed.

I'm in the list Dev
I'm Selected Prd

Hence to resolve we can try out with the label concept available in kotlin,  Since our programming language says there is no explicit label needed for the inline function. we can directly use it as "return@forEach".  But this will also lead to be failed, this produces the below output.

I'm in the list Dev
I'm Selected Prd
I'm in the list Test
I'm in the list Sbx
I'm in the list demo
Done

The highlighted text are unnecessary to this case.  In the below code snippet run block with label is used to break the loop as soon as we get the expected result and breaks the blocks and proceeds the normal flow function flow.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var data = listOf<String>("Dev", "Prd", "Test", "Sbx", "demo")
    run envBlock@{
        data.forEach {
            if (it.equals("Prd")) {
                println("I'm Selected $it")
                return@envBlock
            }
            println("I'm in the list $it")
        }
    }
    println("Done")

And will get the expected output.


I'm in the list Dev
I'm Selected Prd
Done

Happy Coding :-)

Saturday, 17 August 2019

Kotlin Null Handling


- Kotlin Null Safe
- Here we can’t initialise or assign null value.
- If purposely we need to have null, it provides with Question mark.

val username: String? = null

Here we have 4 types of null handling shots.

1. Safe Call
2. Safe Call with let
3. Elvis Operator
4. Non-Null Assertion Operator.

1. Safe Call: It is represented by "?." and this facilitates to access the methods of the object.  In case the reference object or variable is null it will safely handle that and produce the return value as string as "null"

var username: String? = null
println("Username Length is : ${username?.length}")   // We won't get crash, it just print the value as null
username = "manakular"
println("Username Length is : ${username?.length}")

Output:


Username Length is : null
Username Length is : 9

2. Safe Call with let:  It is also similar to the Safe call, instead of accessing the method this allows you to execute the block of code and implicitly returns the last line of the block based on the code,  here "it" keyword will refer the concern data value.

    var username: String? = "manakularpondy"
    val status: String? = username?.let {
        println("Username is $it")
        if (it.length > 10) "Valid Input" else "Invalid length"
    }
    println(status)

Output:

Username is manakularpondy
Valid Input

In case, if we change the value to null  var username: String? = null  the status value will be also null.  So, in order to handle the failure i.e. null scenario we can take help of run block.


    var username: String? = null
    val status: String? = username?.let {
        println("Username is $it")
        if (it.length > 10) "Valid Input" else "Invalid length"
    }.run {
        "Need Input"
    }
    println(status)

Output:

Need Input

3. Elvis Operator: Hope we most of them aware we don't have ternary operator in kotlin programming, but similar to that we are having this elvis operator.  This will be denoted by ?: as mentioned on the below code snippet the username is initialised as null and once we trying to access the length of the variable we are all aware it going to be a null type.   Hence so we are accessing the username value via Safe call (?), then it sees the value as null our elvis operator helps to executes the or take the values after the ?:  Hence here we can see the length value as  0 even the username value is null.    

var username: String? =null
val length: Int = username?.length ?: 0
println("Length is $length")

Output:

Length is 0

4. Non-Null Assertion Operator: This need to handled very carefully, it is referred by using the double exclamation (!!).   Since you are 100% sure the object is non-null then you can use this else the value is null it will throws the null pointer exception.


var username: String? =null
val length: Int = username!!.length ?: 0
println("Length is $length")

The above code snippet throws the null pointer exception, because username object is null

Saturday, 20 July 2019

Kotlin Code - Get IPV4 & IPV6 Address

The below code helps to get the IPv4 and IPv6 Address using Kotlin.

import java.net.NetworkInterface
import java.util.*

/*
* Author: Rajendhiran E
* Date: 21-Jan-2018
* */

object IPHelper {
    val IPV4Address: String
        get() = getIPAddress(true)

    val IPV6Address: String
        get() = getIPAddress(false)

    /**
     * Get IP address from first non-localhost interface
     * @param userIPV4 true=return ipv4, false=return ipv6
     * @return address or empty string
     */
    private fun getIPAddress(userIPV4: Boolean): String {
        try {
            Collections.list(NetworkInterface.getNetworkInterfaces()).forEach {
                Collections.list(it.inetAddresses).forEach {
                    if (!it.isLoopbackAddress) {
                        val sAddr = it.hostAddress
                        val isIPv4 = sAddr.indexOf(':') < 0
                        if (userIPV4) {
                            if (isIPv4) {
                                return sAddr
                            }
                        } else {
                            if (!isIPv4) {
                                val delim = sAddr.indexOf('%')
                                return if (delim < 0) sAddr.toUpperCase() else sAddr.substring(0, delim).toUpperCase()
                            }
                        }
                    }
                }
            }
        } catch (ignored: Exception) {
        }
        return ""
    }
}


println("IP Address V4 - ${IPHelper.IPV4Address}")
println("IP Address V6 - ${IPHelper.IPV6Address}")


Output  Console
IP Address v4 - 192.168.240.2
IP Address v6 - FE80:0:0:0:4D9:5C92:3433:8A6B

Happy Coding :-)