Baeldung on Kotlin https://www.baeldung.com/kotlin Learn about Kotlin in practice Sat, 08 Jan 2022 15:35:15 +0000 en-US hourly 1 Initialize a Map in Kotlin https://www.baeldung.com/kotlin/initialize-map https://www.baeldung.com/kotlin/initialize-map#respond Sat, 08 Jan 2022 15:35:15 +0000 https://www.baeldung.com/kotlin/?p=51261 A quick and practical guide to initializing a Map in Kotlin.

The post Initialize a Map in Kotlin first appeared on Baeldung on Kotlin.]]>
1. Overview

In this tutorial, we’ll look at some ways to initialize a Map in Kotlin. First, we’ll go through methods like mapOf and mutableMapOf.

Then, we’ll look at some functions to create more specific map implementations.

2. Using mapOf

The most common way to initialize a map is to use the mapOf factory method. Using mapOf, we can create an immutable Map with some initial entries:

val mapWithValues = mapOf("Key1" to "Value1", "Key2" to "Value2", "Key3" to "Value3")

Note that we don’t need to specify the type explicitly here. In contrast, this isn’t the case when we create an empty map:

val mapWithoutValues = mapOf<String, String>()

This creates an empty immutable map of the specified type. This is the same as using the emptyMap:

val emptyMap = emptyMap<String, String>()

3. Using mutableMapOf

Similarly, we can use the mutableMapOf factory method to create a MutableMap:

val emptyMutableMap = mutableMapOf<String, String>()
emptyMutableMap["Key"] = "Value"

Alternatively, we can initialize the map with some values and still be able to add/modify the map later:

val mutableMap = mutableMapOf("Key1" to "Value1", "Key2" to "Value2", "Key3" to "Value3")
mutableMap["Key3"] = "Value10" // modify value
mutableMap["Key4"] = "Value4" // add entry
mutableMap.remove("Key1") // delete existing value

4. Using hashMapOf

With the hashMapOf function, we can create a HashMap:

val hashMap = hashMapOf("Key1" to "Value1", "Key2" to "Value2", "Key3" to "Value3")

As we know, HashMap is mutable. Hence, we can add/modify its entries post-creation:

hashMap["Key3"] = "Value10" // modify value
hashMap["Key4"] = "Value4" // add entry
hashMap.remove("Key1") // delete existing value

5. Using sortedMapOf and linkedMapOf

In Kotlin, we also have access to functions to create other specific maps:

val sortedMap = sortedMapOf("Key3" to "Value3", "Key1" to "Value1", "Key2" to "Value2")
val linkedMap = linkedMapOf("Key3" to "Value3", "Key1" to "Value1", "Key2" to "Value2")

As the name suggests, sortedMapOf creates a mutable SortedMap. Likewise, the linkedMapOf function creates a LinkedMap object.

6. Conclusion

Kotlin has a variety of functions to create maps. The most commonly used are the mapOf and mutableMapOf.

On the other hand, some use cases (such as legacy code bases) may require specific maps. For these cases, we also have access to more specific factory functions.

As always, the code samples are available over on GitHub.

The post Initialize a Map in Kotlin first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/kotlin/initialize-map/feed 0 https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-01-k-150x150.png
Using Swagger (OpenAPI) for a Spring REST API With Kotlin https://www.baeldung.com/kotlin/swagger-spring-rest-api https://www.baeldung.com/kotlin/swagger-spring-rest-api#respond Mon, 03 Jan 2022 10:53:38 +0000 https://www.baeldung.com/kotlin/?p=51244 Learn how to use OpenAPI to document a Kotlin Spring REST API.

The post Using Swagger (OpenAPI) for a Spring REST API With Kotlin first appeared on Baeldung on Kotlin.]]>
1. Introduction

The Swagger specification is now better known as OpenAPI Specification. Although Smartbear still supports some of the tools – for instance, Swagger annotations for Java and Kotlin code – wherever possible, it’s best to use OpenAPI versions of everything.

Here, we’ll touch on the advantages of OpenAPI specification in our projects. There are two main approaches: either we have the code and want to generate a specification for it, or we have a specification and now want to generate some code.

In either case, OpenApi/Swagger tools provide an automatic API documentation page.

2. Introducing OpenAPI to a Spring Boot Project

Let us use Gradle to set up our project. We will create a project with Gradle, Kotlin, and JDK 17 on Spring Initializr. Spring Web framework will be our only dependency. Then, we can download a project that is ready to run.

To start displaying documentation in our project, it’s enough to add three dependencies:

implementation("org.springdoc:springdoc-openapi-data-rest:1.6.0")
implementation("org.springdoc:springdoc-openapi-ui:1.6.0")
implementation("org.springdoc:springdoc-openapi-kotlin:1.6.0")

That’s it. Now, we can run the project and access http://localhost:8080/swagger-ui.html. An empty documentation page will appear. Let’s populate it.

3. Generating a Specification From Existing Code

Often, we come to a project that already has some history. Such projects expose their API, but onboarding new clients to that API is usually fraught with difficulties. As usual, everything changes, and the documentation becomes obsolete the day it’s published.

Using our code as the source of truth for our documentation ensures that the documentation always stays relevant. This makes especially good sense if we provide the API to the users outside our organization. Therefore, we can make a new version without consulting anyone. Then we notify our clients when the new set of APIs comes online.

3.1. Using Annotations to Generate a Specification

To achieve the goal of generated documentation, we must annotate our code, both REST controllers and models that serve as arguments and returned values. For the models, we should take a look at the @Schema annotation. It’s the main annotation for data transfer classes:

@Schema(description = "Model for a dealer's view of a car.")
data class DealerCar(
  // Other fields
  @field:Schema(
    description = "A year when this car was made",
    example = "2021",
    type = "int",
    minimum = "1900",
    maximum = "2500"
  )
  val year: Int,
  // More fields
)

This annotation has many attributes: to specify value range, to provide an example value, and to specify a format of a string field, among others. We need to use a Kotlin-specific field target on class fields so that the swagger-core library will process them correctly.

The methods of our REST controller have @Operation annotations explaining their purpose and usage. We can also specify return codes and explain cases in which we return them:

    @Operation(summary = "Sets a price for a chosen car", description = "Returns 202 if successful")
    @ApiResponses(
      value = [
          ApiResponse(responseCode = "202", description = "Successful Operation"),
          ApiResponse(responseCode = "404", description = "Such a car does not exist"),
      ]
    )
    @PostMapping("/price/{carId}", consumes = ["application/json"])
    fun setPrice(
      @PathVariable carId: Int,
      @RequestBody @OASRequestBody(
        description = "New price for the car",
        content = [Content(
          mediaType = "application/json",
          schema = Schema(type = "number", format = "float", minimum = "0.0", example = "23000.34"),
        )]
      ) price: BigDecimal
    ): ResponseEntity<Unit> {
        carService.setPrice(carId, price)
        return ResponseEntity.accepted().build()
    }

Here, we can specify all the responses our method is likely to return and the request body it takes as an argument. Needless to say, this approach may quickly become unmanageable, with the annotations taking much more space than the actual code, so it often pays off to start with a specification.

4. Generating a Server or Client From an Existing Specification

Both complying with a specification on the client and writing an HTTP web-point is often repetitive and tedious. By generating that code, we make our life easier.

Another use of having a specification first is that it’s easier to agree upon a specification between the front-end and back-end.

And, as we already saw, we can achieve more readable sources by keeping the specification and the code apart.

4.2. Using a Specification File to Create a Spring Server

First, we need to create a specification file. An example of such is on the Swagger Online Editor site. However, for a simple demonstration, we’ll use a more straightforward setup which can be found over on our GitHub.

Then, we’ll use the OpenAPI Generator tool. It’s available as a standalone CLI tool and, as such, is supposed to run once to kick the project off. However, when it runs every time the specification changes instead, it provides us with a constant feedback loop on how compliant we are with the specification. Thus, it brings the most advantage.

So, we’ll add it to our project build.gradle.kts:

// The values oasPackage, oasSpecLocation, oasGenOutputDir are defined earlier
tasks.register("generateServer", org.openapitools.generator.gradle.plugin.tasks.GenerateTask::class) {
    input = project.file(oasSpecLocation).path
    outputDir.set(oasGenOutputDir.get().toString())
    modelPackage.set("$oasPackage.model")
    apiPackage.set("$oasPackage.api")
    packageName.set(oasPackage)
    generatorName.set("kotlin-spring")
    configOptions.set(
      mapOf(
        "dateLibrary" to "java8",
        "interfaceOnly" to "true",
        "useTags" to "true"
      )
    )
}

We have to remember to add a dependency on this task into KotlinCompile tasks and add the generated source into the main source set. This plugin can generate the whole REST server, and then we have to supply an ApiDelegate with actual business logic. But for our purposes, just the interfaces are enough:

class CarCrudController(private val carService: CarService) : CarsApi {
    override fun createCar(carBody: CarBody): ResponseEntity<Car> = TODO("Implementation")
    override fun getCar(id: Int): ResponseEntity<Car> = TODO("Implementation")
    override fun getCars(): ResponseEntity<List<Car>> = TODO("Implementation")
}

4.3. Generating a Client From an Existing Specification

Similar to the server generation, we can create a client as well. We just need to change one line in the Gradle script and use generatorName.set(“kotlin”). After that, we should add the necessary dependencies for the client:

implementation("com.squareup.moshi:moshi-kotlin:1.13.0")
implementation("com.squareup.moshi:moshi-adapters:1.13.0")
implementation("com.squareup.okhttp3:okhttp:4.9.3")

Then, we can just call the client:

val car = CarsApi("http://localhost:8080")
  .createCar(ClientCarBody(model = "CM-X", make = "Gokyoro", year = 2021))

5. Conclusion

In this tutorial, we discussed how OpenAPI, the successor of Swagger, can be used to create an API specification if we have source code implementing that API, create the code from the specification, and display user-friendly documentation generated from the same specification.

As usual, the code from the samples can be found over on GitHub.

The post Using Swagger (OpenAPI) for a Spring REST API With Kotlin first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/kotlin/swagger-spring-rest-api/feed 0 https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-01-k-150x150.png
Composing Coroutines and Suspend Functions https://www.baeldung.com/kotlin/composing-coroutines-suspend-functions https://www.baeldung.com/kotlin/composing-coroutines-suspend-functions#respond Sun, 26 Dec 2021 15:51:50 +0000 https://www.baeldung.com/kotlin/?p=51230 Learn how to work with coroutines in Kotlin and how to compose them together.

The post Composing Coroutines and Suspend Functions first appeared on Baeldung on Kotlin.]]>
1. Introduction

In this tutorial, we’ll look into various types of coroutines we might want to create in our application and how to compose them together.

Often articles concerning coroutines only deal with the “Hello, world!” level of scenarios. However, our real-life tasks or already written code are much more complex. This is why we want to bridge that gap and provide some useful tools on how to deal with multiple aspects of a multi-threaded concurrent application.

2. A Task Closer to The Reality

Let’s consider a task that might arise during our actual work project. To meet the requirements for the task we must:

  1. make two requests to other endpoints, the order of the requests doesn’t matter
  2. apply some business logic
  3. write the result of the business logic procedure into the database via JDBC
  4. log some information for audit and debug
  5. return the response to the user

Let’s use coroutines where possible. Then some of the steps will lend themselves naturally to the coroutine approach, like two HTTP requests. Others, like a JDBC operation, are blocking and therefore will need more thinking:

fun processCallAsync(userInput: UserInput): Deferred<String> = async {
    val responseA = client.get(urlA, userInput.query)
    val responseB = client.get(urlB, userInput.query)
    (responseA.body + responseB.body)
      .also {
          storeToDatabase(userInput, it)
          logger.info("User input $userInput was processed with the result $it")
      }
}

The important part of the business logic step is that it requires both responses, so it is enough to just concatenate the responses.

3. Understanding Context

Coroutines are a language construct, not an actual representation of what is happening inside the Virtual Machine. Like any other set of instructions in JVM-universe, coroutines must have a thread on which to run. Threads, in their turn, shouldn’t live unattached to anything but should reside in thread pools.

Apart from this, coroutines might need some business information to use during their runtime. One example of this is the MDC context. We can also redefine the uncaught exception handler and other settings.

All that can be done inside a construct that is called CoroutineContext. A CoroutineContext is usually provided by a CoroutineScope. A CoroutineScope manages the lifecycle of the coroutines it creates.

The most important part of a CoroutineContext is a CoroutineDispatcher: it defines the thread pool which provides the thread for the set of instructions which is the coroutine.

So, which parts of our “real” function do we want to execute in the same context and which we would like to separate?

There are three reasons to separate contexts:

  • The function within a coroutine might block the thread which executes it, thus preventing other coroutines from using the same thread. This defeats the purpose of having cooperative concurrency. The context for a blocking task should contain its dispatcher.
  • The lifecycle of a sub-coroutine might differ from its creator. We might want to proceed with it even if the creator fails, or we might want to make sure that the creator will proceed no matter what happens to the sub-coroutine. The context for such tasks shouldn’t be a child of the caller context.
  • We are adding new keys to a CoroutineContext. This is possible only by creating a new child context.

4. Blocking Input-Output Tasks

The advantage of coroutines is that due to their collaborative nature they can satisfy the same set of requirements as traditional threaded code by a lesser number of threads. However, the computational load for the coroutine code isn’t lower than for the threaded code. In fact, since during runtime coroutines are compiled to a state-machine with a certain amount of additional instructions for switching between the coroutines, the computational load for coroutine-assisted code is slightly higher. So if tasks performed by coroutines are CPU-heavy we won’t get many advantages out of them.

The same is true for the IO-tasks if they block the thread in which they run. While the thread waits for the completion of an IO operation, it cannot do anything. This might even starve the CoroutineDispatcher out of threads, leading to Denial of Service.

4.1. A Separate Context For IO

It would be a good idea to at least offload blocking IO-tasks to a separate context. That way a sudden slowdown in disk or database operations won’t reduce the throughput of the main function:

launch(Dispatchers.IO) {
    storeToDatabase(userInput, it)
}

Kotlin coroutine library offers a standard Dispatchers.IO dispatcher for such tasks. We must remember, however, that it is the default JVM ForkJoinPool, and it is relatively easy to starve it out of threads.

Another approach we can choose is to use FileChannels for file operations and R2DBC connectors to relational databases. That is to say, it is reasonable to go fully asynchronous in a coroutine-based application.

4.2. A Dedicated Executor For IO Tasks

Still, another way to address the problem would be to post our tasks to a queue and consume that queue with a single thread. Between posting a task and receiving an answer the producer thread is free:

class AsyncWorker(val writerFunction: (Pair<UserInput, String>) -> Int) {
    private val executor = Executors.newSingleThreadExecutor()

    fun submit(input: Pair<UserInput, String>): CompletableFuture =
      CompletableFuture.supplyAsync({ writerFunction(input) }, executor)
}

fun storeToDatabaseAsync(userInput: UserInput, result: String): CompletableFuture<Int> =
  asyncDbWriter.submit(userInput to result)

We may note how an Executor implements both the queue and its handling for us. When we want to see the result of this task, we can block the coroutine (but not its thread!) with an extension function await() from the helper library kotlinx-coroutines-jdk8:

storeToDatabaseAsync(userInput, result).await()

5. Map-Reduce Pattern in Asynchronous Tasks

Now that we have got the complex IO task out of the way let’s deal with the thing the coroutines were invented for: simultaneous asynchronous network calls. There is no reason whatsoever to stay blocked and keep all that context loaded while crucial hundreds of milliseconds slip away.

5.1. Concurrent Launching of a Coroutine

Kotlin promotes the concept of explicit concurrency: nothing we write in Kotlin will run in another thread unless we consciously and intentionally ask the system to do so. In our case it means that to get those two network calls on the wire at roughly the same time we need to wrap them into async {}:

val responseA = async { client.get(urlA, userInput.query) }
val responseB = async { client.get(urlB, userInput.query) }
return responseA.await().body + responseB.await().body

When we need the results, we execute await() on the Deferred objects that async calls gave us. This approach is reminiscent of a Map-Reduce pattern – first we “map” our queries to various URLs and then we “reduce” their responses to compose a final answer.

5.2. Bulk Concurrent Launching

However, our example is still a very simple one. Sometimes we need to call many sources known only at runtime, or just a lot of similar resources. In that case, we cannot create a variable for each such call. Instead, we can place all the calls via async{} first. They will execute as soon as possible, however, the coroutine will continue its execution until we awaitAll() on them:

val result: List<Response> = urls.map { url -> async { client.get(url, userInput.query) } }
  .awaitAll()

We must remember, though, that awaitAll() will fail even if one of the requests fails. It will also cancel the scope we are running in. Alternatively, we can await each one of them in case we can tolerate some failures:

urls.map { url -> async { runCatching { client.get(url, userInput.query) } } }
  .mapNotNull { deferred ->
      deferred.await().fold(
        onSuccess = { it },
        onFailure = {
            logger.error("Error during one of the calls", it)
            null
        }
      )
  }

Such an approach can be useful for aggregator sites: even if one of our providers (e.g., a car rental provider) hasn’t answered, we can still return the rest of the results.

Similarly to awaitAll(), there is a joinAll() call in case we aren’t interested in the result of the operations, just in their success, and therefore used launch{} to start them:

results.map { launch { storeToDatabase(userInput, it) } }.joinAll()

6. Fire and Forget Coroutines

It can also happen that the result of the operation isn’t interesting to us. For instance, it is an audit logging and we just want it done sometime after the operation completes. In such cases, we may use the launch {} function.

We might want to launch these fire-and-forget operations in the same context or another one. Another context might be a child of our original context or else it might be on its own. The difference is mainly in cancellation: should our main context be canceled, all of our coroutines within it will be canceled as well. The same is true for related context: the cancellation of a parent context means the cancellation of all its children:

launch {
    logger.info("User input $userInput was processed with the result $it")
}

For the audit log, it makes sense to only complete it if the action overall is successful, so we will use the same context.

In other cases, we might want to make sure that the launched set of instructions actually succeeded before moving forward. This is easy because a launch {} call will return a Job instance, which we can then join(): 

launch(Dispatchers.IO) {
    storeToDatabase(userInput, it)
}.join()

7. Bridging Normal and Suspending Functions

The coroutine approach is easiest when the whole application is built with it in mind, like a Ktor application. However, even traditional threaded applications may benefit from coroutines, if they do many non-CPU tasks. Then the question arises: how to launch a root coroutine, which launches everything else?

The simplest way is to just use runBlocking:

runBlocking {
    processCallAsync(userInput).await()
}

Then the thread where we do this will block until the argument lambda finishes or throws. Or we can do it in a fire-and-forget style:

fun processCallAndForget(userInput: UserInput) = launch {
    processCallAsync(userInput)
}

The launch call will return a Job object, which we might want to cancel or check if it is still active (isActive). In case we want to block until it finishes, we can do that as well:

val job = launch { /*coroutine code here*/ }
runBlocking {
    job.join()
}

However, joining suspends and has to be wrapped in runBlocking.

8. Conclusion

In this article, we carefully considered the lifecycle of each subroutine within a coroutine section of our application. Some of them are fine as simple suspend functions and will run within the same context. Others might require their context: to execute concurrently or to survive past the coroutine that launched them.

We looked at basic approaches that can be used to split the main coroutine into several worker coroutines, and also how to join them back together and use their results. We also discussed how to call blocking code from a non-blocking context, and how to launch a non-blocking routine from traditional threaded code.

The code from the samples can be found over on GitHub.

The post Composing Coroutines and Suspend Functions first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/kotlin/composing-coroutines-suspend-functions/feed 0 https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-02-k-150x150.png
Access Kotlin Companion Object in Java https://www.baeldung.com/kotlin/companion-objects-in-java https://www.baeldung.com/kotlin/companion-objects-in-java#respond Sun, 26 Dec 2021 15:47:56 +0000 https://www.baeldung.com/kotlin/?p=51224 A quick and practical guide to accessing Kotlin's companion objects from Java.

The post Access Kotlin Companion Object in Java first appeared on Baeldung on Kotlin.]]>
1. Overview

In this tutorial, we’ll learn about Kotlin’s companion object and how to access them from Java using some simple examples. We’ll also see the decompiled Kotlin bytecode – the equivalent Java code that the compiler generates – for each of the examples.
If using IntelliJ, we can access the generated code from, Tools → Kotlin → Show Kotlin Bytecode → Decompile. It’s okay to skip the decompiled code during the initial reading of this article.

2. Declaring a companion object

In Kotlin, we can easily create a thread-safe singleton using the object declaration. If we declare the object inside a class, we have an option to mark it as a companion object. In terms of Java, the members of the companion object can be accessed as static members of the class. Marking an object as a companion allows us to omit the object’s name while calling its members.
Let’s see a quick example that shows how to declare a companion object in Kotlin:

class MyClass {
    companion object {
        val age: Int = 22
    }
}

In the above sample, we have declared a companion object. Note that we’ve omitted its name.

3. Accessing Properties of companion object from Java

As Kotlin is 100% interoperable with Java, there’s also a provision to access properties of companion objects as static fields from a Java class.

3.1. @JvmField Annotation

We can mark a property in a Kotlin class with the @JvmField annotation to let the Kotlin compiler know that we want to expose it as a static field:

class FieldSample {
    companion object{
        @JvmField
        val age : Int = 22
    }
}

Now, let’s access it from a Java class:

public class Main {
    public static void main(String[] args) {
        System.out.println(FieldSample.age);
    }
} 

In the above example, we marked the version property with the @JvmField annotation. Then, we were able to access it in our Java class directly. Note that if we just see the Java code, then it appears as if we’re accessing a static field of AppDatabase.

Let’s see the decompiled Kotlin bytecode for the FieldSample class:

public final class FieldSample {
   @JvmField
   public static int age = 22;
   @NotNull
   public static final FieldSample.Companion Companion = new FieldSample.Companion((DefaultConstructorMarker)null);

   public static final class Companion {
      private Companion() {
      }
...
   }
}

We can see from the above snippet that the Kotlin compiler generates a static field for the property marked with the @JvmField annotation.

3.2. Special Case – lateinit Modifier

Variables defined as lateinit are special because when defined as part of a companion object, a static backing field is created for each of them. This static backing field has the same visibility as that of the lateinit variable. So, if we define a public lateinit variable, we can access it in our Java code.

Let’s write a quick Kotlin class that declares both private and public lateinit variables:

class LateInitSample {
    companion object{
        private lateinit var password : String
        lateinit var userName : String

        fun setData(pair: Pair<String,String>){
            password = pair.first
            userName = pair.second
        }
    }
}

As shown in the following Java snippet, we can only access the lateinit variable that we declared as public:

public class Main {
    static void callLateInit() {
        System.out.println(LateInitSample.userName);
        //System.out.println(LateInitSample.password); compilation error
    }
}

Let’s see an excerpt of the decompiled Kotlin bytecode for the LateInitSample class:

public final class LateInitSample {
   private static String password;
   public static String userName;
   @NotNull
   public static final LateInitSample.Companion Companion = new LateInitSample.Companion((DefaultConstructorMarker)null);

   public static final class Companion {
      @NotNull
      public final String getUserName() {
         String var10000 = LateInitSample.userName;
         if (var10000 == null) {
            Intrinsics.throwUninitializedPropertyAccessException("userName");
         }

         return var10000;
      }

      public final void setUserName(@NotNull String var1) {
         Intrinsics.checkNotNullParameter(var1, "<set-?>");
         LateInitSample.userName = var1;
      }

      public final void setData(@NotNull Pair pair) {
         Intrinsics.checkNotNullParameter(pair, "pair");
         LateInitSample.password = (String)pair.getFirst();
         ((LateInitSample.Companion)this).setUserName((String)pair.getSecond());
      }

