Kotlin Koans—Part 7

This portion of the Kotlin Koans showed off a really boss feature of the language: Data Classes. These are special classes whose primary purpose is to hold data.

Here is a Java class that we start with that’s taken directly from the tutorial.

public class Person {
        private final String name;
        private final int age;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }

It’s not a special class. This is a class with a primary constructor, getters/setters and two private variables. It’s also one of my biggest complaints about the Java language. I can do the same thing in Python like this.

class Person:
    def __init__(self, name=None, age=None):
        self.name = name
        self.age = age

Four lines of code in Python. In all fairness to Java, would could just declare name and age to be public variables, but doing so is not only frowned upon, but many Java libraries look for getter/setter method to access a property of a Java bean. Basically speaking, even though we could allow for public access of a Java property, it’s not really practical at this point.

There is a Java library called Lombok that does a lot to solve this problem.

@Data
public class Person {
    private String name;
    private String age;
}

Lombok has been the solution I have used for most of my projects. It’s not perfect however. For example, I can’t use the @Data annotation to make a read only class. That forces me to use a mix of Lombok annotations or define a stereotype annotation. It’s not a huge problem, but it’s still something to think about.

Kotlin data classes take this to a whole other level. Here is the same class in Kotlin.

data class Person(val name: String, val age: Int)

That’s it! One line of code!!! With this single line of code, we get our two properties, it’s getter methods, hashcode, equals, toString() and a constructor. The class is immutable because the variables are declared with the val keyword. We can make the class mutable by using var instead of val. Finally, we aren’t losing our ability to work with existing Java libaries.

I really don’t see how it can get any better than this. I have used data classes countless times when working with ORM libraries such as hibernate. I’d say 95% of these classes are classes that just hold data and map to a table in the database. Although any IDE can generate constructors, getters/setters, equals, and hashcode, and toString, let’s face it, it’s even better to have this built directly into the language itself.

You can click here to see Part 6

Advertisements

Kotlin Koans—Part 6

Insert Values into String

Kotlin upgrades some of Java’s String capabilities. One of the first things I liked was the ability to insert variables into the String

val a = 1
val b = 2
str = "Here is a String with values a=$a and b=$b)

We could of course have done this with String.format in Java

int a = 1;
int b = 2;
String str = "Here is a String with values a=%d and b=%d".format(a, b);

I think most people agree that the Kotlin approach is more concise.

Multiline Strings

Kotlin supports the “”” for mutliline strings without any need to escape charaters.

str = """
Here is a multiline String
C:\folder\file.txt

"""

The Kotlin Koans tutorial suggested that this was also useful for Regex expressions.

Task

The task for this portion of the tutorial was simple enough. We have a variable named month that we insert into a regex expression.

val month = "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)"

fun task5(): String{
    return """\d{2}\ $month \d{4}"""
}

This a use case for the triple quote Strings. In Java, we would have needed to escape all of the backslashes in the regex expression. I know that I am not the first developer who has gotten burned by typing \ when I should have typed \\, so the triple quote String is a nice feature.

You can click here to see Part 5.

Kotlin Koans—Part 5

Many modern programming lanugages have support for functional programming. I remember when Java got support for functional programming in JDK8. I have to say it was awesome to finally get support for functional programming.

Of course, Java has supported functional programming to a certain degree for a while now through anonymous inner classes. The syntax was verbose…

public class Window extends JFrame {
    
    public Window(){
        JButton jButton = new JButton("Button");
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Clicked");
            }
        });
    }
}

Java 8 simplified this mess when it officially supported functional programming.

public class Window extends JFrame {

    public Window(){
        JButton jButton = new JButton("Button");
        jButton.addActionListener(e -> System.out.println("Clicked"));
    }
}

Readers can see that the above code is far more consise than the previous example so many Java developers, including myself, were greatful for the change. Android developers weren’t so lucky and unless things have changes, Android developers still have to live with anonymous inner class syntax.

