Home Programming Kotlin Programming Cookbook

Kotlin Programming Cookbook

By Aanand Shekhar Roy , Rashi Karanpuria
books-svg-icon Book
eBook $43.99 $29.99
Print $54.99
Subscription $15.99 $10 p/m for three months
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
eBook $43.99 $29.99
Print $54.99
Subscription $15.99 $10 p/m for three months
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
  1. Free Chapter
    Installation and Working with Environment
About this book
The Android team has announced first-class support for Kotlin 1.1. This acts as an added boost to the language and more and more developers are now looking at Kotlin for their application development. This recipe-based book will be your guide to learning the Kotlin programming language. The recipes in this book build from simple language concepts to more complex applications of the language. After the fundamentals of the language, you will learn how to apply the object-oriented programming features of Kotlin 1.1. Programming with Lambdas will show you how to use the functional power of Kotlin. This book has recipes that will get you started with Android programming with Kotlin 1.1, providing quick solutions to common problems encountered during Android app development. You will also be taken through recipes that will teach you microservice and concurrent programming with Kotlin. Going forward, you will learn to test and secure your applications with Kotlin. Finally, this book supplies recipes that will help you migrate your Java code to Kotlin and will help ensure that it's interoperable with Java.
Publication date:
January 2018
Publisher
Packt
Pages
434
ISBN
9781788472142

 

Chapter 1. Installation and Working with Environment

The following recipes will be covered in this chapter:

  • Creating Kotlin Android project
  • How to use Gradle to run Kotlin code
  • How to run a Kotlin compiled class
  • How to build a self-executable jar with Gradle and Kotlin
  • Reading console input in Kotlin
  • Converting Java code to Kotlin and vice versa
  • How to write an idiomatic logger with Kotlin
  • Escaping for Java identifiers that are keywords in Kotlin
  • Disambiguating using the "as" keyword to locally rename the clashing entity
  • Doing bit manipulations in Kotlin
  • Parsing String to Long, Double, or Int
  • Using String templates in Kotlin
 

Introduction


Android apps are a fascinating piece of technology. The apps developed on Android have worldwide appeal and audience. However, that has posed serious challenges for developers. The challenge is with updating APIs, platforms, and varied device capabilities. For example, if you are an Android developer, you have to rely on Java 6 if you want to support all API levels in Android. Java 6 is obsolete now, so much so that even its successor, Java 7, is kind of obsolete today. There was a great need for modern language for Android, which has built a trillion dollar industry around it and has influenced billions of lives. True, we have Java 8 now, but we can only use it if we are developing Android apps for API level 24 and above. However, that’s equivalent to targeting only 9% of Android devices as of 2017; clearly, this isn’t the way to go.

All is not lost though, and thanks to the JVM, we can write Android apps using any language that produces JVM compatible bytecode on compilation. So theoretically, we can use Clojure, Groovy, Scala, and Kotlin, but Kotlin is the best alternative among all, why? It's because in April 2017, Google announced Kotlin as an official language for Android development.

Some of the biggest tech companies such as Pinterest, Uber, Atlassian, Coursera, and Evernote are now using Kotlin in their Android apps. This wide adoption by them already speaks a huge volume for Kotlin. The 100% interoperability with Android and Java has helped Kotlin in its adoption. Kotlin is much easier to work with than Java and, apart from Android apps, you can also build web-apps with it. So, this chapter will introduce you to Kotlin and help you get started with this awesome piece of technology.

In this chapter, we will first see how to set up the environment to begin working with Kotlin.

 

Creating Kotlin Android project


Getting started with Kotlin is really easy, especially after Google has added official support for the language. You can use Kotlin directly with Android Studio 3. Android Studio 3 is still in Beta version at the time of writing this book. The best thing about using Kotlin for Android is that it is interoperable with your existing code, be it Java or C++. While working with Kotlin, you will realize that code in Kotlin is concise, extensible, and powerful. It really makes Android development more fun. Let's see how we can start working in Kotlin by first creating a Kotlin project in Android Studio 3.

Getting ready

To get started with this recipe, you will need Android Studio installed on your computer. Android Studio has both Android SDK and Android Virtual device in it. Ensure that you have Java Development Kit installed on your system. You will need an android phone or Emulator for debugging your project. You will also need at least one Android Virtual Device installed, of your desired specifications if you are not using an Android phone.

So basically, here's the checklist of the things that need to be installed before you move on to the next section:

  • Java Development Kit (use the latest)
  • Android Studio 3+
  • Android phone or emulator

How to do it...

Creating a project in Android Studio is very simple and to create it in Kotlin just requires one extra click. Here's a step-by-step process of doing it:

  1. In Android Studio, in the menu, click on File | New | New Project. Alternatively, if you've just opened Android Studio and see the Welcome to Android Studio window, click on Start a new Android Studio project.
  1. In the wizard, add your Application name and Company domain, and simply check the box that says Include Kotlin support. Click on Next:

  1. On the next screen, you will be asked to choose your target devices and the minimum SDK support. So basically, it asks things like, "Do you want the application to run on both phone and android wear?" and "Do you want to support from Jelly Bean up or KitKat and up?":

  1.  On the next screen, you will be prompted to Add an Activity to the project. You can also skip this step and add an activity later, but for now, just click on a Basic Activity and click on Next. If you have also chosen Wear or any other option, you will be prompted to add activity for those components as well:
  1. Next, you will be prompted to Configure the Activity you added. Basically, what you have to do is to provide Activity Name, Layout Name, and Title. After this, click on Finish, because you are done with creating your first project in Kotlin.
  2. Run project on your device: You need to follow these steps:
    1. Connect your device to your development machine with a USB cable.
    2. Enable USB debugging on your device by going to Settings | Developer options.

Note

On Android 4.2 and newer, Developer options are hidden by default. To make it available, go to Settings | About phone and tap on Build number seven times. Return to the previous screen to find Developer options.

Now in your Android Studio, click on the app module in the Project window and then select Run (or click on Run in the toolbar).

In the Select Deployment Target window, select your device, and click on OK. After a while, you will see the application running on your mobile or an emulator.

There's more...

After clicking on the Finish button in the Create New Project window, Android Studio will configure things and create your project. If you added an activity as mentioned in Step 4, you will be greeted with the boilerplate code of the activity. It looks something like this:

 

 

How to use Gradle to run Kotlin code


Gradle has now become the de facto build tool for Android, and it is very powerful. It’s great for automating tasks without compromising on maintainability, usability, flexibility, extensibility, or performance. In this recipe, we will see how to use Gradle to run Kotlin code.

Getting ready

We will be using IntelliJ IDEA because it provides great integration of Gradle with Kotlin, and it is a really great IDE to work on. You can also use Android Studio for it.

How to do it...

In the following steps, we will be creating a Kotlin project with the Gradle build system. First, we will select the Create New Project option from the menu. Then, follow these steps:

  1. Create the project with the Gradle build system:

  1. After you have created the project, you will have the build.gradle file, which will look something like the following:
version '1.0-SNAPSHOT'

buildscript {
  ext.kotlin_version = '1.1.4-3'

  repositories {
      mavenCentral()
  }
  dependencies {
      classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  }
}

apply plugin: 'java'
apply plugin: 'kotlin'

sourceCompatibility = 1.8

repositories {
  mavenCentral()
}

dependencies {
  compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
  testCompile group: 'junit', name: 'junit', version: '4.12'
}

compileKotlin {
  kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
  kotlinOptions.jvmTarget = "1.8"
}
  1. Now we will create a HelloWorld class, which will have a simple main function:
  1. Now, it would be really cool to run this code directly. To do so, we will use the gradle run command. However, before that, we need to enable the application plugin, which will allow us to directly run this code. We need to add two lines in the build.gradle file to set it up:
apply plugin: 'application'
mainClassName = "HelloWorldKt"
  1. After this, you can type gradle run in the terminal to execute this file, and you will see the output of the method, as shown:

There's more...

The default structure of the project, when you create a new project in IntelliJ, is as illustrated:

project
   - src
       - main (root)
           - kotlin
           - java

If you want to have a different structure of the project, you should declare it in build.gradle. You can do it by adding the following lines in build.gradle.

The corresponding sourceSets property should be updated if not using the default convention:

sourceSets {
   main.kotlin.srcDirs += 'src/main/myKotlin'
   main.java.srcDirs += 'src/main/myJava'
}

Though you can keep Kotlin and Java files under the same package, it’s a good practice to keep them separated.

See also

Check out the How to build a self-executable jar with Gradle and Kotlin recipe in this chapter.

 

How to run a Kotlin compiled class


Working with the command-line compiler for any language is one of the first steps to get a better understanding of the language, and this knowledge comes handy at a lot of times. In this recipe, we will run a Kotlin program using the command line, and we will also play a bit with the interactive shell of Kotlin.

Getting ready

To be able to perform this recipe, you need a Kotlin compiler installed on your development machine. Every Kotlin release ships with a standalone compiler. You can find the latest release at https://github.com/JetBrains/kotlin/releases.

To manually install the compiler, unzip the standalone compiler into a directory and optionally, add the bin directory to the system path. The bin directory contains the scripts needed to compile and run Kotlin on Windows, OS X, and Linux.

How to do it...

