Java is like Kotlin
BASICS
Hello World
Java
System.out.println("Hello, world!")
Kotlin
println("Hello, world!")
Variables And Constants
Java
int myVariable = 42;
myVariable = 50;
final int myConstant = 42;

// Primitive Data Types:
byte myNumByte = 17;         // Size: 1 byte, Stores whole numbers from -128 to 127
short myNumShort = 55;       // Size: 2 bytes, Stores whole numbers from -32,768 to 32,767
int myNumInt = 5;            // Size: 4 bytes, Stores whole numbers from -2,147,483,648 to 2,147,483,647
long myNumLong = 12333;      // Size: 8 bytes, Stores whole numbers from -9,223,372,036,854,775,808
                             // to 9,223,372,036,854,775,807
float myNumFloat = 5.99f;    // Size: 4 bytes, Stores fractional numbers.
                             // Sufficient for storing 6 to 7 decimal digits
double myNumDouble = 76.24d; // Size: 8 bytes, Stores fractional numbers.
                             // Sufficient for storing 15 decimal digits
boolean myBool = true;
char myLetter = 'D';         // Size: 2 bytes, Stores a single character/letter or ASCII

// Non-Primitive Data Types:
// Non-primitive data types are called reference types because they refer to objects.
String myText = "Hello";     // String
Kotlin
var myVariable = 42
myVariable = 50
val myConstant = 42
// Kotlin has the keywords var (variable) and val (constant).
// The compiler in Kotlin can automatically assign the corresponding data type to a value.

val myNumByte: Byte = 17
val myNuShort: Short = 5555
val myNumInt: Int = 1000000000
val myNumLong: Long = 100000000000000000
val myNumFloat: Float = 5.99f
val myNumDouble: Double = 76.24
val myTrue: Boolean = true
val myFalse: Boolean = false
val boolNull: Boolean? = null
val myChar: Char = 'a'
val myString: String = "Hello World"

// Creates an Array with values ["0", "1", "4", "9", "16"]
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { println(it) }

// Primitive type arrays:
val myArray = IntArray(5) {42} // Array of int of size 5 with values [42, 42, 42, 42, 42]
myArray.forEach { println(it) }
// There are also, ByteArray, ShortArray,
Integer (Wrapper Class) vs int (Primitive Data Type)
Java
// Integer --> is a class or a reference type defined in the standard library
//         --> stores a reference to an object containing a value

// int --> is a primitive type and part of the language itself
//     --> stores an actual value

// Integer is the wrapper type for int, and objects of type Integer are boxed values.

// Each primitive type has a corresponding wrapper type:
// Primitive Data Type <--> Wrapper Class
// byte         <-->    Byte
// short        <--> 	Short
// int          <--> 	Integer
// long         <--> 	Long
// float 	<-->    Float
// double 	<-->    Double
// boolean 	<-->    Boolean
// char 	<-->    Character
Kotlin
Annotations
Java
Kotlin
Nullability
Java
// Annotations are used to provide supplement information about a program.
// Annotations start with ‘@’.
// Annotations do not change action of a compiled program.
// Annotations help to associate metadata (information) to the program elements i.e.
// instance variables, constructors, methods, classes, etc.
// Annotations are not pure comments as they can change the way a program is treated by compiler.

// Nullability Annotations:
@NonNull
@Nullable
// @Nullable and @NotNull annotations let you check nullability of a variable, parameter, or return value.
// The null-safety feature produces warnings at compile time.
// Such warnings may prevent catastrophic null pointer exceptions (NPEs) at runtime.

@NonNull
// Use this annotation to declare non-null constraint anywhere an object reference is expected:
// a field, a method parameter or a methods return value.

@Nullable
// Same as @NonNull, only with nullable instead of non-null.
Kotlin
// By default, Kotlin assumes that value cannot be null.
// You cannot assign null to reference a, and if you try to do so, it will result in a compiler error:
var a: String = "value"
//a = null
// Error: null can not be a value of a non-null type String

// If we want to create a nullable reference,
// we need to create append the question mark(?) to the type definition:
var b: String? = "value"
b = null
println(b)
// No Error
// println(b) --> null

// When we want to access the b reference, we must handle the null case explicitly:
if (b != null) {
    println("b ist nicht null, sondern $b")
} else {
    println("b ist null")
}
Explicit Types
Java
double explicitDouble = 70.0;
// oder
double explicitDouble = 70.0d;
Kotlin
val explicitDouble: Double = 70.0

// Implicit: automatically
// Explicit: manually
Type Coercion
Java
String label = "The width is ";
int width = 94;
String widthLabel = label + width;
System.out.println(widthLabel);
// widthLabel is a String

// TypeCoercion Error Example:
System.out.println('A' + 0);
// 65
System.out.println('A' + 50 + "A");
// 115A
System.out.println("A" + 'A' + 50);
// AA50
Kotlin
val label = "The width is "
val width = 94
val widthLabel = label + width
if(widthLabel is String) {
        println("widthLabel is of type String")
    }
// widthLabel is a String

// TypeCoercion Error Example:
println('A' + 0)
// A
println('A' + 50 + "A")
// sA
println("A" + 'A' + 50)
// AA50
String Interpolation
Java
int apples = 3;
int oranges = 5;
String fruitSummary = "I have " + (apples + oranges) +
    " pieces of fruit.";
Kotlin
val apples = 3
val oranges = 5
val fruitSummary = "I have ${apples + oranges}" +
    " pieces of fruit."

// String Interpolation:
// Evaluate a string literal that contains one or more placeholders.
Range Operator
Java
String[] names = {"Anna", "Alex", "Brian", "Jack"};
for (int i = 0; i < names.length; i++) {
    System.out.println("Person " + (i + 1) + " is called " + names[i]);
}
// Person 1 is called Anna
// Person 2 is called Alex
// Person 3 is called Brian
// Person 4 is called Jack
Kotlin
val names = arrayOf("Anna", "Alex", "Brian", "Jack")
val count = names.count()
for (i in 0..count - 1) {
    println("Person ${i + 1} is called ${names[i]}")
}
// Person 1 is called Anna
// Person 2 is called Alex
// Person 3 is called Brian
// Person 4 is called Jack
Inclusive Range Operator
Java
IntStream.rangeClosed(1, 5).forEach(i -> System.out.println(i + " times 5 is " + (i * 5)));
// or in two lines
IntStream.rangeClosed(1, 5).forEach(
                i -> System.out.println(i + " times 5 is " + (i * 5)));
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25
Kotlin
for (index in 1..5) {
    println("$index times 5 is ${index * 5}")
}
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25
Conditions and Loops
while-loops
Java
while ( Bedingung ) {
    // Bedingung muss True sein,
    // damit die Anweisung ausgeführt wird.
    Anweisung;
}

do {
    Anweisung;
} while ( Bedingung );
// Die Anweisung wird unabhängig der
// Bedingung immer mindestens 1-mal ausgeführt.

// Example:
int zahl = 1;
while (zahl <= 3) {
    System.out.println(zahl);
    zahl++;
}
System.out.println();
do {
    System.out.println("Wird mindestens einmal ausgeführt.");
    System.out.println(zahl);
    zahl++;
} while (zahl <= 3);

// Ausgabe:
// 1
// 2
// 3
//
// Ich werde vor der Bedingung mindestens einmal ausgeführt.
// 4
Kotlin
while ( Bedingung ) {
    // Bedingung muss True sein,
    // damit die Anweisung ausgeführt wird.
    Anweisung
}

do {
    Anweisung
} while ( Bedingung )
// Die Anweisung wird unabhängig der
// Bedingung immer mindestens 1-mal ausgeführt.

// Example:
var zahl: Int = 1
while (zahl <= 3){
    println(zahl)
    zahl++
}
println()
do {
    println("Wird mindestens einmal ausgeführt.")
    println(zahl)
    zahl++
} while (zahl <= 3)

// Ausgabe:
// 1
// 2
// 3
//
// Ich werde vor der Bedingung mindestens einmal ausgeführt.
// 4
for-loops
Java
for ( Laufvariable; Bedingung; Veränderung ) {
    // Bedingung muss True sein, damit die Anweisung ausgeführt wird.
    Anweisung;
}

// Example:
for (int counter = 1; counter <= 5; counter++) {
    System.out.println("Zaeler ist bei: " + counter);
}
// Ausgabe:
// Zaeler ist bei: 1
// Zaeler ist bei: 2
// Zaeler ist bei: 3
// Zaeler ist bei: 4
// Zaeler ist bei: 5
Kotlin
for (counter in 1..5) {
    println("Zaeler ist bei: $counter")
}
// Ausgabe:
// Zaeler ist bei: 1
// Zaeler ist bei: 2
// Zaeler ist bei: 3
// Zaeler ist bei: 4
// Zaeler ist bei: 5

// No need to declare the data type of variable.
// If iterating over a range, we can use in
// the lower and upper (including) limit can
// be defined on both the sides of .. Operator.
break
Java
// break --> Schleife wird komplett abgebrochen.
for (int i = 0; i < 5; i++) {
    System.out.println(i);
    if (i == 2) {
        break;
    }
}
System.out.println("nach Schleife");
// Ausgabe:
// 0
// 1
// 2
// nach Schleife

// Zum Vergleich:
for (int i = 0; i < 5; i++) {
    System.out.println(i);
}
System.out.println("nach Schleife");
// Ausgabe:
// 0
// 1
// 2
// 3
// 4
// nach Schleife
Kotlin
// break --> Schleife wird komplett abgebrochen.
for (i in 0..4) {
    println(i)
    if (i == 2) {
        break
    }
}
println("nach Schleife")
// Ausgabe:
// 0
// 1
// 2
// nach Schleife

// Zum Vergleich:
for (i in 0..4) {
    println(i)
}
println("nach Schleife")
// Ausgabe:
// 0
// 1
// 2
// 3
// 4
// nach Schleife
continue
Java
// continue --> Momentaner Schleifendurchlauf wird übersprungen.
for (int i = 0; i < 5; i++) {
    System.out.println(i);
    if (i == 3) {
        continue;
    }
    System.out.println("nach continue");
}
System.out.println("nach Schleife");
// Ausgabe:
// 0
// nach continue
// 1
// nach continue
// 2
// nach continue
// 3
// 4
// nach continue
// nach Schleife

// Zum Vergleich:
for (int i = 0; i < 5; i++) {
    System.out.println(i);
    System.out.println("nach continue");
}
System.out.println("nach Schleife");
// Ausgabe:
// 0
// nach continue
// 1
// nach continue
// 2
// nach continue
// 3
// nach continue <--
// 4
// nach continue
// nach Schleife
Kotlin
// continue --> Momentaner Schleifendurchlauf wird übersprungen.
for (i in 0..4) {
    println(i)
    if (i == 3) {
        continue
    }
    println("nach continue")
}
println("nach Schleife")
// Ausgabe:
// 0
// nach continue
// 1
// nach continue
// 2
// nach continue
// 3
// 4
// nach continue
// nach Schleife

// Zum Vergleich:
for (i in 0..4) {
    println(i)
    println("nach continue")
}
println("nach Schleife")
// Ausgabe:
// 0
// nach continue
// 1
// nach continue
// 2
// nach continue
// 3
// nach continue <--
// 4
// nach continue
// nach Schleife
for-each-loops
Java
for ( Datentyp Element : Collection ){
    // Bedingung, die Element enthält
}

public static void main(String[] args) {
    int viererReihe [] = new int [5];
    for (int i = 0; i < viererReihe.length; i++) {
        viererReihe[i] = (i + 1) * 4;
    }
    for (int i: viererReihe){
        System.out.println(i);
    }
}
// Ausgabe:
// 4
// 8
// 12
// 16
// 20
Kotlin
val viererReihe = IntArray(5)
for (i in viererReihe.indices) {
    viererReihe[i] = (i + 1) * 4
}
for (i in viererReihe) {
    println(i)
}

// Ausgabe:
// 4
// 8
// 12
// 16
// 20
if-expression
Java
int zahl = 2;
if (zahl <= 1){
    // Bedingung muss True sein, damit die Anweisung ausgeführt wird.
    System.out.println(zahl + " kleiner oder gleich 1");
} else if (zahl == 2) {
    System.out.println(zahl + " ist gleich 2");
} else {
    System.out.println(zahl + " ist größer als 2");
}
// Ausgabe:
// 2 ist gleich 2
Kotlin
var zahl: Int = 2
if (zahl <= 1) {
    // Bedingung muss True sein, damit die Anweisung ausgeführt wird.
    println("$zahl kleiner oder gleich 1")
} else if (zahl == 2) {
    println("$zahl ist gleich 2")
} else {
    println("$zahl ist größer als 2")
}
// Ausgabe:
// 2 ist gleich 2
switch/when
Java
int zahl = 2;
switch (zahl) {
    case 1:
        System.out.println("Zahl ist gleich 1");
        break;
    case 2:
        System.out.println("Zahl ist gleich 2");
        break;
    default:
        System.out.println("Zahl ist weder 1 noch 2");
        break;
}
// Ausgabe:
// Zahl ist gleich 2
Kotlin
var zahl: Int = 2
when (zahl) {
    1 -> println("Zahl ist gleich 1")
    2 -> println("Zahl ist gleich 2")
    else -> {
        println("Zahl ist weder 1 noch 2")
    }
}
// Ausgabe:
// Zahl ist gleich 2
Collections
Arrays
Java
// declares an array of String:
String[] anArrayWithTheNameArray;
// allocates memory for 4 String:
anArrayWithTheNameArray = new String[4];

// initialize of elements:
anArrayWithTheNameArray[0] = "catfish";
anArrayWithTheNameArray[1] = "water";
anArrayWithTheNameArray[2] = "tulips";
anArrayWithTheNameArray[3] = "blue paint";

// Replacing the second element
anArrayWithTheNameArray[1] = "bottle of water";

for (String element : anArrayWithTheNameArray) {
    System.out.println(element);
}

// Ausgabe:
// catfish
// bottle of water
// tulips
// blue paint
---------------------------------------------------------------

// Declares an array of String and initialize the elements in one:
String[] anArrayWithTheNameArray = {"catfish", "water", "tulips", "blue paint"};

// Replacing the second element
anArrayWithTheNameArray[1] = "bottle of water";

for (String element : anArrayWithTheNameArray) {
    System.out.println(element);
}
// Ausgabe:
// catfish
// bottle of water
// tulips
// blue paint
Kotlin
// declares an array of String:

// allocates memory for 4 String:
val anArrayWithTheNameArray: Array = arrayOfNulls(4)
// ? --> Can be null.

// initialize of elements:
anArrayWithTheNameArray[0] = "catfish"
anArrayWithTheNameArray[1] = "water"
anArrayWithTheNameArray[2] = "tulips"
anArrayWithTheNameArray[3] = "blue paint"

// Replacing the second element
anArrayWithTheNameArray[1] = "bottle of water"

for (element in anArrayWithTheNameArray) {
    println(element)
}
// Ausgabe:
// catfish
// bottle of water
// tulips
// blue paint
---------------------------------------------------------------

// Declares an array of String and initialize the elements in one:
val anArrayWithTheNameArray = arrayOf("catfish", "water",
    "tulips", "blue paint")

// Replacing the second element
anArrayWithTheNameArray[1] = "bottle of water"

for (element in anArrayWithTheNameArray) {
    println(element)
}
// Ausgabe:
// catfish
// bottle of water
// tulips
// blue paint
Listen
Java
java.util.List anListWithTheNameList = java.util.Arrays.asList("catfish", "water", "tulips", "blue paint");
anListWithTheNameList.set(1, "bottle of water");
for (String s : anListWithTheNameList) {
    System.out.println(s);
}
// Ausgabe:
// catfish
// bottle of water
// tulips
// blue paint
Kotlin
val anListWithTheNameList = mutableListOf("catfish", "water", "tulips", "blue paint")
anListWithTheNameList[1] = "bottle of water"
for (s in anListWithTheNameList) {
    println(s)
}
// Ausgabe:
// catfish
// bottle of water
// tulips
// blue paint
Maps
Java
Kotlin
val occupations = mutableMapOf(
    "Malcolm" to "Captain",
    "Kaylee" to "Mechanic"
)
occupations["Jayne"] = "Public Relations"
Empty Collections
Java
Kotlin
val emptyArray = arrayOf<String>()
val emptyMap = mapOf<String, Float>()
Quantities
Java
Kotlin
fun main() {
    val a = listOf("a", "b", "c", "d")
    val b = listOf("d", "e", "f", "a")
    println("a=$a b=$b") // a=[a, b, c, d] b=[d, e, f, a]
    println("combined ${a + b}") // combined [a, b, c, d, d, e, f, a]
    println("union ${a.union(b)}") // union [a, b, c, d, e, f]
    val ab = a.toMutableList()
    ab.retainAll(b)
    println("a retainAll b $ab") // a retainAll b [a, d]
    val ba = b.toMutableList()
    ba.retainAll(a)
    println("b retainAll a $ba") // b retainAll a [d, a]
}
// Ausgabe:
// a=[a, b, c, d] b=[d, e, f, a]
// combined [a, b, c, d, d, e, f, a]
// union [a, b, c, d, e, f]
// a retainAll b [a, d]
// b retainAll a [d, a]
Combining multiple collections.
Combination of A and B
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Combination_of_A_and_B {
    public static void main(String[] args) {
        List A = new ArrayList<>(Arrays.asList("a", "b", "c", "d", "e"));
        List B = new ArrayList<>(Arrays.asList("f", "e", "h", "b", "e"));

        System.out.println("Liste A: " + A);
        System.out.println("Liste B: " + B);

        A.addAll(B); // Inserts the elements of list B at the end of list A.
        System.out.println("Combination of A and B: " + A);
    }
}
// Ausgabe:
// Liste A: [a, b, c, d, e]
// Liste B: [f, e, h, b, e]
// Combination of A and B: [a, b, c, d, e, f, e, h, b, e]
Kotlin
fun main() {
    val a = mutableListOf("a", "b", "c", "d", "e")
    val b = mutableListOf("f", "e", "h", "b", "e")

    println("Liste a: $a")
    println("Liste b: $b")

    a.addAll(b) // Inserts the elements of list b at the end of list a.
    println("Combination of a and b: $a")
}
// Ausgabe:
// Liste a: [a, b, c, d, e]
// Liste b: [f, e, h, b, e]
// Combination of a and b: [a, b, c, d, e, f, e, h, b, e]
Union of A and B
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Union_of_A_and_B {
    public static void main (String[] args) {
        List A = new ArrayList<>(Arrays.asList("a","b","c","d","e"));
        List B = new ArrayList<>(Arrays.asList("f","e","h","b","e"));

        System.out.println("Liste A: " + A);
        System.out.println("Liste B: " + B);

        Set setAB = new HashSet<>();

        // Adds the elements of lists A and B to the set setAB:
        setAB.addAll(A);
        setAB.addAll(B);

        System.out.println("Union of A and B: " + setAB);
    }
}
// Ausgabe:
// Liste A: [a, b, c, d, e]
// Liste B: [f, e, h, b, e]
// Union of A and B: [a, b, c, d, e, f, h]
Kotlin
fun main() {
    val a = mutableListOf("a", "b", "c", "d", "e")
    val b = mutableListOf("f", "e", "h", "b", "e")

    println("Liste a: $a")
    println("Liste b: $b")

    val setab = mutableSetOf()

    // Adds the elements of lists a and b to the set setab:
    setab.addAll(a)
    setab.addAll(b)

    println("Union of a and b: $setab")

    // In Kotlin there is the function .union() which
    // makes it much easier to get to the union of two collections:
    println("Union of a and b: ${a.union(b)}")
}
// Ausgabe:
// Liste a: [a, b, c, d, e, f, h]
// Liste b: [f, e, h, b, e]
// Union of a and b: [a, b, c, d, e, f, h]
// Union of a and b: [a, b, c, d, e, f, h]
Intersection of A and B
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Intersection_of_A_and_B {
    public static void main(String[] args) {
        List A = new ArrayList<>(Arrays.asList("a","b","c","d","e"));
        List B = new ArrayList<>(Arrays.asList("f","e","h","b","e"));

        System.out.println("Liste A: " + A);
        System.out.println("Liste B: " + B);

        A.retainAll(B); // Retains only the elements in A that are contained in B.
        System.out.println("Intersection of A and B: " + A);
    }
}
// Ausgabe:
// Liste A: [a, b, c, d, e]
// Liste B: [f, e, h, b, e]
// Intersection of A and B: [b, e]
Kotlin
fun main() {
    val a = mutableListOf("a", "b", "c", "d", "e")
    val b = mutableListOf("f", "e", "h", "b", "e")

    println("Liste a: $a")
    println("Liste b: $b")

    a.retainAll(b) // Retains only the elements in a that are contained in b.
    println("Intersection of a and b: $a")

    // In Kotlin there is the function .intersect() which
    // makes it much easier to get to the intersection of two collections:
    println("Intersection of a and b: ${a.intersect(b)}")
}
// Ausgabe:
// Liste a: [a, b, c, d, e]
// Liste b: [f, e, h, b, e]
// Intersection of a and b: [b, e]
// Intersection of a and b: [b, e]
Symmetric difference of A and B
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Symmetric_difference_of_A_and_B {
    public static void main(String[] args) {
        List A = new ArrayList<>(Arrays.asList("a","b","c","d","e"));
        List B = new ArrayList<>(Arrays.asList("f","e","h","b","e"));

        System.out.println("Liste A: " + A);
        System.out.println("Liste B: " + B);


        Set symmetricDiff = new HashSet<>(A);
        symmetricDiff.addAll(B);
        // symmetricDiff now contains the union
        System.out.println("Union of A and B: " + symmetricDiff);

        Set intersection = new HashSet<>(A);
        intersection.retainAll(B);
        // intersection now contains the intersection
        System.out.println("Intersection of A and B: " + intersection);

        symmetricDiff.removeAll(intersection);
        // union minus intersection equals symmetric-difference
        System.out.println("------------------");
        System.out.println("Symmetric difference of A and B: " + symmetricDiff);
    }
}
// Ausgabe:
// Liste A: [a, b, c, d, e]
// Liste B: [f, e, h, b, e]
// Union of A and B: [a, b, c, d, e, f, h]
// Intersection of A and B: [b, e]
// ------------------
// Symmetric difference of A and B: [a, c, d, f, h]
Kotlin
fun main() {
    val a = mutableListOf("a", "b", "c", "d", "e")
    val b = mutableListOf("f", "e", "h", "b", "e")

    println("Liste a: $a")
    println("Liste b: $b")


    val symmetricDiff = mutableSetOf()
    symmetricDiff.addAll(a)
    symmetricDiff.addAll(b)
    // symmetricDiff now contains the union
    println("Union of a and b: $symmetricDiff")

    val intersection = mutableSetOf()
    intersection.addAll(a)
    intersection.retainAll(b)
    // intersection now contains the intersection
    println("Intersection of a and b: $intersection")

    symmetricDiff.removeAll(intersection)
    // union minus intersection equals symmetric-difference
    println("------------------")
    println("Symmetric difference of a and b: $symmetricDiff")
}
// Ausgabe:
// Liste a: [a, b, c, d, e]
// Liste b: [f, e, h, b, e]
// Union of a and b: [a, b, c, d, e, f, h]
// Intersection of a and b: [b, e]
// ------------------
// Symmetric difference of a and b: [a, c, d, f, h]
Relative complement of A and B
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Relative_complement_of_A_and_B_2 {
    public static void main(String[] args) {
        List A = new ArrayList<>(Arrays.asList("a","b","c","d","e"));
        List B = new ArrayList<>(Arrays.asList("f","e","h","b","e"));

        System.out.println("Liste A: " + A);
        System.out.println("Liste B: " + B);

        A.removeAll(B); // Removes all elements of B that are also contained in A.
        System.out.println("------------------");
        System.out.println("Relative complement of A and B: " + A);
    }
}
// Ausgabe:
// Liste A: [a, b, c, d, e]
// Liste B: [f, e, h, b, e]
// ------------------
// Relative complement of A and B: [a, c, d]
Kotlin
fun main() {
    val a = mutableListOf("a", "b", "c", "d", "e")
    val b = mutableListOf("f", "e", "h", "b", "e")

    println("Liste A: $a")
    println("Liste B: $b")

    a.removeAll(b) // Removes all elements of b that are also contained in a.

    println("------------------")
    println("Relative complement of a and b: $a")

    // To determine the relative complement in Koltin, you can also use the minus operator:
    val relativeComp = a-b
    println("Relative complement of a and b: $relativeComp")
}
// Liste A: [a, b, c, d, e]
// Liste B: [f, e, h, b, e]
// ------------------
// Relative complement of a and b: [a, c, d]
// Relative complement of a and b: [a, c, d]
FUNCTIONS
Parameters
Java
public class Parameters {
    public static void main(String[] args) {
        // Code that is executed
        int result = parameter(20,5);
        System.out.println("Das Ergebnis lautet: " + result);
        result = parameterWithLinebreaks(20,5);
        System.out.println("Das Ergebnis lautet: " + result);
    }

    // Definition of parameters: type name
    // Parameters are separated using commas.
    public static int parameter(int number, int subtracted) {
        return number - subtracted;
        // The return keyword is used to return
        // the difference of the val number and val subtracted.
    }

    // Function with line breaks between parameters:
    public static int parameterWithLinebreaks(
            int number,
            int subtracted
    )
    {
        return number - subtracted;
    }
}
// Ausgabe:
// Das Ergebnis lautet: 15
// Das Ergebnis lautet: 15
Kotlin
fun main() {
    // Code that is executed
    var result = parameter(20,5)
    println("Das Ergebnis lautet: $result")
    result = parameterWithLinebreaks(20,5)
    println("Das Ergebnis lautet: $result")
}

// Definition of parameters: name: type
// Parameters are separated using commas.
fun parameter(number: Int, subtracted: Int): Int {
    return number - subtracted
    // The return keyword is used to return
    // the difference of the val number and val subtracted.
}

// Function with line breaks between parameters:
fun parameterWithLinebreaks(
        number: Int,
        subtracted: Int, // trailing comma
): Int // Type that is returned
{
    return number - subtracted
}
// Ausgabe:
// Das Ergebnis lautet: 15
// Das Ergebnis lautet: 15
Default arguments
Java
public class Default_arguments {
    public static void main(String[] args) {
        // Java does not support the following named inputs for methods.
        // int result = product(number = 5, multiplier = 3);
        int result = product(5,3);
        // Since there is no default value,
        // the method product uses 5 as the multiplier value instead of 3.

        System.out.println("Das Ergebnis lautet: " + result);
    }

    // Java does not have default parameters.
    public static int product(
            int number,
            int multiplier
    )
    {
        multiplier = 5;
        return number * multiplier;
    }
}
// Ausgabe:
// Das Ergebnis lautet: 25
Kotlin
fun main() {
    var result = product(number = 5) // Default argument multiplier is used.
    println("Das Ergebnis lautet: $result")
    result = product(5,3) // Default argument multiplier is not used.
    println("Das Ergebnis lautet: $result")
}

// Function parameters can have default values,
// which are used when you skip the corresponding argument:
fun product(
        number: Int,
        multiplier: Int = 5, // This is a default value
): Int
{
    return number * multiplier
}
// Ausgabe:
// Das Ergebnis lautet: 25
// Das Ergebnis lautet: 15
Named arguments
Java
public class Named_arguments {
    public static void main(String[] args) {
        // Calling the Parameters method from the Parameters.java class:
        int result = Parameters.parameter(10,5);
        System.out.println("Das Ergebnis lautet: " + result);
        // Java does not support named parameters
        // for constructors or method arguments.
    }
}
// Ausgabe:
// Das Ergebnis lautet: 5
Kotlin
fun main() {
    // If the file of the function you wish to call is
    // not in the same package, you must import that file.
    // Calling the Parameters function from the Parameters.kt file:
    var result = parameter(number = 10, subtracted = 5) // subtracted and number are named arguments
    // You can freely change the order in which you call named arguments:
    println("Das Ergebnis lautet: $result")
    result = parameter(subtracted = 5, number = 10)
    println("Das Ergebnis lautet: $result")
}
// Ausgabe:
// Das Ergebnis lautet: 5
// Das Ergebnis lautet: 5
Unit-returning
Java
Kotlin
// If a function does not return any useful value, its return type is Unit.
// The Unit value does not have to be returned explicitly:
fun unit(name: String?): Unit { // The Unit return type declaration is optional.
    if (name != null) {
        println("Hello $name")
    } else {
        println("Hello")
    }
    // return Unit or return is optional
}
Local functions
Java
Kotlin
fun main(){
    println(over(number = 5))
}

fun over(number: Int): String {
    val multiplier = 5
    // Kotlin supports local functions, which are functions inside another function:
    fun local(multiplier: Int): Int {
        // The local function local can use the local val number of the outer function.
        return number * multiplier
    }
    return "The product of $number and $multiplier is: ${local(multiplier)}"
}
// Ausgabe:
// The product of 5 and 5 is: 25
Visibility modifiers
Java
public class Visibility_modifiers {
    public static void main(String[] args) {
        int result = Default_arguments.product(5,5);
        // The product method is from the Default_arguments.java
        // Class can be used because it is puplic.
        // If the modifier is not specified, it is puplic.

        System.out.println(result);
        System.out.println(hello());
    }

    // The modifier private means that the method hello
    // can only be used in the class where it was declared.
    private static String hello() {
        return "Hello";
    }
}
// Ausgabe:
// 25
// Hello
Kotlin
package de.check24.learningKotlinJava.kotlin.functions

import de.check24.learningKotlinJava.kotlin.test

fun main() {
    val result = product(5,5)
    // The product function from the Default_arguments.kt
    // file can be used because it is puplic.
    // If the modifier is not specified, it is puplic.

    println(result)
    hello()
    test()
}
// The modifier private means that the function hello
// can only be used in the file where it was declared.
private fun hello() {
    return println("Hello")
}

// internal is an alternative to Java’s package-private.
// internal means that the declarations are visible inside a module.

// protected:
// Declarations are only visible in its class and in its subclassess

// Ausgabe:
// 25
// Hello
// Test

---------------------------------------------------------------

package de.check24.learningKotlinJava.kotlin

internal fun test() {
    return println("Test")
}
FUNCTIONS
Functions
Java
public class Functions {
    public static void main(String[] args) {
        System.out.println(greet("Bob","Tuesday"));
        greet2("Max", "Monday");
    }

    public static String greet(String name, String day) {
        return "Hello " + name + ", today is " + day + ".";
    }

    public static void greet2(String name, String day) {
        System.out.println("Hello " + name + ", today is " + day + ".");
    }
}
// Ausgabe:
// Hello Bob, today is Tuesday.
// Hello Max, today is Monday.
Kotlin
fun main() {
    fun greet(name: String, day: String): String {
        return "Hello $name, today is $day."
    }
    fun greet2(name: String, day: String) {
        println("Hello $name, today is $day.")
    }

    // Aufrufen der Funktion greet
    println(greet("Bob", "Tuesday"))

    // Aufrufen der Funktion greet2
    greet2("Max","Monday")
}
// Ausgabe:
// Hello Bob, today is Tuesday.
// Hello Max, today is Monday.
Functions
Java
public class Functions {
    public static void main(String[] args) {
        final Integer result1 = double1(2,2);
        final Integer result2 = double2(2,2);

        System.out.println("double1: " + result1);
        System.out.println("double2: " + result2);
        // You can also call the function inside the println function:
        System.out.println("double1: " + double1(2,2));
        System.out.println("double2: "+ double2(2,2));
    }

    public static Integer double1(Integer zahl, Integer multiplier) {
        return zahl * multiplier;
    }

    // Function with line breaks between parameters:
    public static Integer double2(
            Integer zahl,
            Integer multiplier
    )
    {
        return zahl * multiplier;
    }
}
// Ausgabe:
// double1: 4
// double2: 4
// double1: 4
// double2: 4
Kotlin
// Functions in Kotlin are declared using the fun keyword:
fun main() {
    val result1 = double1(2,2)
    val result2 = double2(2,2)

    println("double1: $result1 \ndouble2: $result2")
    // You can also call the function inside the println function:
    println("double1: ${double1(2,2)}\ndouble2: ${double2(2,2)}")

    println(double3(zahl = 5)) // The default value multiplikator = 2 is used.
}

fun double1(zahl: Int, multiplikator: Int): Int {
    return zahl * multiplikator
}

// Function with line breaks between parameters:
fun double2(
        zahl: Int,
        multiplikator: Int, // trailing comma
): Int
{
    return zahl * multiplikator
}

// Function parameters can have default values,
// which are used when you skip the corresponding argument:
fun double3(
        multiplikator: Int = 2,
        zahl: Int,
): Int
{
    return zahl * multiplikator
}
// Ausgabe:
// double1: 4
// double2: 4
// double1: 4
// double2: 4
// 10
Tuple Return
Java
Kotlin
data class GasPrices(val a: Double, val b: Double,
     val c: Double)
fun getGasPrices() = GasPrices(3.59, 3.69, 3.79)
Variable Number Of Arguments
Java
Kotlin
fun sumOf(vararg numbers: Int): Int {
    var sum = 0
    for (number in numbers) {
        sum += number
    }
    return sum
}
sumOf(42, 597, 12)

// sumOf() can also be written in a shorter way:
fun sumOf(vararg numbers: Int) = numbers.sum()
Function Type
Java
Kotlin
fun makeIncrementer(): (Int) -> Int {
    val addOne = fun(number: Int): Int {
        return 1 + number
    }
    return addOne
}
val increment = makeIncrementer()
increment(7)

// makeIncrementer can also be written in a shorter way:
fun makeIncrementer() = fun(number: Int) = 1 + number
Map
Java
Kotlin
val numbers = listOf(20, 19, 7, 12)
numbers.map { 3 * it }
Sort
Java
Kotlin
listOf(1, 5, 3, 12, 2).sorted()
Named Arguments
Java
Kotlin
fun area(width: Int, height: Int) = width * height
area(width = 2, height = 3)

// This is also possible with named arguments
area(2, height = 2)
area(height = 3, width = 2)
CLASSES
Declaration
Java
public class Declaration {
    // Classes in Java are declared using the keyword class:
    public class Classname {
        // Code of the class Classname
    }

    // Curly braces cannot be omitted even if the class has no body:
    public class Empty {}

    // Declaring a class with multiple properties:
    public class Person{
        String firstName; // Create a class attribute
        String lastName;
        int age;
    }
}
Kotlin
// Classes in Kotlin are declared using the keyword class:
class Classname {
    // Code of the class Classname
}

// If the class has no body, curly braces can be omitted:
class Empty

// Declaring a class with multiple properties:
class Person(
        val firstName: String,
        val lastName: String,
        var age: Int, // trailing comma
) {
    // Code of the class Person
}
Constructors
Java
public class Constructors {
    int number; // Create a class attribute

    // Create a class constructor for the Constructors class:
    public Constructors() {
        number = 5; // Set the initial value for the class attribute number
    }

    public static void main(String[] args) {
        // Create an object of class Constructors
        // (This will call the constructor):
        Constructors someObject = new Constructors();
        // Print the value of number:
        System.out.println("The value of number is: " + someObject.number);
    }
}
// Ausgabe:
// The value of number is: 5
Kotlin
// A class in Kotlin can have a primary constructor and one or more secondary constructors.

// The primary constructor is part of the class header,
// it goes after the class name (and optional type parameters):
class withconstructorKeywort constructor(firstName: String) {
    // Code of the class Person
}

// primary constructor: constructor(firstName: String)

// If the primary constructor does not have any annotations or
// visibility modifiers, the constructor keyword can be omitted:
class withoutconstructorKeywort (firstName: String) {
    // Code of the class Person
}
Initialization
Java
import java.util.Locale;

public class Initialization {
    static class InitTestClass {
        String someString1 = "Hello";
        int zahl = 5;
        {
            System.out.println("Die Zahl lautet: " + zahl);
            String someString2 = "World";
            System.out.println(someString1 + " " + someString2);
        }

        int zahlAdded2 = zahl + 2;
        {
            System.out.println("Die Zahl " + zahl + " + 2 lautet: " + zahlAdded2);
            System.out.println(someString1.toUpperCase(Locale.ROOT));
        }
    }

    public static void main(String[] args) {
        InitTestClass someObject = new InitTestClass();
        System.out.println(someObject);
    }
}
// Ausgabe:
// Die Zahl lautet: 5
// Hello World
// Die Zahl 5 + 2 lautet: 7
// HELLO
Kotlin
// Initialization code can be placed in initializer blocks,
// which are prefixed with the init keyword.