That is until Kotlin came along and is now supported for Android. In this portion of the Kotlin Koans tutorial, I had to rewrite this Java code into Kotlin.

public class JavaCode4 extends JavaCode {
    public boolean task4(Collection collection) {
        return Iterables.any(collection, new Predicate() {
            @Override
            public boolean apply(Integer element) {
                return element % 42 == 0;
            }
        });
    }
}

Of course, JDK 8 developers get the Stream API and lambda syntax, while Android developers were out of luck. Here is the equivalent Kotlin code.

fun task4(collection: Collection): Boolean{
    return collection.any { element -> element % 42 == 0 }
}

You can click here to see Part 4

Kotlin Koans—Part 3

The last tutorial’s challange was to take a collection and assemble it into a string using StringBuilder. Java 8 finally gave developers a way to join a String, but Kotlin seems to make it even easier.

This partion of the Kotlin Koans tutorial has us using collection::joinToString. Using Kotlin, we can assemble an entire collection into a String using just one line of code.

fun task2(collection: Collection): String {
    return collection.joinToString(", ", "{", "}")
}

This code is functionally equivalent to what we did in part 2. I also learned a little bit more about the language. Kotlin let’s us have default parameters in our methods. I have to say, while I appreciate Java’s method overloading capabilities, there are times where it’s simplier to use default parameters.

You can click here to see Part 2 or Part 4

Kotlin Koans—Part 2

After doing the first tutorial on Kotlin, I was impressed, but let’s face it, anyone can do a simple “hello world” style program. Nevertheless, I decided to continue with the Kotlin tutorial found at kotlinlang.org. When I moved onto part two of the tutorial, I was really impressed.

It wasn’t that I was super impressed with the language itself. It was IntelliJ’s support of Kotlin that blew me away. When you copy and paste Java code into the IDE, it will offer to translate it to Kotlin for you.

You can see in the video that IntelliJ just did the work of taking the Java code that I copied and pasted into my Kotlin class. I thought this was incredibly slick because it gave me the change to see the differences between Java and Kotlin.

Of course, I wanted to do the exercise myself so that I can get the hang of writing Kotlin code. The problem in this portion of the tutorial was to take this Java code and rewrite as Kotlin code.

public class JavaCode1 extends JavaCode {
    public String task1(Collection collection) {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()) {
            Integer element = iterator.next();
            sb.append(element);
            if (iterator.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("}");
        return sb.toString();
    }
}

It’s not too painful of code. Here is what I ended with when I wrote the code as Kotlin code on my own.

fun todoTask1(collection: Collection): Nothing = TODO(
    """
        Task 1.
        Rewrite JavaCode1.task1 in Kotlin.
        In IntelliJ IDEA, you can just copy-paste the code and agree to automatically convert it to Kotlin,
        but only for this task!
    """,
    references = { JavaCode1().task1(collection) })


fun task1(collection: Collection): String {
    val sb = StringBuilder()
    sb.append("{")
    val iterator = collection.iterator()
    while (iterator.hasNext()){
        val element = iterator.next()
        sb.append(element)
        if (iterator.hasNext()){
            sb.append(", ")
        }
    }
    sb.append("}")
    return sb.toString()
}

There was one thing I noticed about the Kotlin code that I liked. It looks as if we are allowed to have free standing functions in Kotlin outside of a class definition. While I appreciate OOP, there are frankly times where I’m not sure if OOP is the best approach to a problem. This was one of things I really like about Python is that I can break out of OOP when I want.

Now I know that it’s perfectly true that we can use static imports in Java, but I have always felt that was a clumsy approach. Static functions and static imports always seemed more like an after thought to the language that got tacked on after enough people complained. Of course, that’s just a matter of opinion, but anyway, I do like having a choice in Kotlin about when to use classes or just when to use function. Kotlin seems to have included this choice as part of the design of the language right from the get go.

You can click here to see Part 1 and here to see Part 3.