Now we are ready to run our first program using the command line. First, we will create a simple application that displays Hello World! and then compile it:

  1. Create a file with the name hello.kt and add the following lines of code in that file:
fun main(args: Array<String>) {
    println("Hello, World!")
 }
  1. Now we compile the file using the following command:
$ kotlinc hello.kt -include-runtime -d hello.jar
  1. Now we run the application using the following command:
$ java -jar hello.jar
  1. Suppose you want to create a library that can be used with other Kotlin applications; we can simply compile the Kotlin application in question into .jar executable without the -include-runtime option, that is, the new command will be as follows:
$ kotlinc hello.kt -d hello.jar
  1. Now, let's check out the Kotlin interactive shell. Just run the Kotlin compiler without any parameters to have an interactive shell. Here's how it looks:

Hopefully, you must have noticed the information I am always guilty of ignoring, that is, the command to quit interactive shell is :quit and for help, it is :help.

You can run any valid Kotlin code in the interactive shell. For example, try some of the following commands:

  • 3*2+(55/5)
  • println("yo")
  • println("check this out ${3+4}")

Here's a screenshot of running the preceding code:

How it works...

The -include-runtime option makes the resulting .jar file self-contained and runnable by including the Kotlin runtime library in it. Then, we use Java to run the .jar file generated.

The -d option in the command indicates what we want the output of the compiler to be called and maybe either a directory name for class files or a .jar filename.

There's more...

Kotlin can also be used for writing shell scripts. A shell script has top-level executable code.

Kotlin script files have the .kts extension as opposed to the usual .kt for Kotlin applications.

To run a script file, just pass the -script option to the compiler:

$ kotlinc -script kotlin_script_file_example.kts
 

How to build a self-executable JAR with Gradle and Kotlin


Kotlin is great for creating small command-line utilities, which can be packaged and distributed as normal JAR files. In this recipe, we will see how to do it using Gradle build system. Gradle build system is one of the most sophisticated build systems out there. It is the default build tool for Android and is designed to ease scripting of complex, multilanguage builds with a lot of dependencies (typical of big projects). It achieves the goal of automating your project without compromising on maintainability, usability, flexibility, extensibility, or performance. We will be using Gradle build system to create a self-extracting JAR file. This JAR file can be distributed to and run on any platform supporting Java.

Getting ready

You need an IDE (preferably IntelliJ or Android Studio), and you need to tell it where your Kotlin files are present. You can do so by specifying it in the build.gradle file by adding the following:

sourceSets {
   main.java.srcDirs += 'src/main/kotlin/'
}

The preceding lines are required if you have your Kotlin files separated from Java packages. This is optional, and you can continue working with Kotlin files under Java packages, but it’s a good practice to keep them separated.

We’ll be creating a very simple function that just prints Hello World! when executed. Since it’ll be a simple function, I am just adding it as a top-level main() function.

How to do it...

Let's go through these steps, with which we can create a self-executable JAR:

  1. We’ll create a simple class HelloWorld.kt having the main function, which just prints out “Hello world!”:
fun main(args:Array<String>){
   println("Hello world")
}
  1. Now we need to configure a jar task, which Gradle build goes through to inform it of our entry to our project. In a Java project, this will be the path to the class where our main() function resides, so you will need to add this jar task in build.gradle:
jar {
   manifest {
       attributes 'Main-Class': 'HelloWorldKt'
   }
   from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
  1. After adding the preceding snippet to build.gradle, you need to run the following gradle command to create the jar file:
./gradlew clean jar
  1. The created jar file can be found in the build/libs folder. Now you can just run the java -jar demo.jar command to run the JAR file.

After you do that, you can see the output in the console:

How it works...

To make self-executable JARs, we need a manifest file called MANIFEST.MF in the META-INF directory. For our purposes here, we just need to specify the name of the Java class that contains the Java-based extractor program's main() method.

One might argue that even though we don’t have top-level class declaration, we are specifying it as HelloWorldKt in the code for the jar task:

manifest {
       attributes 'Main-Class': 'HelloWorldKt'
   }

The reason for putting the preceding code block in the jar task is that Kotlin compiler adds all top-level functions to respective classes for back-compatibility with JVM. So, the class generated by Kotlin compiler will have the filename, plus the Kt suffix, which makes it HelloWorldKt.

Also, the reason we added from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } in jar task is because we want Gradle to copy all of a JAR’s dependencies. The reason for doing so is that, by default, when Gradle (as well as Maven) packs some Java class files into a JAR file, it assumes that this JAR file will be referenced by an application, where all of its dependencies are also accessible in the classpath of the loading application. So, by specifying the preceding lines in jar task, we are telling gradle to take all of this JAR’s referenced dependencies and copy them as part of the JAR itself. In the Java community, this is known as a fat JAR. In a fat JAR, all the dependencies end up within the classpath of the loading application, so the code can be executed without problems. The only downside to creating fat JARs is their growing file size (which kind of explains the name), though it is not a big concern in most situations.

 