// During an instance initialization,
// the initializer blocks are executed in the same order
// as they appear in the class body, interleaved with the property initializers:
class InitTestClass(zahl: Int) {
    // val and var that have been declared outside
    // of an init can be used by all following inits:
    val someString1 = "Hello"

    init {
        println("Die Zahl lautet: $zahl")
        // val and var, which were declared within an init,
        // can also only be used in this init:
        val someString2 = "World"
        println("$someString1 $someString2")
    }

    val zahlAdded2 = zahl + 2
    init {
        println("Die Zahl $zahl + 2 lautet: $zahlAdded2")
        println(someString1.toUpperCase())
    }

}

fun main () {
    // Executing the class InitTestClass:
    InitTestClass(5)
}
// Ausgabe:
// Die Zahl lautet: 5
// Hello World
// Die Zahl 5 + 2 lautet: 7
// HELLO
Default Value
Java
Kotlin
// You can provide default value to constructor parameters:
class defaultValue (name: String, age: Int = 18) {
    init {
        println("$name ist $age Jahre alt.")
    }
}

fun main () {
    defaultValue("Markus")
    defaultValue(name = "Max", age = 22)
}
// Ausgabe:
// Markus ist 18 Jahre alt.
// Max ist 22 Jahre alt.
Creating Instances of Classes
Java
Kotlin
class Instances (nachname: String, vorname: String){
    init {
        println("Der Name der person lautet: $vorname $nachname")
    }
}

fun main () {
    // To create an instance of a class,
    // call the constructor as if it were a regular function:
    val instance1 = Instances("Mustermann","Max")
    val instance2 = Instances("Müller","Markus")
    instance1
    instance2
}
// Ausgabe:
// Der Name der person lautet: Max Mustermann
// Der Name der person lautet: Markus Müller
Inheritance
Java
Kotlin
// All classes in Kotlin have a common superclass, which is Any.
// Any has three methods: equals(), hashCode() and toString()

// By default, Kotlin classes are final: they can’t be inherited.
// To make a class inheritable, one needs to mark it with the open keyword:
open class Inheritable {
    val number1 = 5
    val number2 = 5
}

// Addition inherits the val number1 and val number2 from Inheritable:
class Addition : Inheritable() {
    val sum = number1 + number2
    init {
        println("Die Summe von $number1 und $number2 lautet $sum")
    }
}

fun main () {
    Addition()
}
// Ausgabe:
// Die Summe von 5 und 5 lautet 10
Overriding Methods
Java
Kotlin
open class First {
    open fun number (zahl: Int): Int{
        return zahl * 2
    }
}

class Second() : First() {
    init {
        println(number(5))
    }
    // The override modifier overwrites the
    // original function with the following one:
    override fun number(zahl: Int): Int {
        return zahl * 3
    }
    // To prohibit re-overriding, put the
    // keyword final in front of the keyword override:
    // final override fun number(zahl: Int): Int
}

fun main () {
    print("Die Summe lautet: ")
    Second()
}
// Ausgabe:
// Die Summe lautet: 15
Overriding Properties
Java
Kotlin
open class Number1 {
    open val firstNumber: Int = 5
}

class Number2 : Number1(){
    // Override the val firstNumber:
    override val firstNumber = 10
    init {
        println(firstNumber)
    }
}

fun main () {
    print("val firstNumber after override: ")
    Number2()
}
// Ausgabe:
// val firstNumber after override: 10
CLASSES
Declaration
Java
Kotlin
class Shape {
    var numberOfSides = 0
    fun simpleDescription() =
        "A shape with $numberOfSides sides."
}
Usage
Java
Kotlin
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
Subclass
Java
Kotlin
open class NamedShape(val name: String) {
    var numberOfSides = 0

    open fun simpleDescription() =
        "A shape with $numberOfSides sides."
}

class Square(var sideLength: BigDecimal, name: String) :
        NamedShape(name) {
    init {
        numberOfSides = 4
    }

    fun area() = sideLength.pow(2)

    override fun simpleDescription() =
        "A square with sides of length $sideLength."
}

val test = Square(BigDecimal("5.2"), "square")
test.area()
test.simpleDescription()
Checking Type
Java
Kotlin
var movieCount = 0
var songCount = 0

for (item in library) {
    if (item is Movie) {
        ++movieCount
    } else if (item is Song) {
        ++songCount
    }
}
Pattern Matching
Java
Kotlin
val nb = 42
when (nb) {
    in 0..7, 8, 9 -> println("single digit")
    10 -> println("double digits")
    in 11..99 -> println("double digits")
    in 100..999 -> println("triple digits")
    else -> println("four or more digits")
}
Downcasting
Java
Kotlin
for (current in someObjects) {
    if (current is Movie) {
        println("Movie: '${current.name}', " +
	    "dir. ${current.director}")
    }
}
Protocol
Java
Kotlin
interface Nameable {
    fun name(): String
}

fun f<T: Nameable>(x: T) {
    println("Name is " + x.name())
}
Extensions
Java
Kotlin
val Double.km: Double get() = this * 1000
val Double.m: Double get() = this
val Double.cm: Double get() = this / 100
val Double.mm: Double get() = this / 1000
val Double.ft: Double get() = this / 3.28084

val oneInch = 25.4.mm
println("One inch is $oneInch meters")
// prints "One inch is 0.0254 meters"
val threeFeet = 3.0.ft
println("Three feet is $threeFeet meters")
// prints "Three feet is 0.914399970739201 meters"