From Java to Kotlin. Cheatsheet

I wanted to keep everything regarding the differences between Java and Kotlin on one place. That’s why I’ve created with Cheatsheet.
I hope it would be useful for you as well.

Printing

Java

System.out.print("Hello, World!");
System.out.println("Hello, World!");
Kotlin
print("Hello, World!")
println("Hello, World!")

Variables I

Java
final int x;
final int y = 1;
Kotlin
val x: Int
val y = 1

Variables II

Java
int w;
int z = 2;
z = 3;
w = 1;
Kotlin
var w: Int
var z = 2
z = 3
w = 1

Null I

Java
final String name = null;

String lastName;
lastName = null
Kotlin
val name: String? = null

var lastName: String?
lastName = null

var firstName: String
firstName = null // Compilation error!!

Null II

Java
if(text != null){
  int length = text.length();
}
Kotlin
val length = text?.length

val length = text!!.length // NullPointerException if text == null

Strings I

Java
String name = "John";
String lastName = "Smith";
String text = "My name is: " + name + " " + lastName;
String otherText = "My name is: " + name.substring(2);
Kotlin
val name = "John"
val lastName = "Smith"
val text = "My name is: $name $lastName"
val otherText = "My name is: ${name.substring(2)}"

Strings II

Java
String text = "First Line\n" +
              "Second Line\n" +
              "Third Line";
Kotlin
val text = """
        |First Line
        |Second Line
        |Third Line
""".trimMargin()

Ternary Operator

Java
String text = x > 5 ? "x > 5" : "x <= 5";
Kotlin
val text = if (x > 5)
              "x > 5"
            else "x <= 5"

Bits Operations

Java
final int andResult  = a & b;
final int orResult   = a | b;
final int xorResult  = a ^ b;
final int rightShift = a >> 2;
final int leftShift  = a << 2;
Kotlin
val andResult  = a and b
val orResult   = a or b
val xorResult  = a xor b
val rightShift = a shr 2
val leftShift  = a shl 2

Is As In

Java
if(x instanceof Integer){ }

final String text = (String) other;

if(x >= 0 && x <= 10 ){}
Kotlin
if (x is Int) { }

val text = other as String

if (x in 0..10) { }

Smart Cast

Java
if(a instanceof String){
  final String result = ((String) a).substring(1);
}
Kotlin
if (a is String) {
  val result = a.substring(1)
}

Switch / When

Java
final int x = // value;
final String xResult;

switch (x){
  case 0:
  case 11:
    xResult = "0 or 11";
    break;
  case 1:
  case 2:
    //...
  case 10:
    xResult = "from 1 to 10";
    break;
  default:
    if(x < 12 && x > 14) {
      xResult = "not from 12 to 14";
      break;
    }

    if(isOdd(x)) {
      xResult = "is odd";
      break;
    }

    xResult = "otherwise";
}



final int y = // value;
final String yResult;

if(isNegative(y)){
  yResult = "is Negative";
} else if(isZero(y)){
  yResult = "is Zero";
}else if(isOdd(y)){
  yResult = "is Odd";
}else {
  yResult = "otherwise";
}
Kotlin
val x = // value
val xResult = when (x) {
  0, 11 -> "0 or 11"
  in 1..10 -> "from 1 to 10"
  !in 12..14 -> "not from 12 to 14"
  else -> if (isOdd(x)) { "is odd" } else { "otherwise" }
}

val y = // value
val yResult = when {
  isNegative(y) -> "is Negative"
  isZero(y) -> "is Zero"
  isOdd(y) -> "is odd"
  else -> "otherwise"
}

For

Java
for (int i = 1; i < 11 ; i++) { }

for (int i = 1; i < 11 ; i+=2) { }

for (String item : collection) { }

for (Map.Entry&ltString, String&gt entry: map.entrySet()) { }
Kotlin
for (i in 1..10) { }

for (i in 1..10 step 2) {}

for (item in collection) {}
for ((index, item) in collection.withIndex()) {}

for ((key, value) in map) {}