Reading console input in Kotlin


In many applications, user interaction is a very important part, and the most basic way of doing that is reading input entered by the user and giving output based on it. In this recipe, we will understand different ways of reading input and also provide output in the console.

Getting ready

You need to install a preferred development environment that compiles and runs Kotlin. You can also use the command line to compile and run your Kotlin code, for which you need Kotlin compiler installed along with JDK.

How to do it...

Let's go through the following steps by which we can read console input in Kotlin:

  1. We will start simple and move to more advanced logic as we move forward. First, let's start with simply printing a line as output in the console:
println("Just a line")
  1. Now we will try to take String input from the console and output it again:
println("Input your first name")
var first_name = readLine()
println("Your first name: $first_name")
  1. Okay, how about we repeat the process with Int:
println("Hi $first_name, let us have a quick math test. Enter two numbers separated by space.")
val (a, b) = readLine()!!.split(' ').map(String::toInt)
println("$a + $b = ${a+b}")
  1. Now, let's try a complicated code and then start with the explanations:
fun main(args: Array<String>) {
   println("Input your first name")
   var first_name = readLine()
   println("Input your last name")
   var last_name = readLine()
   println("Hi $first_name $last_name, let us have a quick math test. Enter two numbers separated by space.")
   val (a, b) = readLine()!!.split(' ').map(String::toInt)
  println("what is $a + $b ?")
  println("Your answer is ${if (readLine()!!.toInt() == (a+b)) "correct" else "incorrect"}")
   println("Correct answer = ${a+b}")
 println("what is $a * $b ?")
   println("Your answer is ${if (readLine()!!.toInt() == (a*b)) "correct" else "incorrect"}")
   println("Correct answer = ${a*b}")
   println("Thanks for participating :)")
}

Here's a screenshot of compiling and running the preceding code:

How it works...

Let's try to understand the methods by which we were able to read input in Kotlin.

Behind the scenes, Kotlin.io uses java.io for the input-output. So println is basically System.out.println, but with additional power by Kotlin to use String templates and inline functions, which makes writing extremely simple and concise.

This is a part of the actual code from Kotlin stdlib used for Console IO:

/** Prints the given message and newline to the standard output stream. */
@kotlin.internal.InlineOnly
public inline fun println(message: Any?) {
   System.out.println(message)
}
 

Converting Java code to Kotlin and vice versa


The best part about Kotlin is its interoperability with Java. Also, with IntelliJ-based IDE, we can directly convert our Java code to Kotlin. In this recipe, we will see how to do it.

Getting ready

This recipe needs IntelliJ-based IDE installed, which compiles and runs Kotlin and Java.

How to do it...

Let's see the steps to convert a Kotlin file to a Java file:

  1. In your IntelliJ IDE, open the Java file that you want to convert to Kotlin.
  2. Note that it has a .java extension. Now, in the main menu, click on Code menu and choose the Convert Java File to Kotlin File option. Your Java file will be converted into Kotlin, and the extension will now be .kt.

Shown here is an example of a Java file:

After converting to Kotlin, this is what we have:

  1. A Kotlin file can be converted into Java, but it's better if you can avoid it or find an alternative way to do it. If you have to absolutely convert your Kotlin code to Java, click on Tools | Kotlin | Show Kotlin Bytecode in the menu:

  1. After clicking on Show Kotlin Bytecode, a window will open with the title Kotlin Bytecode:

  1. Click on Decompile and a .java file will be generated, containing a  decompiled Java bytecode from Kotlin code:

Yes, it has a lot of unnecessary code that was not present in the original Java code, but that is the case with decompiled bytecode. At the moment, this is the only way to convert Kotlin code to Java. Copy the decompiled file into a .java file and remove the unnecessary code.

How it works...

Kotlin is a statically-typed programming language that works on Java Virtual Machine and compiles into JVM compatible bytecode. This is the reason we can convert Java code to Kotlin and mix Java and Kotlin code together.  This is also the reason why you can, in a way, get Java code back from Kotlin (although the output is not completely desired).

 

How to write an idiomatic logger in Kotlin


Kotlin has some great powerful features packed in it that we should be making use of to improve our code. This involves rethinking on our old best practices of coding. Many of our old coding practices can be replaced by better alternatives from Kotlin. One of them is how we write our logger. Though there are a lot of libraries out there that provide logging functionality, we will try to create our own logger in this recipe, just by using idiomatic Kotlin.

Getting ready

We will be using IntelliJ IDE to write and execute our code.

How to do it...

Let's go through the given steps to create an idiomatic logger in Kotlin:

  1. First, let's see how it was done in Java. In Java, SLF4J is used and considered de-facto, so much that logging seems like a solved problem in Java language. Here's what a Java implementation would look like:
private static final Logger logger = LoggerFactory.getLogger(CurrentClass.class);
…
logger.info(“Hi, {}”, name);
  1. It also works fine with Kotlin, obviously with minor modifications:
val logger = LoggerFactory.getLogger(CurrentClass::class)
…
logger.info(“Hi, {}”, name)

However, apart from this, we can utilize the power of Kotlin using Delegates for the logger. In this case, we will be creating the logger using the lazy keyword. This way, we will create the object only when we access it. Delegates are a great way to postpone object creation until we use it. This improves startup time (which is much needed and appreciated in Android). So let us explore a method using lazy delegates in Kotlin:

  1. We'll use java.util.Logging internally, but this works for any Logging library of your choice. So let’s use the Kotlin’s lazy delegate to get our logger:
public fun <R : Any> R.logger(): Lazy<Logger> {
   return lazy { Logger.getLogger(this.javaClass.name) }
}
  1. Now in our class, we can simply call the method to get our logger and use it:
class SomeClass {
  companion object { val log by logger() }

  fun do_something() {
      log.info("Did Something")
  }
}

When you run the code, you can see the following output:

Sep 25, 2017 10:49:00 PM packageA.SomeClass do_something
INFO: Did Something

So, as we can see in the output, we get the class name and method name too (if you are accessing logger inside a method).

How it works...

Here, one thing to note is that we have put our logger inside a companion object. The reason for this is quite straightforward because we want to have only one instance of logger per class.

Also, logger() returns a delegate object, which means that the object will be created on its first access and will return the same value (object) on subsequent accesses.

There's more...

Anko is an Android library that uses Kotlin and makes Android development easier with the help of extension functions. It provides Anko-logger, which you can use if you don’t want to write your own logger. It is included in anko-commons, which also has a lot of interesting things to make it worthwhile to include it in your Android projects that use Kotlin.

In Anko, a standard implementation of logger will look something like this:

class SomeActivity : Activity(), AnkoLogger {
   private fun someMethod() {
       info("London is the capital of Great Britain")
       debug(5) // .toString() method will be executed
       warn(null) // "null" will be printed
   }
}

As you can see, you just need to implement AnkoLogger and you are done.

Each method has two versions: plain and lazy (inlined):

info("String " + "concatenation")
info { "String " + "concatenation" }

The lambda result will be calculated only if Log.isLoggable(tag, Log.INFO) is true.

See also

To know more about delegated properties, refer to the Working with delegated Properties recipe in Chapter 3Classes and Objects.

 

Escaping for Java identifiers that are keywords in Kotlin


Kotlin was designed with interoperability in mind. The existing code in Java can be called from Kotlin code smoothly, but since Java has different keywords than Kotlin, we sometimes run into issues when we call Java method with a name similar to Kotlin keyword. There is a workaround in Kotlin, which allows a method to be called having a name representing a Kotlin keyword.

Getting ready

Ensure that you have access to a code editor where you can write and run the code.

How to do it...

Create a Java class with a method name equal to any Kotlin keyword. I am using is as the method name, so my Java class looks as follows:

public class ASimpleJavaClass {
   static void is(){
       System.out.print("Nothing fancy here");
   }
}

Now try calling that method from Kotlin code. If you are using any code editor with the autocomplete feature, it automatically encloses the method name in backticks (` `):

fun main(args: Array<String>) {
   ASimpleJavaClass.`is`()   
}

Similar is the case with other keywords in Kotlin that are qualified identifiers in Java.

How it works...

