Se afișează postările cu eticheta kotlin. Afișați toate postările
Se afișează postările cu eticheta kotlin. Afișați toate postările

27 octombrie 2022

Kotlin - colecții - ziua 7

Colecții

var people: List<Pers?> = listOf(Pers(23), null)
for (person: Pers? in people) {
println(person?.age)
}

val items = IntArray(2)
items[0] = 1
items[1] = 2

val numbers = intArrayOf(1,2,3,4,5)
numbers.forEachIndexed {index, element ->
println("$index is $element")
}


High order functions

= o funcție care ia ca parametru o altă funcție

val action = { println("Hello World") }
// val calc = {x:Int, y:Int -> x*y}
val calc: (Int, Int) -> Int = {x, y -> x*y}
doSomething(action)

fun doSomething(func: () -> Unit) {
func()
}


Inlining 

- ajută la performanță

val ints = listOf(1,2,3,4)
val i = first(ints, { i -> i == 3})
println(i)


inline fun <T> first(items: List<T>, predicate: (T) -> Boolean): T {
for (item in items) {
if (predicate(item)) return item
}
throw Exception()
}

19 octombrie 2022

Kotlin - NULL handling - ziua 6

Java functional interfaces

Ex. Runnable, Callable 


variabila lambda este refolosita la al doilea apel;

variabila lambda nu mai poate fi refolosita la al doilea apel din cauza lui count;


Constructor SAM - pentru dezambiguizare (când compilatorul nu știe să transforme lambda în interfață funcțională)



Constrângeri de nulabilitate

Evitare NPE prin „cod defensiv” --> mult cod în plus

Kotlin:

- tipuri non-nullable

fun closeMeeting(m: Meeting): Boolean { // m: Meeting, deci nu poate fi null
return if (m.canClose()) m.close()
else false
}

fun main(args: Array<String>) {
closeMeeting(
null) // EROARE de COMPILARE
}


- tipuri nullable:  fun closeMeeting(m: Meeting?): Boolean

- safe calls: obj?.method()  === if (obj != null) obj.method()

- operatorul Elvis: newMeeting = m ?: Meeting()   === newMeeting = (m != null) ? m : new Meeting();

- safe cast:  val saveable = obj as? ISaveable    === saveable = obj instanceof ISaveable ? obj : null;

- not-null assertion:  m!!.close()  === assert (m != null) si arunca NPE daca s-a gasit null

- LET: cheama ce e in paranteze doar daca m != null

  m?.let { closeMeeting(m) }

- lateinit: Kotlin nu te lasă să declari o variabilă fără să fie inițializată. Soluții: inițializare cu o valoare default, cu null (și atunci devine nullable), sau cu lateinit (când știu că nu vreau să fie nullable).

  lateinit var address: Address // promisiune compilatorului că voi inițializa variabila


Interacțiune cu Java (adnotări)

public @Nullable String getTitle() {
  return meetingTitle;
}

public void setTitle(@NotNull String title) {
  this.meetingTitle = title;
}

// Kotlin
var title: String? = meeting.getTitle()


Platform type

Când nu există adnotări, compilatorul Kotlin știe că este doar un tip din Java, nu se știe dacă poate fi null sau nu, apare cu semnul exclamării, ex. String! = String sau String?
- dacă Kotlin implementează o interfață din Java unde există return type de tip platform, atunci return type al metodelor implementate poate fi atât nullable cât și non-nullable

15 octombrie 2022

Kotlin - Objects, High level functions & Filtre (ziua 5)

 object

- introduce un singleton (nu există constructor, instanțe)

- poate extinde un Comparator

- adnotare metodă din interiorul obiectului cu @JvmStatic pentru a putea fi chemată din Java

class Course(val id: Int, val title: String) {
}

object Courses {
var allCourses = arrayListOf<Course>()

init {
allCourses.add(Course(1, "Kotlin"))
allCourses.add(Course(2, "Maven"))
}
}

fun enroll(courseName: String){
val course = Courses.allCourses
.filter{it.title == courseName}
.firstOrNull()
}


Companion objects

- keyword: companion objects => Metodele din interiorul obiectului devin statice (factory methods)

open class Student : Person {
  // ....
  companion object : Internship<Student> {
    override fun applyToInternship(title: Student) {
TODO("Not yet implemented")
}

// adding static methods to the class
fun createUndergrad(name: String) = Undergrad(name)
fun createPostgrad(name: String) = Postgrad(name)
}
}

class Undergrad(name: String) : Student(name)

class Postgrad(name: String) : Student(name)

interface Internship<T> {
fun applyToInternship(title: T)
}


fun main(args: Array<String>) {
  Student.createPostgrad("Naim")
  Student.createUndergrad("Amir")
}


High level functions

program.fibonacci(8) { n -> println(n) }

program.fibonacci(8) { println(it) }

program.fibonacci(8, ::println)


Lambda

- pot schimba valori (in Java trebuie să fie final)

var total = 0

program.fibonacci(8) { it -> total += it }


with (student) {

  // asignari pe campurile obiectului student

  name = "Geo"

  city = "Bucharest"

}


student.apply {

  name = "Geo"

  city = "Bucharest"

}


Filter, map, predicate

val ints = listOf(1,2,3,4,5)
val smallInts = ints.filter { it < 4 }
for(i: Int in smallInts) println(i)

val sqInts = ints.map { it*it }
for(i: Int in sqInts) println(i)

val smallSqInts = ints.filter { it < 3 }.map { it*it }
for(i: Int in smallSqInts) println(i)

val largeInts = ints.all { it > 3 }
println(largeInts) // false: not all are grt than 3

val largeIntsAny = ints.any { it > 3 }
println(largeIntsAny) // true: there is one elem grt than 3

val grtThnThree = { v: Int -> v > 3 }
val largeCount = ints.count(grtThnThree)
println(largeCount) // 2

var found :Int? = ints.find(grtThnThree)
println(found) // 4 is the first elem found grt than 3

found = ints.find { it > 5 }
println(found) // null


Secvențe

- folosite atunci când listele create de filter/map ar fi imense

- folosesc evaluare leneșă

- se preferă secvențele în locul listelor

- în Java8, echivalentul este streams

Exemplu:

val titles = meetings.asSequence().filter { ... }.map { ... }

// for (i: String in titles) println(i)

Diferențe

- cu asSequence si fara println (comentat), nu se evalueaza deloc expresia (lazy)

- cu asSequence si println, ordinea este filtru + map + printare element din meetings, deoarece rezultatul este evaluat la cerere, cand este nevoie de el in println

- fara asSequence se evalueaza expresia indiferent daca rezultatul este sau nu folositor; ordinea este: toate filtrele, apoi toate maparile, apoi toate printarile

- cu asSequence operatiile pot fi mai eficiente, in special daca se cere doar primul rezultat (ca exemplu cu find = terminal operator)

06 octombrie 2022

KOTLIN - Clase (ziua 4)

 Interfețe

- public by default

- nu există implements / extends

interface Time {
fun setTime(hrs: Int, mins: Int = 0, secs: Int = 0)
fun setTime(time: String) = setTime(0) // default implementation
}

interface NoTime {
fun setTime(time: String) {}
}

class MyTime : Time, NoTime {
override fun setTime(hrs: Int, mins: Int, secs: Int) {}

override fun setTime(time: String) {
super<Time>.setTime(time)
super<NoTime>.setTime(time)

}
}


Clase

- public, final by default (și metodele sunt final by default)

- dacă vrei să nu fie final - se specifică open

In Java era o practică bună să adaugi final claselor care nu trebuiesc extinse

- suport pt abstract

- clase sigilate (sealed)

- internal: clase vizibile doar în modulul respectiv 

- protected, private; dar nu există package private

open abstract class Person () {
var firstName: String = ""
var lastName: String = ""

open fun getName(): String = "$firstName $lastName" // can be overriden

abstract fun getWork() // can be implemented

fun getVacations() {} // cannot be overriden
}

class Student : Person() {
override fun getName(): String{return ""}
override fun getWork() {
TODO("Not yet implemented")
}
}


Clase sigilate

- ierarhizare, asemănare cu enum

sealed class PersonEvent {
// nested subclasses
class Awake: PersonEvent()
class Asleep: PersonEvent()
class Eating(val food: String): PersonEvent()
}

fun handlePersonEvent(event: PersonEvent) =
when(event) {
is PersonEvent.Awake -> println("Awake")
is PersonEvent.Asleep -> println("Asleep")
is PersonEvent.Eating -> println("Eating ${event.food}")
}


Constructori

open class Person (_fname: String, _lname: String) {
var firstName: String = ""
var lastName: String = ""

init {
this.firstName = _fname
this.lastName = _lname
}

constructor(name: String) : this(name, "")
}


class Student : Person {
var age: Int;
init {
age = 0;
}

constructor(name: String) : super(name)

constructor(first: String, last: String) : super(first, last)

constructor(first: String, last: String, age: Int) : super(first, last) {
this.age = age;
}
}


Data classes

- furnizează metodele toString, equals, hashCode + metoda copy pentru clonare

- sunt clase imutabile

- introdusă prin keywork data class

fun main(args: Array<String>) {
var st1 = Steward(1, "Lina")
var st2 = Steward(1, "Lina")
var st3 = st2.copy(name = "Roberta")
// toate câmpurile la fel mai puțin name

println("Equal? ".plus(st1 == st2)) // true numai dacă există keyword data peste Steward
println(st3) // apelează toString, rezultat citibil față de un Steward@5e2de80c, dacă nu era data
}