Collections

Java
final List&ltInteger&gt numbers = Arrays.asList(1, 2, 3);

final Map&ltInteger, String&gt map = new HashMap&ltInteger, String&gt();
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");


// Java 9
final List&ltInteger&gt numbers = List.of(1, 2, 3);

final Map&ltInteger, String&gt map = Map.of(1, "One",
                                        2, "Two",
                                        3, "Three");
Kotlin
val numbers = listOf(1, 2, 3)

val map = mapOf(1 to "One",
                2 to "Two",
                3 to "Three")

Collections

Java
for (int number : numbers) {
  System.out.println(number);
}

for (int number : numbers) {
  if(number > 5) {
    System.out.println(number);
  }
}
Kotlin
numbers.forEach {
    println(it)
}

numbers.filter  { it > 5 }
       .forEach { println(it) }

Collections

Java
final Map&ltString, List&ltInteger&gt&gt groups = new HashMap<>();
for (int number : numbers) {
  if((number & 1) == 0){
    if(!groups.containsKey("even")){
      groups.put("even", new ArrayList<>());
    }

    groups.get("even").add(number);
    continue;
  }

  if(!groups.containsKey("odd")){
    groups.put("odd", new ArrayList<>());
  }

  groups.get("odd").add(number);
}
Kotlin
val groups = numbers.groupBy {
                if (it and 1 == 0) "even" else "odd"
             }

Collections

Java
final List&ltInteger&gt evens = new ArrayList<>();
final List&ltInteger&gt odds = new ArrayList<>();
for (int number : numbers){
  if ((number & 1) == 0) {
    evens.add(number);
  }else {
    odds.add(number);
  }
}
Kotlin
val (evens, odds) = numbers.partition { it and 1 == 0 }

Collections

Java
final List&ltUser&gt users = getUsers();

Collections.sort(users, new Comparator&ltUser&gt(){
  public int compare(User user, User otherUser){
    return user.lastname.compareTo(otherUser.lastname);
  }
});

// or

users.sort(Comparator.comparing(user -> user.lastname));
Kotlin
val users = getUsers()
users.sortedBy { it.lastname }

 

Improve your algorithms using the correct Data Structure

Algorithm complexity. Big O

 

We know that Object-oriented Programming can help us to design and build huge systems, but this is only the half history. Usually, we use computer programs because we need to manage huge amounts of data and do it within a reasonable amount of time.

Here is where algorithm design comes into play. The way we manage the data into the algorithm will determine the time that will take to solve the problem. (See above the Amount of data – Time correlation table)

Is this post, I want to talk about how using the correct data structure can help us to get a successful cost-effective algorithm.

When developing an algorithm, there are several things that we should take into account:

1- Amount of data

2- How we structure the data

3- How we manage the data

4- Time and space complexity

We assume that the main aim of our algorithm is to manage a big amount of data ( >1000 items ). The difference of time between two algorithms (let’s say O(x) vs O(x²)) for 10 elements is almost irrelevant.

Our work as a software engineers is to avoid unnecessary resource consumption and decrease the server costs.

The most important step when choosing a Data Structure is to know what kind of operations will be performed against that Data Structure.

Most common operations are Access, Search, Insertion and Deletion. Requirements may vary depending of each case but we base our research in those 4 as a first step.

Of course, the most valuable aspect of an algorithm is the programmer creativity. Let’s consider then, the following Data Structure table a cheatsheet for that.

 

Access Search Insertion Deletion Space
Array O(1) O(n) O(n) O(n) O(n)
Stack O(n) O(n) O(1) O(1) O(n)
Queue O(n) O(n) O(1) O(1) O(n)
List with PI O(n) O(n) O(1) O(1) O(n)
Hash table O(1)/O(n) O(1)/O(n) O(1)/O(n) >=O(n)

*as long as we overdimension the hash table there will be less collisions and we will get the item easily.

 

My plan is to get more deeply into the listed Data Structures. If you find interesting any other Data Structure, please comment below. I will appreciate any suggestion.