According to Kotlin’s documentation, some of the Kotlin keywords are valid identifiers in Java: in, object, is, and so on. If a Java library uses a Kotlin keyword for a method, you can still call the method, escaping it with the backtick (`) character.

The following are the keywords in Kotlin:

package

as

typealias

class

this

super

val

var

fun

for

null

true

false

is

in

throw

return

break

continue

object

if

try

else

while

do

when

interface

typeof

 

Disambiguating using the "as" keyword to locally rename the clashing entity


Disambiguation refers to the removal of ambiguity by making something clear. Importing a library or a class in code is a daily routine of a programmer. It’s pretty easy to import files into the code in every language, thanks to the great code editors nowadays.

However, what happens if you try to import two classes into a file? Though you should always try to have different names for different classes, sometimes it’s unavoidable. For example, in the case of different libraries having the same name for their classes. In Java, there is a workaround; you have to use the full qualifier, which looks something like this:

class X {
   com.very.very.long.prefix.bar.Foo a;
   org.other.very.very.long.prefix.baz.Foo b;
   ...
}

Dirty, isn’t it? Now, let’s see how Kotlin addresses it gracefully.

Getting ready

Ensure that you have a code editor on which you can write and run the code. To test things out, you can create two classes with the same name but under different packages. Refer to the example here:

How to do it...

In the following steps and examples, we will see how we can disambiguate classes of the similar name using Kotlin's keyword.

  1. In Kotlin, you can disambiguate using the as keyword to locally rename the clashing entity. So in Kotlin, it will look as shown:
import foo.Bar // Bar is accessible
import bar.Bar as bBar // bBar stands for 'bar.Bar'
  1. Then, access their methods like this:
Bar.methodOfFooBar()
bBar.methodOfBarBar()

For example, let's see the use of the as keyword to disambiguate two classes having the same name (SomeClass.kt), but in different packages:

SameClass.kt (packageA)

package packageA
class SameClass {
  companion object {
      fun methodA(){
          println("Method a")
      }
  }
}

SameClass.kt (packageB)

package packageB
class SameClass {
  companion object {
      fun methodB(){
          println("Method b")
      }
  }
}

HelloWorld.kt is the class that uses classes with similar names:

import packageA.SameClass as anotherSameClass
import packageB.SameClass
fun main(args: Array<String>) {
   anotherSameClass.methodA()
   SameClass.methodB()

}
 

Doing bit manipulations in Kotlin


Kotlin provides several functions (in infix form) to perform bitwise and bit shift operations. In this section, we will learn to perform bit-level operation in Kotlin with the help of examples.

Bitwise and bit shift operators are used on only two integral types—Int and Long—to perform bit-level operations.

Getting ready

Here's the complete list of bitwise operations (available for Int and Long only):

  • shr(bits): signed shift right (Java's >>)
  • ushr(bits): unsigned shift right (Java's >>>)
  • and(bits): bitwise and
  • or(bits): bitwise or
  • xor(bits): bitwise xor
  • inv(): bitwise inversion

How to do it...

Let's check out a few examples to understand the bitwise operations.

Or

The or function compares the corresponding bits of two values. If either of the two bits is 1, it gives 1, and it gives 0 if not.

Consider this example:

fun main(args: Array<String>) {
  val a=2
  val b=3
  print(a or b)
}

The following is the output:

 3

Here's the explanation of the preceding example:

2 = 10 (Binary format)

3 = 11 (Binary format)

 Bitwise OR of 2 and 3 that is

in binary 

 10 OR 11

 11 = 3 (Decimal format)

and

The and function compares the corresponding bits of two values. If either of the two bits is 0, it gives 0, if not and both bits are 1, it gives 1.

Consider this example:

fun main(args: Array<String>) {
  val a=2
  val b=3
  print(a and b)
}

 

This is the output:

 2

Let's look at the explanation:

2 = 10 (Binary format)

3 = 11 (Binary format)

Bitwise AND of 2 and 3

              in binary

10 AND 11

10 = 2 (Decimal format)

xor

The xor function compares the corresponding bits of two values. If the corresponding bits are the same, it gives 0, and if they are different, it gives 1.

Look at this example:

fun main(args: Array<String>) {
  val a=2
  val b=3
  print(a xor b)
}

Given is the output:

 1

Here's the explanation:

2 = 10 (Binary format)

3 = 11 (Binary format)

Bitwise XOR of 2 and 3

                    in binary

10 XOR 11

01 = 1 (Decimal format)

inv

The inv function simply inverts the bit patterns. If the bit is 1, it makes it 0 and vice versa.

Here's an example:

fun main(args: Array<String>) {
    val a=2
   print(a.inv())}

This is the output:

 -3

The following is the explanation:

2 = 10 (Binary format)

Bitwise complement of 2 = 01, but the compiler shows 2’s complement of that number, which is the negative notation of the binary number.

2’s complement of an integer n is equal to -(n+1).

 

shl

The shl function shifts the bit pattern to the left by the specified number of bits.

Consider this example:

fun main(args: Array<String>) {
       println( 5 shl 0)
       println( 5 shl 1)
       println( 5 shl 2)
}

This is the output:

5
10
20

Here's the explanation:

5 = 101 (Binary format)

101 Shift left by 0 bits = 101

101 Shift left by 1 bits = 1010 (10 in Decimal)

101 Shift left by 2 bits = 10100 (20 in Decimal)

 

shr

The shr function shifts the bit pattern to the right by the specified number of bits.

Take this example into consideration:

fun main(args: Array<String>) {
       println( 5 shr 0)
       println( 5 shr 1)
       println( 5 shr 2)
}

Given here is the output:

5
2
1

The following is the explanation:

5 = 101 (Binary format)

101 Shift right by 0 bits = 101

101 Shift right by 1 bits = 010 (2 in Decimal)

101 Shift right by 2 bits = 001 (1 in Decimal)

ushr

The ushr function shifts the bit pattern to the right by the specified number of bits, filling the leftmost with 0s.

Here's an example:

fun main(args: Array<String>) {
       println( 5 ushr 0)
       println( 5 ushr 1)
       println( 5 ushr 2)
}

This will output the following:

5
2
1

This is its explanation:

5 = 101 (Binary format)

101 Shift right by 0 bits = 101

101 Shift right by 1 bits = 010 (2 in Decimal)

101 Shift right by 2 bits = 001 (1 in Decimal)

How it works...

The bitwise operators in Kotlin aren’t built-in operators like in Java, but they can still be used as an operator. Why? Look at its implementation:

public infix fun shr(bitCount: Int): Int

You can see that the method has the infix notation, which enables it to be called as an infix expression.

 

Parsing String to Long, Double, or Int


Kotlin makes it really easy to parse String into other data types, such as Long, Integer, or Double.

In JAVA, Long.parseLong(), or the Long.valueOf() static method is used, which parses the string argument as a signed decimal long and returns a long value, and similarly for other data types such as Int, Double, and Boolean. Let’s see how to achieve it in Kotlin.

Getting ready

You just need a Kotlin editor to write and run your code. We’ll use conversion of Long as an example to discuss parsing with string. Conversion to other data types is quite similar.

How to do it...

To parse the string to a Long data type, we use the .toLong() method with the string. It parses the string as a Long number and returns the result. It throws NumberFormatException if the string is not a valid representation of a number. Later, we will see examples for this.

Converting String to Long

Here's an example that shows parsing of string to Long:

fun main(args: Array<String>) {
  val str="123"
  print(str.toLong())
}

When you run the preceding code, you will see this output:

123

If you don’t want to deal with the exceptions, you can use .toLongOrNull(). This method parses the string as a Long and returns the result, or null if the string is not a valid representation of a number.

Converting string to Long using string.toLongOrNull()

In this example, we will see how we can parse a string using the .toLongOrNull() method:

fun main(args: Array<String>) {
  val str="123.4"
  val str2="123"
  println(str.toLongOrNull())
  println(str2.toLongOrNull())
}

On running the preceding program, the following output is generated:

 null 123
Converting with special radix

All the preceding examples use the base (radix) 10. There are cases when we wish to convert a String to Long but using another base. Both string.toLong() and string.toLongOrNull() can receive a custom radix to be used in the conversion. Let's take a look at its implementation:

  • string.toLong(radix):
    • This parses the string as a [Long] number and returns the result
    • @throws NumberFormatException if the string is not a valid representation of a number
    • @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion
  • string.toLongOrNull(radix):
    • This parses the string as a [Long] number and returns the result or null if the string is not a valid representation of a number
    • @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion

Parsing string to Long with special radix

In the preceding examples, we were parsing strings with radix 10, that is, decimals. By default, the radix is taken as 10, but there are certain situations where we need different radix. For example, in case of parsing a string into a binary or octal number. So now, we will see how to work with radix other than the decimal. Though you can use any valid radix, we will show examples that are most commonly used, such as binary and octal.

  • Binary: Since a binary number is made from 0 and 1, the radix used is 2:
fun main(args: Array<String>) {
       val str="11111111"
       print(str.toLongOrNull(2))   }

On running the preceding program, the following output is generated:

 255
  • Octal: The octal numeral system, or oct for short, is the base-8 number system and uses the digits 0 to 7. Hence, we will use 8 as a radix:
fun main(args: Array<String>) {
      val str="377"
       print(str.toLongOrNull(8))
   }

On running the preceding program, this output is generated:

 255
  • Decimal: The decimal system has 10 numbers in it (0-9); hence, we will use 10 as radix. Note that radix as 10 is used by default in the methods without the radix arguments (.toLong() , .toLongOrNull()):
fun main(args: Array<String>) {
      val str="255"
       print(str.toLongOrNull(10))
   }

On running the preceding program, the following output is generated:

 255

How it works...

Kotlin uses String’s extension functions such as .toLong() and toLongOrNull() to make things easier. Let’s dive into their implementation.

  • For Long, use this:
public inline fun String.toLong(): Long = java.lang.Long.parseLong(this)

As you can see, internally, it also calls the Long.parseLong(string) Java static method, and it is similar to the other data types.

  • For Short, it's the following:
public inline fun String.toShort(): Short = java.lang.Short.parseShort(this)
  • Use this for Int:
public inline fun String.toInt(): Int = java.lang.Integer.parseInt(this)
  • For parsing with Radix, use the following:
public inline fun String.toLong(radix: Int): Long = java.lang.Long.parseLong(this, checkRadix(radix))

The checkRadix method checks whether the given [radix] is valid radix for string to number and number to string conversion.

There's more...

Let’s quickly see a few other extension functions provided by Kotlin to parse String:

  • toBoolean(): Returns `true` if the content of this string is equal to the word true, ignoring case, and `false` otherwise.
  • toShort(): Parses the string as a [Short] number and returns the result. Also, it throws NumberFormatException if the string is not a valid representation of a number.
  • toShort(radix): Parses the string as a [Short] number and returns the result, throws NumberFormatException if the string is not a valid representation of a number, and throws IllegalArgumentException when [radix] is not a valid radix for the string to number conversion.
  • toInt(): Parses the string as an [Int] number and returns the result and throws NumberFormatException if the string is not a valid representation of a number.
  • toIntOrNull(): Parses the string as an [Int] number and returns the result or `null` if the string is not a valid representation of a number.
  • toIntOrNull(radix): Parses the string as an [Int] number and returns the result or `null` if the string is not a valid representation of a number, or @throws IllegalArgumentException when [radix] is not a valid radix for string to number conversion.
  • toFloat(): Parses the string as a [Float] number and returns the result, and @throws NumberFormatException if the string is not a valid representation of a number.
  • toDouble() : Parses the string as a [Double] number and returns the result, and @throws NumberFormatException if the string is not a valid representation of a number.
 

Using String templates in Kotlin


Kotlin packs great features with commonly used data type String. One of the really cool features is String templates. This feature allows Strings to contain template expression.

In Java, you had to use StrSubstitutor (https://commons.apache.org/proper/commons-text/javadocs/api-release/org/apache/commons/text/StrSubstitutor.html) and a map to go with it. A template expression in Java will look as follows:

Map<String, String> valuesMap = new HashMap<String, String>();
valuesMap.put("city", "Paris");
valuesMap.put("monument", "Eiffel Tower");
String templateString ="Enjoyed ${monument} in ${city}.";
StrSubstitutorsub=newStrSubstitutor(valuesMap);
String resolvedString =sub.replace(templateString);

Kotlin eases out the pain in writing template expressions and makes it fun, concise, and a lot less verbose.

Using String templates, you can embed a variable or expression inside a string without string concatenation. So, let’s get started!

How to do it...

In the following steps, we will learn how to use String templates:

  1. In Kotlin, the template expression starts with a $ sign.
  2. The syntax of string templates is as follows:
$variableName

Alternatively, it is this:

${expression}
  1. Let's check out a few examples:
  • Consider the example of a String template with variable:
fun main(args: Array<String>) {
    val foo = 5;
    val myString = "foo = $foo"
    println(myString)
 }

The output of the preceding code will be foo = 5.

  • Consider the example of a String template with expression:
fun main(arr: Array<String>){
  val lang = "Kotlin"
  val str = "The word Kotlin has ${lang.length} characters."
  println(str)
}
  • Consider the example of a String template with raw string:
    • Raw string: A string consisting of newlines without writing \n and arbitrary string. It's a raw string and is placed in triple quotes ("""):
fun main(args: Array<String>) {
    val a = 5
    val b = 6

    val myString = """
    ${if (a > b) a else b}
 """
    println("Bigger number is: ${myString.trimMargin()}")
 }

When you run the program, the output will be Bigger number is: 6.

How it works...

The use of String template with a variable name is quite straightforward. Earlier, we used to concatenate the strings, but now we can just specify the variable with the $  symbol before it.

When the string template is used as an expression, the expression inside the ${..} is evaluated first and the value is concatenated with the string. In the preceding example (String template with raw string), the ${if (a > b) a else b} expression is evaluated and its value, that is 6, is printed with the string.

There’s more...

String templates also come in handy with String properties and functions. Here's an example:

fun main(args: Array<String>) {
      val str1="abcdefghijklmnopqrs"
       val str2="tuvwxyz"
       println("str1 equals str2 ? = ${str1.equals(str2)}")
       println("subsequence is ${str1.subSequence(1,4)}")
       println("2nd character is ${str1.get(1)}")
   }

Here's the output:

str1 equals str2 ? = false
subsequence is bcd
2nd character is b
About the Authors
Latest Reviews (1 reviews total)
The platform is so good that I can buy the book only in a minute.
Kotlin Programming Cookbook
Unlock this book and the full library FREE for 7 days
Start now