Skip to content

Instantly share code, notes, and snippets.

@marsicdev
Created June 21, 2017 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marsicdev/2a43331d770053db9b0eebb47da83b5f to your computer and use it in GitHub Desktop.
Save marsicdev/2a43331d770053db9b0eebb47da83b5f to your computer and use it in GitHub Desktop.
import java.util.*
fun main(args: Array<String>) {
println("Say hello to Kotlin".withUnderscore())
// ----- VARIABLES -----
// Kotlin uses type inference
// Create a read only variable
val name = "Marko"
// Mutable (changeable) variable
var myAge = 28
// Kotlin uses type inference, but you can define the type
val bigInt: Int = Int.MAX_VALUE
val smallInt: Int = Int.MIN_VALUE
println("Biggest Int : " + bigInt)
println("Smallest Int : " + smallInt)
val bigLong: Long = Long.MAX_VALUE
val smallLong: Long = Long.MIN_VALUE
println("Biggest Long : " + bigLong)
println("Smallest Long : " + smallLong)
val bigDouble: Double = Double.MAX_VALUE
val smallDouble: Double = Double.MIN_VALUE
println("Biggest Double : " + bigDouble)
println("Smallest Double : " + smallDouble)
val bigFloat: Float = Float.MAX_VALUE
val smallFloat: Float = Float.MIN_VALUE
println("Biggest Float : " + bigFloat)
println("Smallest Float : " + smallFloat)
// Doubles are normally precise to 15 digits
val dblNum1: Double = 1.11111111111111111
val dblNum2: Double = 1.11111111111111111
println("Sum : " + (dblNum1 + dblNum2))
// Booleans are either true or false
if (true is Boolean) {
print("true is boolean\n")
}
// Characters are single quoted characters
val letterGrade: Char = 'A'
println("A is a Char : " + (letterGrade is Char))
// ----- CASTING -----
// You can cast from one type to another using
// toShort, toInt, toLong, toFloat, toDouble, toChar,
// toString
println("3.14 to Int : " + (3.14.toFloat()))
println("A to Int : " + (letterGrade.toInt()))
println("65 to Char : " + (65.toChar()))
// ----- STRINGS -----
// Strings are double quoted series of characters
val myName = "John Doe"
val longStr = """This is a
multiline long
long string """
println("Long String : " + longStr)
var firstName = "John"
var lastName = "Smith"
// You can change values
firstName = "Jon"
lastName = "Some name"
// You can combine strings
val fullName = firstName + " " + lastName
println("Name : $fullName")
// You can use string interpolation
val fullName1 = "$firstName $lastName"
val fullNameLength = "Length : ${firstName.trim().length + lastName.trim().length}"
println("Name : $fullName1, $fullNameLength")
// You can perform other operations with {}
println("1 + 2 = ${1 + 2}")
// Get length
println("String length : ${longStr.length}")
println("String is empty : ${longStr.isEmpty()}")
val str1 = "A random string"
val str2 = "a random string"
// Compare strings
println("Strings Equal : ${str1 == str2}")
println("Strings Equal ignore case : ${str1.equals(str2, true)}")
// Get character at an index
println("2nd Index : ${str1.get(2)}")
println("2nd Index : ${str1[2]}")
// Get a substring from start up to but not including end
println("Index 2-7 : ${str1.subSequence(2, 8)}")
// Checks if a string contains another
println("Contains random : ${str1.contains("random")}")
// ----- ARRAYS -----
// You can store multiple types in arrays
val myArray = arrayOf(1, 1.23, "Dog")
// You can access values using indexes starting at 0
println(myArray[2])
// Change the value
myArray[1] = 3.14
println(myArray[1])
// Elements in array
println("Array Length : ${myArray.size}")
// Is element in the array
println("Dog in Array : ${myArray.contains("Dog")}")
// Get first 2 elements in array as an array
val partArray = myArray.copyOfRange(0, 1)
println("First : ${partArray[0]}")
// Get the first element
println("First : ${myArray.first()}")
// Get index of value
println("Dog Index : ${myArray.indexOf("Dog")}")
// There are type specific arrays
val arr2: Array<Int> = arrayOf(1, 2, 3)
println(arr2[2])
// ----- LISTS -----
// There are immutable Lists and mutable MutableLists
// Create a mutable list
var list1: MutableList<Int> = mutableListOf(1, 2, 3, 4, 5)
// Create an immutable list
val list2: List<Int> = listOf(1, 2, 3)
// Add an item
list1.add(6)
// Get first item
println("1st : ${list1.first()}")
// Get last
println("Last : ${list1.last()}")
// Get value at index
println("2nd : ${list1[2]}")
// Get a list starting from index to another
var list3 = list1.subList(0, 3)
// Size of List
println("Length : ${list1.size}")
// Clear a Mutable list
// list3.clear()
// Remove a value
list1.remove(1)
// Remove at index
list1.removeAt(1)
// Add value at index
list1[2] = 10
list1.forEach { n -> println("Mutable List : $n") }
// ----- RANGES -----
// You define ranges by providing a starting and ending
// value
val oneTo10 = 1..10
val alphabet = "A".."Z"
// Use in to search a Range
println("R in alpha : ${"R" in alphabet}")
// Create ranges that decrement
val tenTo1 = 10.downTo(1)
print("Range decrement : $tenTo1")
// Create array up to a value
val twoTo20 = 2.rangeTo(20)
print("Range up : $twoTo20")
// Step through an array while adding 3
val rng3 = oneTo10.step(3)
// Cycle through a range and print
for (x in rng3) println("rng3 : $x")
// Reverse a range
tenTo1.reversed().forEach {
val element = it
println("Reverse : $element")
}
// ----- CONDITIONALS -----
// Conditional Operators : >, <, >=, <=, ==, !=
// Logical Operators : &&, ||, !
val age = 8
if (age < 5) {
println("Go to Preschool")
} else if (age == 5) {
println("Go to Kindergarten")
} else if ((age > 5) && (age <= 17)) {
val grade = age - 5
println("Go to Grade $grade")
} else {
println("Go to College")
}
// When works like Switch in other languages
when (age) {
// Match a list
0, 1, 2, 3, 4 -> println("Go to Preschool")
// Match a specific value
5 -> println("Go to Kindergarten")
// Match a range
in 6..17 -> {
val grade = age - 5
println("Go to Grade $grade")
}
// Default
else -> println("Go to College")
}
// ----- LOOPING -----
// You can use for loops to cycle through arrays
// ranges, or anything else that implements the
// iterator function
for (x in 1..10) {
println("Loop : $x")
}
// Generate a random number from 1 to 50
val rand = Random()
val magicNum = rand.nextInt(50) + 1
// While loops while a condition is true
var guess = 0
while (magicNum != guess) {
guess += 1
}
println("Magic num is $magicNum and you guessed $guess")
var arr3: Array<Int> = arrayOf(3, 6, 9)
// Iterate for indexes
for (i in arr3.indices) {
println("Mult 3 : ${arr3[i]}")
}
// Output indexes
for ((index, value) in arr3.withIndex()) {
println("Index : $index & Value : $value")
}
// ----- NULL SAFETY -----
// Null safety is built into Kotlin
// By default you cannot assign null
// var nullVal: String = null
// To allow for a null value use ?
val nullVal: String? = null
nullVal?.length
// nullVal ?: throw IllegalArgumentException()
// nullVal.length
// A function that may return null uses ?
// fun myFun(): String?
// Kotlin provides for the opportunity of a
// null value if an if statement protects
// from danger
fun returnNull(): String? {
return null
}
val nullVal2 = returnNull()
// This is a smart cast
if (nullVal2 != null) {
println(nullVal2.length)
}
// We could use the force operator !! to force
// a null assignment
var nullVal3 = nullVal2!!.length
// The Elvis operator assigns a default value
// if null
var nullVal4: String = returnNull() ?: "No Name"
// ----- FUNCTIONS -----
// Functions start with fun, function name,
// parameters and return type
fun multiply(x: Int = 0, y: Int = 0) = x * y
multiply(y = 3, x = 1)
fun add(num1: Int, num2: Int): Int = num1 + num2
println("5 + 4 = ${add(5, 4)}")
// You don't need a return type with single line functions
// You can define default values for parameters
fun subtract(num1: Int = 1, num2: Int = 1) = num1 - num2
println("5 - 4 = ${subtract(5, 4)}")
// You can use named parameters
println("4 - 5 = ${subtract(num2 = 5, num1 = 4)}")
// You can use only one param since num1 has default value
println("4 - 5 = ${subtract(num2 = 1)}")
// Use unit if you return nothing
fun sayHello(name: String): Unit = println("Hello $name")
sayHello("World")
// Functions can return 2 values with Pair and 3 with Triple
val (two, three) = nextTwo(1)
val (first, second, third) = nextThree(5)
println("1 $two $three")
println("$first $second $third")
// Send a variable number of parameters
println("Sum : ${getSum(1, 2, 3, 4, 5)}")
// We can define function literals
val multiply = { num1: Int, num2: Int -> num1 * num2 }
println("5 * 3 = ${multiply(5, 3)}")
// ----- HIGHER ORDER FUNCTIONS -----
// Higher order functions either accepts or returns
// another function
// Use filter to find evens
val numList = 1..20
// If a function has only 1 parameter you don't
// have to declare, but just use it instead
val evenList = numList.filter { it % 2 == 0 }
evenList.forEach { num -> println(num) }
// Call a function that returns dynamically
// created functions
val mult3 = makeMathFunc(3)
println("5 * 3 = ${mult3(5)}")
// A function that receives a list and a function
val multiply2 = { num1: Int -> num1 * 2 }
val numList2 = arrayOf(1, 2, 3, 4, 5)
mathOnList(numList2, multiply2)
fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
val items = ArrayList<T>()
this.filterTo(items) { predicate(it) }
return items
}
val cars = listOf("BMW", "Fiat", "Mercedes", "KIA", "Ford")
val filteredCars = cars.filter { it.startsWith("F") }
// ----- COLLECTION OPERATORS -----
// Use reduce to sum values in a list
val listSum = numList2.reduce { x, y -> x + y }
println("Reduce Sum : $listSum")
// Fold is like Reduce, but it starts with an initial value
val listSum2 = numList2.fold(5) { x, y -> x + y }
println("Fold Sum : $listSum2")
// Check if any values are even
println("Evens : ${numList2.any { it % 2 == 0 }}")
// Check if all values are even
println("Evens : ${numList2.all { it % 2 == 0 }}")
// Return a list of values greater then 3
val big3 = numList2.filter { it > 3 }
big3.forEach { n -> println(">3 : $n") }
// Use Map to perform an action on every item
// and return a new list
val times7 = numList2.map { it * 7 }
times7.forEach { n -> println("*7 : $n") }
// ----- EXCEPTION HANDLING -----
// Exceptions are handled just like with Java
val divisor = 2
try {
if (divisor == 0) {
throw IllegalArgumentException("Can't Divide by Zero")
} else {
println("5 / $divisor = ${5 / divisor}")
}
} catch (e: IllegalArgumentException) {
println("${e.message}")
}
// ----- MAPS -----
// A modifiable collection that holds key value pairs
// Create a Map
val map = mutableMapOf<Int, Any?>()
val map1 = mapOf<Int, Any?>()
// Create a Map and add values
val map2 = mutableMapOf(1 to "Doug", 2 to 25, Pair(4, true))
// Add values
map[1] = "Marko"
map2[2] = 42
// Get Size
println("Map Size : ${map.size}")
// Add a key value
map.put(3, "Belgrade")
// Remove a key and value
map.remove(2)
// Iterate and get keys and values
for ((key, value) in map) {
println("Key : $key Value : $value")
}
// ----- CLASSES -----
// Create an Animal object
val dog = Animal("Dog", 20.0, 13.5)
// Call method in the class
dog.getInfo()
// ----- INHERITANCE -----
// Create a class Dog that inherits from
// the Animal class
// val myDog = Dog("Doggy", 20.0, 14.5, "Paul Smith")
val myDog = Dog(name = "Doggy", owner = "John Smith", height = 20.toDouble(), weight = 8.toDouble())
myDog.getInfo()
// ----- INTERFACES -----
// Create a Bird object that implements the
// Flyable interface
val tweety = Bird("Tweety", true)
tweety.fly(10.0)
}
// ----- FUNCTIONS -----
// Returns 2 values
fun nextTwo(num: Int): Pair<Int, Int> {
return Pair(num + 1, num + 2)
}
fun nextThree(num: Int): Triple<Int, Int, Int> {
return Triple(num + 1, num + 2, num + 3)
}
// Receive variable number of parameters
fun getSum(vararg nums: Int): Int {
var sum = 0
// For each value in the array add it to sum
nums.forEach { n -> sum += n }
return sum
}
// Returns a custom function that multiplies values
// times the value passed to it
fun makeMathFunc(num1: Int): (Int) -> Int = { num2 -> num1 * num2 }
// Receives a list and a function to use on the list
fun mathOnList(numList: Array<Int>, myFunc: (num: Int) -> Int) {
for (num in numList) {
println("MathOnList : ${myFunc(num)}")
}
}
fun String.withUnderscore(): String {
return this.replace(" ", "_")
}
// ----- CLASSES -----
// There are no static methods
// Classes are final by default unless marked open
// The fields must also be marked as open
open class Animal(val name: String, var height: Double, var weight: Double) {
// Objects are initialized in init
init {
// Regex that matches for a number any place
// in a string
val regex = Regex(".*\\d+.*")
// If these requirements aren't met an
// IllegalArgumentException is thrown
require(!name.matches(regex)) { "Animal name can't Contain Numbers" }
require(height > 0) { "Height must be greater then 0" }
require(weight > 0) { "Weight must be greater then 0" }
}
// If you want to allow overriding of this method
// you must use open
open fun getInfo(): Unit {
println("$name is $height tall and weighs $weight")
}
}
// ----- INHERITANCE -----
class Dog(name: String,
height: Double,
weight: Double,
var owner: String) : Animal(name, height, weight) {
// Overriding Animal method
override fun getInfo(): Unit {
println("$name is $height tall, weighs $weight and is owned by $owner")
}
}
// ----- SEALED CLASS -----
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
// The key benefit of using sealed classes comes into play when you use them in a when expression.
// If it's possible to verify that the statement covers all cases,
// you don't need to add an else clause to the statement.
fun eval(expr: Expr): Double = when (expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}
// ----- INTERFACES -----
// An interface is a contract that states all fields
// and methods a class must implement
interface Flyable {
var flies: Boolean
fun fly(distMiles: Double): Unit
}
// We override flies in the constructor
// To implement the interface we follow the
// constructor parameters with a colon and the
// interface name
class Bird constructor(val name: String, override var flies: Boolean = true) : Flyable {
// We must also override any methods in the interface
override fun fly(distMiles: Double): Unit {
if (flies) {
println("$name flies $distMiles miles")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment