Kotlin is made by JetBrains (the same as that did IntelliJ the IDE).

See their website here:

Check out some real examples at Sylhare/Kotlin!

Project Structure

Assuming you know how to work with Gradle. You need to create the gradle file build.gradle.kts then add dependencies and configurations. An example with Kotlin dsl with gradle 4.8. But you might want to take the latest Gradle version available, you’ll have up to date and better information.

For gradle to pick up the source and test files, you will need to organise your folders like:

└── src
    ├── main
    │   └── kotlin
    │       └── package
    └── test
        └── kotlin
            └── package

Kotlin Specifics

Miscellaneous

  • Use ` (back tick) to define method’s name with space:
@Test
fun `valid parameters` { ... }
  • Overload Objects to generates new ones easily:
val Number.teaspoons get() = Quantity(this, Unit.teaspoon)

So then you can use it this way:

Quantity(1.5, Unit.teasponn) 
1.5.teaspoons
  • Before a recursion, ask yourself these questions:
    • What is the original question?
    • What is the recursive question?
    • What are the Terminal condition? (when the recursive stops)

Handling null

  • The ? is used in Kotlin to handle null:
// The Rectangle? makes the function returns Rectangle or null
fun mayReturnRectangleOrNull() : Rectangle? { ... }

// With "?." the .rectangleMethod() will only occur when mayReturnRectangleOrNull() returns a rectangle
mayReturnRectangleOrNull()?.rectangleMethod() 

// Elvis ?: to have another value if the preceeding one return null
val somethingNotNull = emptyRectangle()
return mayReturnRectangleOrNull() ?: somethingNotNull 
  • The !! to force the function to operate even though it can be null:
return if (list.isEmpty) -1 else list.min()!! //list can be null, without !! it would complain, but can still return null
  • Using the this@Class inside of a list.apply { this.prepend(this@Class) }, you are calling the this of the class (so this@Class to differentiate from the other this (element of the list that you apply to).

Keywords

  • Any for any type
  • init {} to initiate the values at the creation of the class
  • override at the beginning of the function to override it:
override fun equals(other: Any?) { ... }
  • operator to override an operator function. Here an example with the comparison operator (>, <, …)
operator fun compareTo(other: Probability) { ... }
  • infix function are function where you can omit the .:
infix fun isCompatibleWith(other: Unit): Boolean { ... }

// calling the function using the infix notation
unit isCompatibleWith otherUnit

// is the same as
unit.isCompatibleWith(otherUnit)
  • typealias is used to define a name for a function signature (hence alias) usually used to simplify simple functions into a type:
internal typealias CostStrategy = (Double) -> Double
  • For Properties unless they are private, a getter / setter is automatically “build” but you can custom its behaviour through:
// To custom the Getter / Setter of a field
private var field: String = "field" 
var proxyField: String
    get() = field
    set(value) { field = value }

// Public Getter and private Setter   
var abc: String = ""; private set

Operation on lists

  • flatMap transforms a list of list of stuff into a simple list of stuff
list.flatMap { List<List<Path>> } // returns List<Path>
  • onEach is the same as list.map{ this.apply { ... } }

  • sumByDouble is the same as list.map{}.sum{}