Created
June 21, 2017 13:57
-
-
Save marsicdev/2a43331d770053db9b0eebb47da83b5f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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