      private Companion() {
      }
   }
}

From the generated code above, we can see that the compiler generates static fields for the lateinit variables. The visibility is the same as that of the actual fields.

3.3. Special Case – const Modifier

We can define a compile-time constant in Kotlin by applying the const keyword. If we’ve defined a constant in Java, we know that all such fields are static final. Kotlin’s const is equivalent to a Java static final field. Let’s see sample code to define a const variable in a companion object and how to access it in Java:

class ConstSample {
    companion object{
        const val VERSION : Int = 100
    }
}
public class Main {
     static void callConst() {
        System.out.println(ConstSample.VERSION);
    }
}

Let’s see the decompiled Kotlin bytecode for the ConstSample class:

public final class ConstSample {
   public static final int VERSION = 100;
   @NotNull
   public static final ConstSample.Companion Companion = new ConstSample.Companion((DefaultConstructorMarker)null);

 
   public static final class Companion {
      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

As we can see, the compiler internally converts the VERSION field into a static final field in Java.

4. Accessing the companion object’s Methods

To access a companion object’s methods from Java, we need to mark the methods with the @JvmStatic annotation. Let’s see an example:

class MethodSample {
    companion object {
        @JvmStatic
        fun increment(num: Int): Int {
            return num + 1
        }
    }
}
public class Main {
    public static void main(String[] args) {
        MethodSample.increment(1);
    }
}

This annotation tells the Kotlin compiler to generate a static method in the enclosing class. Let’s see an excerpt of the decompiled Kotlin bytecode:

public final class MethodSample {
   @NotNull
   public static final MethodSample.Companion Companion = new MethodSample.Companion((DefaultConstructorMarker)null);

   @JvmStatic
   public static final int increment(int num) {
      return Companion.increment(num);
   }

  
   public static final class Companion {
      @JvmStatic
      public final int increment(int num) {
         return num + 1;
      }

      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

In the above snippet, we can see that, internally, the Kotlin compiler is calling the Companion.increment() method from the enclosing class’s generated static increment method.

5. Conclusion

In this article, we saw how to use the members of a Kotlin companion object from Java. We also saw the generated bytecode to get a better understanding of these features.

The code samples are also available over on GitHub.

The post Access Kotlin Companion Object in Java first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/kotlin/companion-objects-in-java/feed 0 https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-01-k-150x150.png
How to Initialize a List https://www.baeldung.com/kotlin/initialize-list https://www.baeldung.com/kotlin/initialize-list#respond Thu, 23 Dec 2021 08:31:04 +0000 https://www.baeldung.com/kotlin/?p=51219 A quick and practical guide to initializing a List in Kotlin.

The post How to Initialize a List first appeared on Baeldung on Kotlin.]]>
1. Overview

In this tutorial, we’ll discover various ways in which we can initialize a List in Kotlin. The Kotlin Standard Library provides an implementation of the List data type. List implementation and its utility methods are defined in  Collections.kt file from the kotlin.collections package.

2. Creating an Empty Immutable List

We can create an empty immutable List using the emptyList method:

@Test
fun emptyList() {
    val emptyList = emptyList<String>()
    assertTrue(emptyList.isEmpty(), "List is empty")
}

3. Creating an Immutable List

We can use the listOf list builder for creating an immutable List. We need to specify all the elements during List creation. The listOf builder returns an instance of the List interface and hence is immutable.

Let’s see it in action:

val readOnlyList = listOf<String>("John", "Doe")

In the previous example, we specified all the elements. We can also use another list with the listOf builder to initialize a list:

val readOnlyList = listOf<String>("John", "Doe")
//using another list and spread operator
val secondList = listOf<String>(*readOnlyList.toTypedArray())

We can also use an immutable List while filtering out null values. For this, we need to use the listOfNotNull method. Let’s see a sample:

val filteredList = listOfNotNull("A", "B", null)

4. Creating a Mutable List

4.1. Using mutableListOf

We can create mutable lists using the mutableListOf List builder method. It returns an instance of the MutableList interface, which provides add, remove, and other list manipulation methods. Let’s see how we can use this method in our code:

@Test
fun readWriteList() {
    var mutableList = mutableListOf<String>()
    mutableList.add("Sydney")
    mutableList.add("Tokyo")
    assert(mutableList.get(0) == "Sydney")
    mutableList = mutableListOf("Paris", "London")
    assert(mutableList.get(0) == "Paris")
}

4.2. Using arrayListOf

We can create an instance of ArrayList by using the arrayListOf method.

ArrayList is a child of MutableList and implements the RandomAccess interface. Let’s see how we can use it:

@Test
fun readWriteList() {
    var arrList = arrayListOf<Int>()
    arrList.add(1)
    arrList.remove(1)
    assert(arrList.size == 0)
    arrList = arrayListOf(1, 2, 3, 4)
    assert(arrList.size == 4)
}

5. Converting to List

We can also convert a datatype like Map to a List. The toList extension function on Map converts its elements to a List:

@Test
fun fromMaps() {
    val userAddressMap = mapOf(
        "A" to "India",
        "B" to "Australia",
        "C" to null
    )
    val newList : List<Pair<String,String?>> = userAddressMap.toList()
    assert(newList.size == 3)
}

6. List Builders

We can create List or MutableList objects by specifying size and an initialization lambda function:

fun dynamicBuild(){
    val myList = List(10){
        it.toString()
    }
    println(myList) 
    val myMutableList = MutableList(10){
        it.toString()
    }
    myMutableList.add("11")
    println(myMutableList)
}

Let’s look at the output from the above example:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]

6.1. Using buildList()

Using the buildList method allows us to define a builderAction lambda in which we can manipulate a MutableList. The buildList method then returns an instance of a read-only List with the same elements.

Let’s see how to do this with an example:

fun build(){
    val students = listOf<String>("Hertz","Jane")
    val myList = buildList<String>(students.size + 1) {
        add("Jitendra")
        addAll(students)
    }
    println(myList)
}

The previous sample produces the output:

[Jitendra, Hertz, Jane]

7. Conclusion

In this article, we saw the different ways we can define a List in Kotlin. The code samples are also available over on GitHub.

The post How to Initialize a List first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/kotlin/initialize-list/feed 0 https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-02-k-150x150.png
Guide to Spring Boot Testing with Kotlin https://www.baeldung.com/kotlin/spring-boot-testing https://www.baeldung.com/kotlin/spring-boot-testing#respond Wed, 22 Dec 2021 10:42:04 +0000 https://www.baeldung.com/kotlin/?p=51215 Explore a few unit and integration testing techniques for the Spring Boot app with Kotlin.

The post Guide to Spring Boot Testing with Kotlin first appeared on Baeldung on Kotlin.]]>
1. Overview

In this tutorial, we’ll explore a few testing techniques for a Kotlin based Spring Boot application.

First, let’s create a basic Kotlin based Spring Boot app with a few components like the repository, controller, and service. Then, we can discuss the unit and integration testing techniques.

2. Setup

Let’s brush up on the Maven dependencies for the Spring Boot app with Kotlin.

First, we’ll add the latest spring-boot-starter-web and spring-boot-starter-data-jpa Maven dependencies to our pom.xml for web and JPA support:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.6.1</version>
</dependency>

Then, let’s add the h2 embedded database for persistence:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
    <version>2.0.202</version>
</dependency>

Next, we can define the source directories of the Kotlin code:

<build>
    <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
    <plugins>
        // ...
    </plugins>
</build>

Last, we’ll set up the kotlin-maven-plugin plugin to provide compiler plugins like all-open and no-arg for Spring and JPA support:

<plugin>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-plugin</artifactId>
    <configuration>
        <args>
            <arg>-Xjsr305=strict</arg>
        </args>
        <compilerPlugins>
            <plugin>spring</plugin>
            <plugin>jpa</plugin>
            <plugin>all-open</plugin>
            <plugin>no-arg</plugin>
        </compilerPlugins>
        <pluginOptions>
            <option>all-open:annotation=javax.persistence.Entity</option>
            <option>all-open:annotation=javax.persistence.Embeddable</option>
            <option>all-open:annotation=javax.persistence.MappedSuperclass</option>
        </pluginOptions>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-allopen</artifactId>
            <version>1.6.10</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-noarg</artifactId>
            <version>1.6.10</version>
        </dependency>
    </dependencies>
</plugin>

3. Spring Boot Application

Now that our setup is ready. Let’s add a few components to our Spring Boot app for unit and integration testing.

3.1. Entity

First, we’ll create the BankAccount entity with a few properties like bankCode and accountNumber:

@Entity
data class BankAccount (
    var bankCode:String,
    var accountNumber:String,
    var accountHolderName:String,
    @Id @GeneratedValue var id: Long? = null
)

3.2. Repository

Then, let’s create the BankAccountRepository class to provide CRUD features on the BankAccount entity using the Spring Data’s CrudRepository:

@Repository
interface BankAccountRepository : CrudRepository<BankAccount, Long> {}

3.3. Service

Further, we’ll create the BankAccountService class with a few methods like addBankAccount and getBankAccount:

@Service
class BankAccountService(var bankAccountRepository: BankAccountRepository) {
    fun addBankAccount(bankAccount: BankAccount): BankAccount {
        return bankAccountRepository.save(bankAccount);
    }
    fun getBankAccount(id: Long): BankAccount? {
        return bankAccountRepository.findByIdOrNull(id)
    }
}

3.4. Controller

Last, let’s create the BankController class to expose the /api/bankAccount endpoint:

@RestController
@RequestMapping("/api/bankAccount")
class BankController(var bankAccountService: BankAccountService) {

    @PostMapping
    fun addBankAccount(@RequestBody bankAccount:BankAccount) : ResponseEntity<BankAccount> {
        return ResponseEntity.ok(bankAccountService.addBankAccount(bankAccount))
    }

    @GetMapping
    fun getBankAccount(@RequestParam id:Long) : ResponseEntity<BankAccount> {
        var bankAccount: BankAccount? = bankAccountService.getBankAccount(id);
        if (bankAccount != null) {
            return ResponseEntity(bankAccount, HttpStatus.OK)
        } else {
            return ResponseEntity(HttpStatus.BAD_REQUEST)
        }
    }
}

So, we’ve exposed the endpoint with the GET and POST mapping to read and create the BankAccount object, respectively.

4. Testing Setup

4.1. JUnit5

First, we’ll exclude the JUnit’s vintage support, which is part of the spring-boot-starter-test dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Then, let’s include the Maven dependencies for JUnit5 support:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <span class="hljs-tag"><<span class="hljs-name">version</span>></span>5.8.1<span class="hljs-tag"></<span class="hljs-name">version</span>></span>
    <scope>test</scope>
</dependency>

4.2. MockK

Also, we should add mocking capabilities to our tests that prove handy in testing service and repository components.

However, instead of Mockito, we’ll use the MockK library, which is better suited for Kotlin.

So, let’s exclude the mockito-core dependency that comes with the spring-boot-starter-test dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Then, we can add the latest mockk Maven dependency to our pom.xml:

<dependency>
    <groupId>com.ninja-squad</groupId>
    <artifactId>springmockk</artifactId>
    <version>3.0.1</version>
    <scope>test</scope>
</dependency>

5. Unit Tests

5.1. Test Service Using MockK

First, let’s create the BankAccountServiceTest class and mock the BankAccountRepository using MockK:

class BankAccountServiceTest {
    val bankAccountRepository: BankAccountRepository = mockk();
    val bankAccountService = BankAccountService(bankAccountRepository);
}

Then, we can use an every block to mock the response of the BankAccountRepository and verify the result of the getBankAccount method:

@Test
fun whenGetBankAccount_thenReturnBankAccount() {
    //given
    every { bankAccountRepository.findByIdOrNull(1) } returns bankAccount;

    //when
    val result = bankAccountService.getBankAccount(1);

    //then
    verify(exactly = 1) { bankAccountRepository.findByIdOrNull(1) };
    assertEquals(bankAccount, result)
}

5.2. Test Controller Using @WebMvcTest

We can use the @WebMvcTest annotation that automatically configures the Spring MVC infrastructure for our unit tests.

First, we’ll inject the MockMvc bean and mock the BankAccountService using the @MockkBean annotation:

@WebMvcTest
class BankControllerTest(@Autowired val mockMvc: MockMvc) {

    @MockkBean
    lateinit var bankAccountService: BankAccountService
}

Then, we can mock the response of BankAccountService, use an instance of the MockMvc bean to perform a GET request, and verify the JSON result:

@Test
fun givenExistingBankAccount_whenGetRequest_thenReturnsBankAccountJsonWithStatus200() {
    every { bankAccountService.getBankAccount(1) } returns bankAccount;

    mockMvc.perform(get("/api/bankAccount?id=1"))
      .andExpect(status().isOk)
      .andExpect(content().contentType(MediaType.APPLICATION_JSON))
      .andExpect(jsonPath("$.bankCode").value("ING"));
}

Similarly, we can verify a GET request that results in a bad request:

@Test
fun givenBankAccountDoesntExist_whenGetRequest_thenReturnsStatus400() {
    every { bankAccountService.getBankAccount(2) } returns null;

    mockMvc.perform(get("/api/bankAccount?id=2"))
      .andExpect(status().isBadRequest());
}

Also, we can use the MockMvc bean to perform a POST request with the BankAccount JSON as the request body and verify the result:

@Test
fun whenPostRequestWithBankAccountJson_thenReturnsStatus200() {
    every { bankAccountService.addBankAccount(bankAccount) } returns bankAccount;

    mockMvc.perform(post("/api/bankAccount").content(mapper.writeValueAsString(bankAccount)).contentType(MediaType.APPLICATION_JSON))
      .andExpect(status().isOk)
      .andExpect(content().contentType(MediaType.APPLICATION_JSON))
      .andExpect(jsonPath("$.bankCode").value("ING"));
}

6. Integration Tests

6.1. Test Repository Using @DataJpaTest

We can use the @DataJpaTest annotation that provides a standard setup for the persistence layer to test a repository.

First, we’ll create the BankAccountRepositoryTest class and inject the TestEntityManager bean that rollbacks the entire execution once the test is over:

@DataJpaTest
class BankAccountRepositoryTest {
    @Autowired
    lateinit var entityManager: TestEntityManager
            
    @Autowired
    lateinit var bankAccountRepository: BankAccountRepository
}

Then, let’s test the findByIdOrNull extension method of the BankAccountRepository using an instance of the TestEntityManager:

@Test
fun WhenFindById_thenReturnBankAccount() {
    val ingBankAccount = BankAccount("ING", "123ING456", "JOHN SMITH");
    entityManager.persist(ingBankAccount)
    entityManager.flush()
    val ingBankAccountFound = bankAccountRepository.findByIdOrNull(ingBankAccount.id!!)
    assertThat(ingBankAccountFound == ingBankAccount)
}

6.2. Test App Using @SpringBootTest

We can use the @SpringBootTest annotation to start our app in a sandbox web environment:

@SpringBootTest(
  classes = arrayOf(KotlinTestingDemoApplication::class),
  webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class KotlinTestingDemoApplicationIntegrationTest {

    @Autowired
    lateinit var restTemplate: TestRestTemplate
}

Also, we’ve injected the TestRestTemplate bean to test the RESTful endpoints exposed by our app.

So, let’s test the GET request on the /api/bankAccount endpoint:

@Test
fun whenGetCalled_thenShouldBadReqeust() {
    val result = restTemplate.getForEntity("/api/bankAccount?id=2", BankAccount::class.java);

    assertNotNull(result)
    assertEquals(HttpStatus.BAD_REQUEST, result?.statusCode)
}

Similarly, we can use the TestRestTemplate instance to test the POST request on the /api/bankAccount endpoint:

@Test
fun whePostCalled_thenShouldReturnBankObject() {
    val result = restTemplate.postForEntity("/api/bankAccount", BankAccount("ING", "123ING456", "JOHN SMITH"), BankAccount::class.java);

    assertNotNull(result)
    assertEquals(HttpStatus.OK, result?.statusCode)
    assertEquals("ING", result.getBody()?.bankCode)
}

7. Conclusion

In this article, we’ve discussed a few unit and integration testing techniques for the Spring Boot app with Kotlin.

First, we developed a Kotlin based Spring Boot app with an entity, repository, service, and controller. Then, we explored different ways to test such components.

As always, code is available over on GitHub.

The post Guide to Spring Boot Testing with Kotlin first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/kotlin/spring-boot-testing/feed 0 https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-01-k-150x150.png
Kotlin DSL for Gradle https://www.baeldung.com/kotlin/gradle-dsl https://www.baeldung.com/kotlin/gradle-dsl#respond Tue, 21 Dec 2021 07:32:56 +0000 https://www.baeldung.com/kotlin/?p=51212 Learn how to write Gradle scripts in Kotlin

The post Kotlin DSL for Gradle first appeared on Baeldung on Kotlin.]]>
1. Overview

Groovy is the default language for writing Gradle scripts. However, since Gradle version 5.0, we can write these scripts in Kotlin, too.

In this tutorial, we’ll look at how we can write Gradle scripts in Kotlin. We will also look at some advantages and disadvantages of using Kotlin DSL scripts.

2. How to Create a Kotlin DSL Script

To write Kotlin DSL scripts, we need to use Gradle version 5.0 or later. To activate the Kotlin DSL and get the best IDE support, we need to use the following extensions:

  • .gradle.kts instead of .gradle for our build scripts
  • .settings.gradle.kts instead of .settings.gradle for all settings scripts
  • .init.gradle.kts instead of .init.gradle for initialization scripts

3. How to Write a Basic Gradle Script for a Java Library

In this section, we’ll go through the different building blocks of a Gradle script written in Kotlin DSL script. We will also look at the differences compared to when writing the same script in Groovy DSL.

3.1. Applying Plugins

We can apply the java-library plugin, which is a core plugin:

plugins {
    `java-library`
}

Please note that we don’t need to specify the id function – unlike in Groovy DSL – for core plugins.

We can apply a community plugin by specifying the fully qualified plugin id and version:

plugins {
    id("org.flywaydb.flyway") version "8.0.2"
}

3.2. Declaring Dependencies

We can declare different types of dependencies using type-safe accessors:

dependencies {
    api("com.google.inject:guice:5.0.1")
    implementation("com.google.guava:guava:31.0-jre")
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
}

The important thing to note here is that the Kotlin DSL makes all four accessors available in the body of the Gradle script immediately after the plugins {} block. This means that when composing this script, we will have type-safe auto-completion in supported IDEs. This results in a fast and superior scripting experience.

3.3. Declaring Repositories

We can declare both built-in and custom repositories using type-safe accessors:

repositories {
    mavenCentral()
    maven {
        url = uri("https://maven.springframework.org/release")
    }
}

While resolving a dependency, Gradle will first check the maven-central repository followed by the springframework repository.

3.4. Configuring Source Sets

Let’s say we want to define a separate source set for our integration tests. The project layout is:

gradle-kotlin-dsl 
  ├── src 
  │    └── main 
  │    |    ├── java 
  │    |    │    ├── DefaultSorter.java
  │    |    │    ├── InMemoryRepository.java
  │    |    │    ├── Reporter.java
  │    |    │    ├── Repository.java
  │    |    │    ├── Sorter.java
  │    ├── test 
  │    |    ├── java 
  │    |    │    └── DefaultSorterTest.java
  │    |    │    └── InMemoryRepositoryTest.java
  │    |    │    └── ReporterTest.java
  │    └── integrationTest 
  │         └── java 
  │              └── ReporterIntegrationTest.java
  └── build.gradle

We can define the integrationTest source set as:

sourceSets {
    create("integrationTest") {
        compileClasspath += sourceSets.main.get().output
        runtimeClasspath += sourceSets.main.get().output
    }
}

With this setup, we create a Gradle task called compileIntegrationTestJava. Using this task, we can compile the source files inside the src/integrationTest/java directory.

3.5. Defining a Custom Gradle Task

We need a task to run the integration tests. We can create it using Kotlin DSL:

val integrationTest = task<Test>("integrationTest") {
    description = "Task to run integration tests"
    group = "verification"

    testClassesDirs = sourceSets["integrationTest"].output.classesDirs
    classpath = sourceSets["integrationTest"].runtimeClasspath
    shouldRunAfter("test")
}

Here, we created a custom task using the Kotlin extension function task that is attached to the Project object. This is different from the Groovy syntax because there we would use the TaskContainer object to create a custom task. This is possible in Kotlin DSL too, but it’s more verbose.

4. IDE Support

Since Kotlin is a statically typed language, unlike Groovy, IDEs can provide several useful features like auto-completion, source code navigation, refactoring support, and error highlighting for Gradle scripts. This means we can enjoy a similar coding experience as we normally do when writing application code in Kotlin or Java. Currently, IntelliJ IDEA and Android Studio provide the best support for Kotlin DSLs.

5. Limitations

The Kotlin DSL has some limitations compared to Groovy especially when comparing the speed of script compilation. There are some other uncommon limitations mentioned on the Gradle official website.

6. Conclusion

In this article, we learned how to compose Gradle scripts using the Kotlin DSL. We also looked at some differences between Gradle scripts written in Groovy and those written in Kotlin DSL.

As usual, all code examples are available over on GitHub.

The post Kotlin DSL for Gradle first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/kotlin/gradle-dsl/feed 0 https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-02-k-150x150.png
Iterate Over a Map in Kotlin https://www.baeldung.com/kotlin/iterate-map https://www.baeldung.com/kotlin/iterate-map#respond Mon, 20 Dec 2021 13:02:35 +0000 https://www.baeldung.com/kotlin/?p=51207 There are a few ways to iterate over the keys and values in a Kotlin map. We look at some of the options and which is more efficient at runtime.

The post Iterate Over a Map in Kotlin first appeared on Baeldung on Kotlin.]]>
1. Overview

In this short tutorial, we’ll look at how to iterate over a map in Kotlin. We’ll see how we can do this with for loops, iterators, and some handy extension functions.

2. Iterate With a for loop

The simplest way to iterate over a map is to iterate over its Entry objects:

val map = mapOf("Key1" to "Value1", "Key2" to "Value2", "Key3" to "Value3")
map.forEach { entry ->
    print("${entry.key} : ${entry.value}")
}

Here, the in operator gives us a handle to the iterator of the map’s entries property. This is essentially the same as:

for (entry in map.entries.iterator()) {
    print("${entry.key} : ${entry.value}")
}

3. Using forEach 

We can also use the handy forEach extension function:

map.forEach { entry ->
    print("${entry.key} : ${entry.value}")
}

To further reduce boilerplate, we can use destructuring. Doing so expands the Entry into handy key and value variables:

map.forEach { (key, value) ->
    print("$key : $value")
}

4. Using the Map.keys Property

Sometimes, we’d only like to iterate over the keys in the map. In that case, we can use the map’s keys property:

for (key in map.keys) {
    print(key)
}

Here, we get a Set of all keys in the map. This also means we can use the Set‘s forEach extension function:

map.keys.forEach { key ->
    val value = map[key]
    print("$key : $value")
}

We should note that iterating over keys and values this way is less efficient. This is because we make multiple get calls on the map to fetch values for the given keys. This can be avoided by using the Entry iteration approach, for instance.

5. Using the map.values Property

Similarly, we can use the map’s values property to get a collection of all values:

for (value in map.values) {
    print(value)
}

Since the values property gives us a collection, we can use the forEach pattern here:

map.values.forEach { value ->
    print(value)
}

6. Conclusion

In this article, we saw several ways to iterate over a map. Some approaches are more flexible but come with a performance cost.

For most use cases, using forEach over entries is a good option.

As always, the code samples are available over on GitHub.

The post Iterate Over a Map in Kotlin first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/kotlin/iterate-map/feed 0 https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-02-k-150x150.png
Kotlin Interview Questions https://www.baeldung.com/kotlin/interview-questions Wed, 08 Dec 2021 08:34:40 +0000 https://www.baeldung.com/kotlin/?p=51151 Learn a few typical interview questions categorized into beginner and advanced levels

The post Kotlin Interview Questions first appeared on Baeldung on Kotlin.]]>
1. Overview

In this tutorial, we’ll discuss a few usual interview questions for Kotlin.

We categorize the questions into beginner and advanced levels for ease of understanding.

2. Beginner Level Questions

2.1. What Is Kotlin? How Is It Interoperable With Java?

Kotlin is a general-purpose JVM-based programming language designed and developed by JetBrains. It’s a statically-typed programming language that supports procedural, functional, and object-oriented programming.

The Kotlin compiler generates the bytecode that is 100% equivalent to the bytecode generated by the Java compiler. Hence, it can seamlessly interoperate with Java.

A few handy features like range expressions, extension functions, null-safety, and smart casts make Kotlin a better alternative over Java.

Additionally, Google promotes Kotlin as the official language for Android development.

2.2. What Are the Different Types of Variable Declaration in Kotlin?

In Kotlin, we can either use the val or var keyword followed by an optional data type to declare a variable:

val userName: String = "John"
var age = 25

The val keyword creates a final immutable variable that allows initialization only once. However, var creates a mutable general-purpose variable suitable for multiple assignments.

When we declare a variable without a data type, Kotlin uses the smart cast feature to determine the data type based on the value assignment.

Also, we can use the const keyword along with val to declare compile-time constants.

2.3. What’s the Difference Between val and const?

The val keyword creates an immutable variable at runtime, whereas const along with val allows creating a compile-time immutable variable (constant):

val welcomeMsg: String = "Hello $userName"
const val FILE_EXTENSION: String = ".jpg"

Also, we can declare global or local immutable variables using the val keyword, assignable to a function or any class constructor.

However, we can’t assign it to a function or any class constructor as Kotlin decides the value of the const variable at compile-time.

2.4. How to Create Constructors in Kotlin?

There are two types of constructors available in Kotlin – primary and secondary. A Kotlin class can have one primary constructor and one or more secondary constructors.

In Kotlin, we initialize the primary constructor in the class header with a var or val variable declaration:

class Person (var firstName: String, var lastName: String) {
    var age: Int = 0
}

var person = Person("John", "Smith");

However, a secondary constructor definition can’t have variable declaration with the var and val keywords:

class Person (var firstName: String, var lastName: String) {
    var age: Int = 0

    constructor (firstName: String, age: Int) {
        this.firstName = firstName
        this.age = age
    }
}

 var personWithAge = Person("John", 27);

Also, a secondary constructor can use the primary constructor internally in the definition:

constructor (firstName: String, lastName: String, age: Int): this(firstName, lastName) {
    this.age = age
}

2.5. Describe String Interpolation in Kotlin

Kotlin supports two ways of String interpolation – variable substitution using $ and interpolating an expression using ${}. For example:

var welcomeMsg = "Hello $userName";
var secondsInOneYear = "${60 * 60 * 24 * 365} seconds"

2.6. What’s Null-Safety in Kotlin?

Null safety in Kotlin guarantees that no object references shall have null or void values.

By default, Kotlin doesn’t allow a variable to have a null value. So, it eliminates the risk of encountering the notorious NullPointerException in the production environment.

However, if required, we can define a variable with the null reference by using ? after the data type:

var name : String?

2.7. What Are the Data Classes in Kotlin?

Kotlin encourages code brevity by reducing boilerplate code. For example, the data class provides a way to write concise and readable POJOs.

They eliminate the need to define getters/setters, parameterized constructors, and override methods like hashcode and equals.

All of this is possible in Kotlin by simply adding the data keyword to the class:

data class Person(var firstName: String, var lastName: String)

Furthermore, apart from usual POJO methods like equals, hashCode, and toString, it also creates a few built-in functions like open and componentN.

2.8. How to Create a Singleton Class in Kotlin?

Similar to the data class, Kotlin reduces boilerplate code in defining a singleton class by using the object keyword:

object SimpleSingleton

The Kotlin compiler internally implements a singleton class with a thread-safe lazy initialization.

2.9. What Is a Double-Bang Operator in Kotlin?

Kotlin’s double bang (!!) operator is a not-null assertion operator. It converts any variable to a non-null type and throws the NullPointerException if it’s null.

So, a developer should use this operator when they are certain for a variable to be not null in any case.

2.10. What Are the Range Expressions in Kotlin?

A range is a sequence of values defined by start and end values. Range expressions in Kotlin help to iterate over a range.

Kotlin provides the rangeTo and downTo functions to create a range. Alternatively, we can also use the double dots (..) operator to define a range of values.

For example, let’s define a few ranges in Kotlin:

(i in 1..10) // range from 1 to 10

(i in 1.rangeTo(10)) // range from 1 to 10

(i in 10.downTo(1)) // range from 10 down to 1

(ch in 'a'..'z') // range from a to z

(i in 1..10 step 2) // range from 1 to 10 with a step of 2 (1, 3, 5, 7, 9)

Also, Kotlin allows a few handy functions like reverse, until, first, and last over range expressions for various use cases.

2.11. Explain when in Kotlin

Kotlin’s when is an advanced version of Java’s switch-case statements.

When a matching expression is found, Kotlin executes the corresponding code and moves to the next statement:

when (person.firstName) {
    "Mike" -> println("hello!")
    "John" -> println("howdy!")
    else -> println("hi!")
}

Unlike Java, Kotlin doesn’t require a break statement at the end of each case block. Furthermore, Kotlin’s when is useful both as a statement and as an expression.

2.12. List All Access Modifiers Available in Kotlin. Which Access Modifier Is Used by Default?

There are four access modifiers available in Kotlinpublic, private, protected, and internal.

Similar to Java, the public modifier in Kotlin provides global visibility to the declarations. It’s the default modifier in Kotlin when not declared.

Similarly, the private modifier is the opposite of the public modifier. Hence, it allows accessing the declarations within the file.

However, the protected declarations are secured and not available to the top-level declarations.

Unlike Java, Kotlin has an internal modifier that provides access to the declarations anywhere in the module.

2.13. Define open in Kotlin

Unlike Java, which allows extending classes and methods by default, Kotlin uses the open keyword to enable others to inherit them. In other words, it’s opposite to Java’s final keyword.

Kotlin keeps everything final, and through the open keyword, it supports the philosophy of limiting the extension of the classes unless required.

3. Advanced Level Questions

3.1. What Are the Advantages of Kotlin Over Java?

Kotlin, a JVM programming language, provides tools to write concise, easy, and readable code that’s interoperable with Java.

Furthermore, it’s an official programming language for Andriod development that supports major programming paradigms, like OOP, procedural, and functional.

Also, Kotlin fills a few gaps that Java possesses – null safety, range expressions, string templates, coroutines, inline – infix functions, and smart casts.

3.2. Define inline and infix Functions

Kotlin’s inline functions allow the compiler to substitute the body directly into places (inlines) where the function gets called:

inline fun isEven (number: Int): Boolean {
     return number % 2 == 0
}

val resultList = (1..10).filter { isEven(it) }

The Kotlin compiler will substitute the body of isEven directly in the filter. Hence, it prevents the object allocations for the functions or lambda expressions. For example:

So, we can write elegant lambdas with the inline keyword without worrying about abstraction and efficiency.

However, infix functions in Kotlin are some functions that can be called without using the period and brackets:

var personDetailsMap = mapOf(
    "firtName" to "john",
    "lastName" to "smith",
    "age" to 25
  )

Here, the to method is used as an infix function and results in code that’s more like a natural language – easy to read and understand.

Kotlin provides a variety of infix functions like and, or, and matches. Also, we can define custom infix functions whenever required.

3.3. Define lazy and lateinit

lazy means lazy initialization, and lateinit means late initialization.

Kotlin doesn’t initialize a lazy variable before its use. Therefore, it’s supported only by val. A lazy variable supports only a single initialization.