data class Steward(val id: Int, val name: String)

30 septembrie 2022

KOTLIN - Funcții (ziua 3)

 Functii

- pot fi standalone (in afara unei clase)

- introduse prin fun

- pot avea parametri by default

- pot extinde tipuri deja existente

- pot fi chemate din Java (import pachetul de kotlin si chemare ca functie statica)

  @file:JvmName("DisplayFunctions") // redenumire oficiala a clasei in Kotlin, pt a putea chema din Java:

  DisplayFunctions.display("ce vrei tu");


fun max(a: Int, b: Int) : Int = if (a > b) a else b // function expression
println(max(1,2))


Parametri default

@JvmOverloads // ca sa poata fi chemata din Java cu sau fara parametrul optional
// Java va crea o metoda cu un singur parametru & una cu 2 parametri
fun log(message: String, logLevel: Int = 1) {
println("$message | $logLevel")
}
log("Salut")


Denumirea parametrilor  (Java nu suporta)

- pentru a ii putea da in orice ordine si ajuta la dezambiguizare atunci cand exista mai multi parametri optionali

log(logLevel = 2, message = "Salut")


Functii care extind

Idee: adăugare funcții la clase existente -> devin funcții statice; util pentru funcții utilitare de moment.

println("Salux Pexri".replaceX())
fun String.replaceX(): String { // extinde in clasa String
return this.replace("x", "t")
}


Funcții INFIX

- prefixate cu infix, au un singur parametru

class Header(var name: String) {}

infix fun Header.plus(other: Header): Header {
return Header(this.name + " " + other.name)
}
var h1 = Header("Petri")
var h2 = Header("Mimi")
val h3 = h1 plus h2

println(h3.name) // Petri Mimi


Operator overloading

operator infix fun Header.plus(other: Header): Header {
return Header(this.name + " " + other.name)
}
val h4 = h1 + h2


Funcții foarte recursive

tailrec - cuvânt-cheie pus înainte de fun atunci când știm că vor avea loc prea multe apeluri recursive, iar Kotlin le va transforma intern într-o buclă; pentru evitarea stack overflow

29 septembrie 2022

KOTLIN - ziua 2

Fisier kt -> .class file

Rulare:

> java -cp ...\kotlin-runtime.jar MainKt 

Alta optiune: export jar

> java -jar MainKt.jar


Mai putina "ceremonie":

- poti defini clase oriunde, nu trebuie sa fie in fisier separat


STRINGS

- string interpolation: 

  println("Display $name")

  println("Display $(obj.name)")

- string comparison: if (str1 == str2)

- nullable vs non-nullable

  var answer: String// non-nullable

  var answer: String?// nullable

- string comparison with null check: if (str1?.prop == str2?.prop) // compara doar daca nu sunt nule


IF este o expresie care returneaza o valoare:

var message = if (str1 == str2) { "egal" } else { "gresit" } 


WHEN - asemanator cu switch

 when (str1) {

  "25" -> print("Corect")

  else -> print("Gresit")

}


TRY - CATCH

val num: Int = try {
Integer.parseInt("20s")
} catch (e: NumberFormatException) {
-1
}
finally {
}


Iteratii - WHILE, FOR

var range = 1..10 // inclusive
// poate fi si range = 'a'..'z' --- orice care implementeaza interfata Comparable

for (i in range step 3) {
println(i)
}
for (i in 10 downTo 1 step 4) {
println(i)
}
for (i in 1 until 10) { // non-inclusive
println(i)
}


LISTE

var nums = listOf(11,22,33)
for (i in nums) {
println(i)
}
for ((index, element) in nums.withIndex()) {
println("$element at index $index")
}


MAPS

var ages = TreeMap<String, Int>()
ages["Geo"] = 33
ages["Petri"] = 7
for ((name, age) in ages) {
println("$name's age is $age")
}

22 septembrie 2022

KOTLIN - ziua 1

KOTLIN este un limbaj OOP simplificat (cu mai puține linii de cod), care acomodează mai bine decât Java paradigma funcțională (fiind chiar limbaj funcțional) și care rulează pe JVM. Considerat o îmbunătățire a Javei.

> kotlinc hello.kt

Creează un fișier .class

> kotlinc hello.kt -include-runtime -d hello.jar

> java -jar hello.jar

Creează un jar și rulează java


var (înaintea declarării unei variabile) vs val (declară variabila immutable)

public este implicit în Kotlin

void este Unit


fun main (args: Array<String>) {
println("Hello world")

val geo = Person("Georgiana")

geo.display1()
geo.display2(::displayHelper)
}

fun displayHelper(name: String) {
println("Bravo $name")
}

class Person (var name: String) {
fun display1() {
println("Display $name")
}

fun display2 (func: (s:String) -> Unit) {
func(
name)
}
}