On the other hand, Kotlin delays initialization for a lateinit variable but expects the variable to be initialized before its use. Also, Kotlin throws the UninitializedPropertyAccessException exception without initialization.

It’s supported by var and allows multiple initializations. However, we can’t use lateinit for the primitive types.

A lazy variable can only be initialized from the initializer lambda. However, the lateinit variable allows initialization from anywhere the variable is accessible.

3.4. Define fold and reduce Functions

The fold and reduce functions traverse a collection and apply a given operation with and without initial value, respectively.

Let’s take a look at a simple operation using the fold and reduce functions:

var sum = (1..10).fold(10) { res, next -> res + next }
assertEquals(65, sum)

The first iteration of the collection with the fold function uses 10 (initial value) to start with. So, the values of res and next are 10 and 1, respectively.

sum = (1..10).reduce { res, next -> res + next }
assertEquals(55, sum)

However, the iteration starts with 1 and 2 with the reduce function.

Also, the fold function allows changing the result type by defining the data type of the initial value.

3.5. What Are the Coroutines in Kotlin?

Coroutines offer lightweight multi-threading programming in Kotlin. Also, we can leverage the suspension and resumption of coroutines mid-execution to write asynchronous programs.

The Kotlin language comes with a rich library called kotlinx-coroutines with a few modules like core, test, debug, and reactive to support multiple features.

3.6. What Are the Companion Objects in Kotlin?

Unlike Java, Kotlin doesn’t have static members or member functions. So, we can define a companion object inside the class to execute a method without the class instance.

We can declare a companion object by using the companion keyword:

class Person(var firstName: String, var lastName: String) {

    companion object {
        val defaultPerson = Person("Mike", "Shaw")
    }

    // ...
}

assertEquals("Mike", Person.defaultPerson.firstName)

However, companion objects in Kotlin are similar to the standard object with a couple of additional features to ease the development. For example, the name of a companion object is optional, and it offers singleton implementation.

3.7. Explain Bitwise Operations in Kotlin

Similar to Java, Kotlin, too, has bitwise operations like or, and, xor, and left and right shifts. However, the operators are named more intuitively than in Java.

For example, the name of Kotlin bit operators are or, and, xor, and inv:

assert(111 or 101 == 111) 
assert(111 and 101 == 101)
assert(111 xor 101 == 10)
assert(101.inv() == -102)

Similarly, the binary shift operators are shl – signed left shift, shr – signed right shift, and ushr – unsigned right shift:

assert(3 shl 3 == 24)
assert(12 shr 2 == 3)
assert(-1 ushr 1 == Int.MAX_VALUE)

4. Conclusion

In this article, we went through a few typical interview questions categorized into beginner and advanced levels.

These questions and their brief answers can give a good start to someone preparing for the Kotlin interview. However, it’s also advised to go through detailed concepts and practice enough to have good hands-on experience.

The post Kotlin Interview Questions first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/wp-content/uploads/sites/5/2021/12/Kotlin-Featured-Image-02-k-150x150.png
Building a Self-Executable Jar With Gradle and Kotlin https://www.baeldung.com/kotlin/gradle-executable-jar Tue, 07 Dec 2021 11:12:02 +0000 https://www.baeldung.com/kotlin/?p=51146 A quick and practical guide to building a self-executable Jar with Gradle and Kotlin.

The post Building a Self-Executable Jar With Gradle and Kotlin first appeared on Baeldung on Kotlin.]]>
1. Introduction

JVM languages promise their users: “Write once – run everywhere”. However, when it comes to shipping, many small problems arise. The ecosystem has evolved, and now it is unthinkable to create any application without dozens and dozens of dependency libraries. All of them must end up in the classpath, and if not – likely, the application won’t even start.

Sometimes we can afford to create another directory and to put all the dependency jars in there. But sometimes we want that uber-jar or else fat-jar, which can be run with java command:

java -jar my-application.jar

One of the ways to achieve that with Gradle has already been discussed on our site. Let’s discuss the other possibilities. We will also use Kotlin Gradle DSL in our build file instead of Groovy.

2. Lightweight Application With Gradle Plugin

Now, “self-executing jar” might be a bit of a misnomer. If we want our application to be runnable on Windows, Linux, and macOS platforms without any CLI fuss, we might use a standard Gradle Plugin – application:

plugins {
    application // enabling the plugin here
    kotlin("jvm") version "1.6.0"
}

// Other configuration here

application {
    mainClass.set("the.path.to.the.MainClass")
}

The only thing we need to do is point to the main class of our application – the class containing the function main(args: Array<String>) that we want to invoke at the start.

The Application Plugin also automatically includes the Distribution Plugin. The Distribution Plugin creates two archives: TAR and ZIP. Their contents are identical and include the project jar, all dependency jars, and two scripts: Bash and .bat-file. Then, distributing our application is no problem at all: We can use our-project/build/distributions/our-project-1.0.1.zip, unpack it, and run the executable script:

unzip our-project-1.0.1.zip
./our-project-1.0.1/bin/our-project-1.0.1

This will start our application on Linux and macOS. The command ./our-project-1.0.1/bin/our-project-1.0.1.bat will start it on Windows.

However, this way of packing and distributing software is not ideal. Indeed, we must assume the existence of a TAR or ZIP un-archiver on the target host, as well as a valid JRE. What if we want the most minimal number of files to transfer and the most straightforward way to start the application?

Enter the fat jar.

3. “Fat Jar” for the Lightweight Application

The next way to ship our application is to build the application plugin, discussed in the previous chapter. We’ll add a custom task to reach our goal.

If we don’t plan to use our project as a dependency in some third project, then we might pack every dependency in a single jar and ship:

tasks {
    val fatJar = register<Jar>("fatJar") {
        dependsOn.addAll(listOf("compileJava", "compileKotlin", "processResources")) // We need this for Gradle optimization to work
        archiveClassifier.set("standalone") // Naming the jar
        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
        manifest { attributes(mapOf("Main-Class" to application.mainClass)) } // Provided we set it up in the application plugin configuration
        val sourcesMain = sourceSets.main.get()
        val contents = configurations.runtimeClasspath.get()
            .map { if (it.isDirectory) it else zipTree(it) } +
                sourcesMain.output
        from(contents)
    }
    build {
        dependsOn(fatJar) // Trigger fat jar creation during build
    }
}

The usage of John Engelman’s ShadowJar plugin becomes necessary only if there’s an actual need for shading our dependencies. To shade a dependency is to rewrite its package name to not clash with the duplicate class files of another version of the same dependency. However, an executable jar is an unlikely candidate for a dependency, and we most probably can skip that in every project.

The code above produces one more jar file in our project’s build/libs directory: our-project-1.0.1-standalone.jar. We can run it directly:

java -jar our-project-1.0.1-standalone.jar

3. Spring Boot Application

Spring Boot applications are executable out of the box. Instead of repackaging all the jars, like in our second approach, the Spring Boot plugin wraps dependency jars with one more jar. The creation of a project is simple in this case. We can use Spring Initializr, choose the technologies we need in our project, and download a ready-to-go project. The plugins are all that we want:

plugins {
    id("org.springframework.boot") version "2.6.0"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
    kotlin("jvm") version "1.6.0"
    kotlin("plugin.spring") version "1.6.0"
}

And then, our application must be a valid Spring Boot application because to manipulate the classpath, Spring Boot uses its starter. After the Gradle build has succeeded, we’ll find our-project-1.0.1.jar in the build/libs directory.

java -jar our-project-1.0.1.jar

4. Conclusion

Depending on the project, its size, and the technologies used, we might opt for an unzipped distribution, a self-built fat jar, a jar with shaded dependencies, or a Spring Boot application. In all the cases, Gradle provides easy tools to achieve our goal.

The sample projects for the self-built fat jar and the Spring Boot application can be found over on GitHub.

The post Building a Self-Executable Jar With Gradle and Kotlin first appeared on Baeldung on Kotlin.]]>
https://www.baeldung.com/wp-content/uploads/sites/5/2020/01/Kotlin-On-Baeldung-150x150.png