Pedro Joya
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- title: Kotlin sacándole los colores a Java tags: Kotlin, Java description: Presentación sobre Kotlin en comparación con Java slideOptions: theme: beige transition: 'slide' mouseWheel: true touch: true controlsLayout: 'edges' hideAddressBar: true keyboard: true overview: false --- # Kotlin ## Sacándole los colores a Java Pedro Joya Máñez ![](https://i.imgur.com/Vc5xLpv.png) https://hackmd.io/@pedrojoya/kotlin#/ --- ### Acerca de mí #### Pedro Joya :man: - Docente de Ciclos Formativos de Formación Profesional de Informática en el IES Saladillo de Algeciras - Profesor de desarrollo de aplicaciones en Android - Apasionado de Kotlin twitter: [@pedrojoyamanez](https://twitter.com/pedrojoyamanez) --- ### ¿Qué es Kotlin? - Lenguaje de programación creado por JetBrains - Inspirado en otros lenguajes: Java, C#, Scala, Groovy, Ruby - Podemos usarlo para desarrollo mobile, web front-end y back-end (Spring, Android, web, nativo) --- ### ¿Por qué Kotlin? - Sintaxis simple y concisa - Curva de aprendizaje suave - Interoperable con Java. Compila hacia JVM bytecode - Lenguaje moderno, conciso y con características de lenguajes funcionales - Google lo ha elegido como lenguaje prioritario para programación en Android --- ![](https://i.imgur.com/Alm8ETd.jpg) --- ### Show me the code ![](https://media.giphy.com/media/AOSwwqVjNZlDO/giphy.gif) --- ### El ; es opcional ```java= // JAVA String name = "Baldomero"; ``` ```kotlin= // KOTLIN val name: String = "Baldomero" ``` * En Kotlin el ; es opcional, excepto en un caso específico de los enums :scream: :clap: :dancer: --- ### val vs. var ```java= // JAVA final String name = "Baldomero"; int age = 45; ``` ```kotlin= // KOTLIN val name: String = "Baldomero" var age: Int = 45 ``` - val define una variable que no puede referenciar ningún otro objeto en el futuro. - var define una varible que puede referenciar distintos objetos a lo largo de su vida --- ### Inferencia de tipos ```java= // JAVA <10 final String name = "Baldomero"; // JAVA 10 var name = "Baldomero"; ``` ```kotlin= // KOTLIN var name = "Baldomero" ``` - Tipo inferido (deducido) a partir del tipo de la expresión de inicialización - Lenguaje fuertemente tipado de tipo estático, aunque haya sido inferido (tiempo de compilación) --- ### Tipos referenciales, no primitivos ```kotlin= // KOTLIN val value: Int = 146 val percent = value.coerceIn(0, 100) ``` - No exiten los tipos primitivos, todos son clases. - Internamente se usará un tipo primitivo cuando sea posible, con boxing y unboxing automático - No hay conversión automática de tipos numéricos, sino funciones de conversión explícita en los tipos, como toLong(), toInt(), etc. --- ### Template Strings (interpolación) ```java= // JAVA final String s = "abc"; System.out.println(s + ".length is " + s.length()); ``` ```kotlin= // KOTLIN val s = "abc" println("$s.length is ${s.length}") ``` - $variable para interpolar el valor de una variable - ${expresion} para interpolar el valor de cualquier expresión --- ### Raw Strings ```java= // JAVA final String artist = "Chiquito de la Calzada"; final String saying = "No te digo trigo...\n" + "por no llamarte Rodrigo\n" + "(" + artist + ")"; ``` ```kotlin= // KOTLIN val artist = "Chiquito de la Calzada" val saying = """ |No te digo trigo |por no llamarte Rodrigo |($artist) """.trimMargin() ``` - Literal de cadena sin caracteres de escape (\n, \t, ...) - Puede contener interpolación. - Se propuso para Java 12, pero fue pospuesto. --- ### if else es una expresión ```kotlin= // KOTLIN val max = if (a > b) { print("a es el máximo") a } else { print("b es el máximo") b } ``` - Las estructura if else es una expresión, que se evalúa al valor al que se evalúa la rama ejecutada - Una rama se evalúa al valor al que se evalúa la última expresión de la rama --- ### No hay operador ternario ```java= // JAVA final int max = a > b ? a : b; ``` ```kotlin= // KOTLIN val max = if (a > b) a else b ``` - En este caso Kotlin puede resultar más verboso que Java :confused: --- ### Estructura for ```java= // JAVA for (int i = 1; i <= 10; i++) System.out.println(i); ``` ```kotlin= // KOTLIN for (i in 1..10) println(i) ``` - Kotlin no posee la estructura for tradicional de Java - Sólo for sobre iterador (for each) - Podemos usar un literal de rango de valores para iterar sobre él --- ### Range ```java= // JAVA for (int i = 1; i < 10; i++) System.out.println(i); for (int i = 6; i >= 0; i-=2) System.out.println(i); ``` ```kotlin= // KOTLIN for (i in 1 until 10) println(i) for (i in 6 downTo 0 step 2) println(i) ``` - La clase Range modela un rango de datos y posee un iterador - Podemos usar los métodos until, downTo y step para crear el rango adecuado --- ### when como switch mejorado ```kotlin= when (input) { 1 -> println("Uno") 7, 8 -> println("Siete u ocho") in 10..19 -> println("Decena") is String -> println("Cadena de ${input.length}") else -> { println("Otra cosa") println("Lo sentimos") } } ``` - No necesita break - Más de un valor de comparación en cada rama - Comprobación de pertenencia o no a un rango, array o lista - Comprobación de pertenencia o no a un tipo --- ### when es una expresión ```kotlin= val semester = when (month) { in 1..6 -> "Primer semestre" in 7..12 -> "segundo semestre" else -> "Mes no válido" } ``` - Devuelve el valor al que se evalúa la rama seleccionada, que corresponde al valor al que se evalúa su última expresión - Debe ser exhaustivo (abarcar todas las posibilidades) - Java 12 incorpora una versión preliminar de switch mejorado con funcionalidad similar --- ### when como if else if ```java= // JAVA if (x.isOdd()) System.out.println("x es impar"); else if (x.isEven()) System.out.println("x es par"); else System.out.println("x está indecisa"); ``` ```kotlin= // KOTLIN when { x.isOdd() -> println("x is impar") x.isEven() -> println("x is par") else -> println("x está indecisa") } ``` - Las ramas se consideran expresiones booleanas y se ejecutará la primera que sea verdadera - También puede usarse como expresión --- ### Hydration break ![](https://media.giphy.com/media/dlbcP3ngz7c6j1kOW2/giphy.gif) --- ### Definición de funciones ```java= // JAVA String greet(String name, String message) { return message + ", " + name; } ``` ```kotlin= // KOTLIN fun greet(name: String, message: String): String { return "$message, $name" } ``` * fun is :smile: * El tipo de retorno se coloca al final, pero puede ser inferido --- ### Funciones que no retornan "nada" ```java= // JAVA void greet(String name, String message) { System.out.println(message + ", " + name); } ``` ```kotlin= // KOTLIN fun greet(name: String, message: String) { println("$message, $name") } ``` - El tipo de retorno es Unit, pero podemos omitirlo - Unit es un tipo, no una palabra reserva como void - La función retorna en realidad el objeto Unit (singleton) --- ### Funciones con una única expresión ```java= // JAVA String greet(String name, String message) { return message + ", " + name; } ``` ```kotlin= // KOTLIN fun greet(name: String, message: String) = "$message, $name" ``` - El tipo de retorno es inferido a partir del tipo de la expresión, aunque puede ser especificado explícitamente --- ### Argumentos con valores por defecto ```java= // JAVA String greet(String name) { return greet(name, "Hola"); } String greet(String name, String message) { return message + ", " + name; } ``` ```kotlin= // KOTLIN fun greet(name: String, message: String = "Hola") = "$message, $name" ``` - Permiten mejorar una API existente fácilmente - El valor por defecto de un parámetro puede usar el valor de un argumento anterior - En Java se simulan mediante sobrecarga de métodos --- ### Named arguments ```kotlin= // KOTLIN fun greet(name: String = "Baldomero", message: String = "Hola") = "$message, $name" println(greet(message="Quillo que")) println(greet(message="Quillo que", name="Germán Ginés")) println(greet("Germán Ginés", message="Quillo que")) ``` * Permite especificar sólo algunos argumentos * Permite cambiar el orden de los argumentos * Puede usarse en conjunción con el paso de argumentos posicional, empezando por éste * Esta funcionalidad NO existe en Java --- ### varargs y spread operator ```kotlin= // KOTLIN fun printStrings(vararg strings: String) { for (string in strings) println(string) } val names = arrayOf("Baldomero", "Germán Ginés") printStrings("Quillo que", *names, "Na aquí") ``` - El operador * (operador de dispersión) delante de un array retorna la lista de valores del array separados por coma , --- ### Top level functions and properties ```kotlin= // KOTLIN // Directamente en un fichero, fuera de cualquier clase const val PI = 3.14 var isUserLoggedIn: Boolean = false fun greet(name: String) { println("Hola $name") } fun main() { greet("Baldomero") isUserLoggedIn = true println("El número PI vale $PI") } ``` - Funciones fuera de cualquier clase. Ejemplo: main - Propiedades fuera de cualquier clase. - const para constantes conocidas en tiempo de compilación, que el compilador usará de modo inline --- ### Extension functions ```java= // JAVA public static String shout(String receiver) { return "¡" + receiver.toUpperCase() + "!"; } String greet = "Quillo que"; System.out.println(StringsUtils.shout(greet)); ``` ```kotlin= // KOTLIN fun String.shout(): String = "¡${this.toUpperCase()}!" val greet = "Quillo que" println(greet.shout()) ``` - Llamada como si fuera un miembro de una determinada clase. - El IDE sugiere la función al escribir un . tras una variable de dicho tipo :dancer: - Dentro de la función, this corresponde al receptor --- ### Lambdas ```kotlin= // KOTLIN fun operateAndPrint(x: Int = 0, action: (Int) -> Int): Int { val result = action(x) // action.invoke(x) println("Result: $result") return result } val increm3 = { x: Int -> x + 3 } operateAndPrint(2, increm3) ``` - Tipos función (vs. interf. func. de Java) - Expresión lambda = literal de objeto función, almacenable y pasable como argumento - Una lamba se ejecuta mediante el operador () o llamando a su método invoke() - La expresión lambda se evalúa al valor al que se evalúe la última expresión de su cuerpo --- ### Lambdas como argumento ```kotlin= // KOTLIN fun operateAndPrint(x: Int = 0, action: (Int) -> Int): Int { val result = action(x) println("Result: $result") return result } operateAndPrint(2, { x -> x + 3}) operateAndPrint(2) { x -> x + 3} operateAndPrint { x -> x + 3 } operateAndPrint { it + 3 } ``` - Inferencia de tipos en los parámetros de la lambda - Si lambda es último argumento, sacar de los () - Si lambda es único argumento, nos ahorramos los () - Si lambda tiene un solo argumento, usar it en cuerpo --- ### Smart cast ```java= // JAVA if (obj instanceof String) System.out.println(((String) obj).length()); ``` ```kotlin= // KOTLIN if (obj is String) println(obj.length) ``` - El compilador hace el cast internamente dentro de la rama :bulb: - Sólo puede aplicarse si la variable no puede cambiar entre la comprobación y el acceso - También en ramas de la estructura when y en comprobación de no null --- ### Tipos nullable y no nullables ```kotlin= // KOTLIN var name: String? = "Baldomero" var sirname: String = "Llegate Ligero" name = null if (name != null) println(name.length) ``` - Nulabilidad dentro del sistema de tipos. - Detección de errores relacionados con null en tiempo de compilación :clap: - Tipo? permite null, Tipo no permite null. Tipo es un subtipo de Tipo? - Smart cast de Tipo? a Tipo tras comprobación de que la variable no es null --- ### Jerarquía de tipos ![](https://i.imgur.com/K4HzWGD.png) - Any es similar a Object - Cada tipo no nullable es subtipo del correspondiente nullable - Nothing es subtipo de todos los tipos --- ### Nothing y throw como expresión ```kotlin= // KOTLIN fun fail(message: String): Nothing { throw IllegalStateException(message) } val fruitPerGlass: Int = if (glassesSold > 0) orangesUsed / glassesSold else throw NoGlassesSold() ``` - El tipo Nothing indica que la función nunca terminará satisfactoriamente y por tanto no retornará - Es subtipo de todos los tipos - throw es una expresión que retorna Nothing --- ### Operador de acceso seguro ```java= // JAVA final Integer length = nickname != null ? nickname.length() : null; final String name = nickname != null ? nickname.toUpperCase() : null; ``` ```kotlin= // KOTLIN val length: Int? = nickname?.length val name = nickname?.toUpperCase() ``` - No se permite usar el operador . con variables de tipo nullable (acceso seguro) - Se debe usar ?. en vez de . para acceder a propiedades y métodos - Se evalúa a null si la variable contiene null --- ### Operador elvis ```java= // JAVA final int length = nickname != null ? nickname.length() : 0; ``` ```kotlin= // KOTLIN val length: Int = nickname?.length ?: 0 ``` - Devuelve la expresión de la izquierda si ésta es distinta de null y la de la derecha en caso contrario - Funciona como un valor por defecto si la expresión es null --- ### Operador bang bang ```java= // JAVA String name = "Baldomero"; final Integer length = name.length(); ``` ```kotlin= // KOTLIN var name: String? = "Baldomero" val lenght = name!!.length ``` - Produce NullPointerException si la variable es null - Se recomienda sólo usarlo cuando estemos completamente seguros de que no es null. --- ### let ```java= // JAVA final String name = "Baldomero"; if (name != null) { System.out.println("Name: " + name); } ``` ```kotlin= // KOTLIN val name: String? = "Baldomero" name?.let { println("Name: $it") } ``` - Extension function, sobre cualquier tipo, que recibe como parámetro una expresión lambda - La lambda es ejecutada pasándole como argumento el objeto sobre el que se ejecuta let - Retorna el valor retornado por la expresión lambda. --- ### also ```java= // JAVA final Student student = new Student(); student.setAge(45); student.setAddress("c/ Avda. Duque de Rivas, 1") ``` ```kotlin= // KOTLIN val student: Student = Student().also { it.age = 45 it.address = "c/ Avda. Duque de Rivas, 1" } ``` - Similar a let pero retorna el propio objeto sobre el que se ejecuta also - Se puede usar para configurar un objeto al crearlo antes de retornarlo (patrón builder) --- ### Hydration break ![](https://media.giphy.com/media/dlbcP3ngz7c6j1kOW2/giphy.gif) --- ### Constructor primario ```java= // JAVA final class Student extends Person { private final boolean isRepeater; private int age; public Student(@NotNull String name, boolean isRepeater, int age) { super(name); this.isRepeater = isRepeater; this.age = age; } } ``` ```kotlin= // KOTLIN class Student(name: String, val isRepeater: Boolean, var age) : Person(name) ``` - Constructor primario definido en primera linea - Llamada al constructor primario de la superclase al definir la herencia --- ### Bloque de inicialización ```java= // JAVA final class Student extends Person { private final boolean isRepeater; private int age; public Student(@NotNull String name, boolean isRepeater, int age) { super(name); this.isRepeater = isRepeater; this.age = age; // Código de inicialización... } } ``` ```kotlin= // KOTLIN class Student(name: String, val isRepeater: Boolean, var age: Int) : Person(name) { init { // Código de inicialización... } } ``` - Código de inicialización en bloque init. --- ### Instanciación ```java= // JAVA final Student student = new Student("Baldomero", false, 23); ``` ```kotlin= // KOTLIN val student = Student("Baldomero", false, 23) ``` - No existe el operador new --- ### Concepto de propiedad ```java= // JAVA final class Student extends Person { private final boolean isRepeater; private int age; private int grade; public Student(@NotNull String name, boolean isRepeater, int age) { super(name); this.isRepeater = isRepeater; this.age = age; } public boolean isRepeater() { return isRepeater; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getGrade() { return grade; } public void setGrade(int grade) { this.grade = grade; } } ``` - Al conjunto formado por el campo (field), el getter y el setter se le conoce como propiedad --- ### Propiedades en Kotlin ```kotlin= // KOTLIN class Student(name: String, val isRepeater: Boolean, var age: Int) : Person(name) { var grade: Int = 0 } ``` - Definidas directamente en el constructor primario o en el cuerpo de la clase - Los parámetros del constructor sin val ni var NO crean propiedades. Son valores para inicialización de otras propiedades --- ### Getter y setters personalizados ```kotlin= // KOTLIN class Student(name: String, val isRepeater: Boolean, var age: Int) : Person(name) { var grade: Int = 0 set(value) { if (value >= 0) field = value else throw IllegalArgumentException() } val gradeDescription: String get() = when(grade) { in 0..4 -> "Mal" in 5..7 -> "Aceptable" in 8..10 -> "Bien" else -> "No válida" } } ``` - field representa el campo interno creado - Podemos crear propiedades que no tienen ningún campo asociado --- ### Acceso a propiedades ```java= // JAVA final Student student = new Student("Baldomero", false, 25); System.out.println(student.getName()); student.setGrade(8); System.out.println(student.getGradeDescription()); ``` ```kotlin= // KOTLIN val student = Student("Baldomero", false, 25) println(student.name) student.grade = 8 println(student.gradeDescription) ``` - Se usa el operador . para acceder a una propiedad, tanto para lectura como para escritura. --- ### Notación infix ```java= // JAVA public final class Pizza { public final void add(@NotNull String ingredient) { System.out.println(ingredient + " added to pizza"); } } Pizza pizza = new Pizza(); pizza.add("Cheese"); ``` ```kotlin= // KOTLIN class Pizza { infix fun add(ingredient: String) { println("$ingredient added to pizza") } } val pizza = Pizza() pizza add "Cheese" ``` - Notación de operaciones aritméticas binarias - Método o extension function con un único parámetro --- ### Concepto de data class ```java= // JAVA public final class User { @NotNull private final String name; private final int age; public User(@NotNull String name, int age) { ... } @NotNull public final String getName() { ... } public final int getAge() { ... } @NotNull public String toString() { ... } public int hashCode() { ... } public boolean equals(@Nullable Object var1) { ... } // ... } ``` - Clase cuyo propósito principal es contener datos. Habitualmente implementan equals(), hashCode() y toString(). --- ### Data class en Kotlin ```kotlin= data class User(val name: String, val age: Int) ``` - Implementaciones por defecto del constructor, getters de propiedades, setters para propiedades var, toString(), hashCode(), equals() - Se puede implementar explícitamente toString(), hashCode() y equals() en el cuerpo de la clase - Implementación del método copy() para crear un nuevo objeto a partir de uno existente - Implementación de métodos para desestructuración: component1(), component2(), etc. --- ### Desestructuración ```java= User jane = new User("Jane", 35); String name = jane.component1(); int age = jane.component2(); ``` ```kotlin= val jane = User("Jane", 35) val (name, age) = jane ``` - Asignación a lista de variables individuales, desde propiedades de un objeto (o elementos de colección) --- ### Delegación ```kotlin= interface Base { fun print() } // Cuando se llame al método print() sobre un objeto de la clase // Derived se llamará automáticamente al método print() de objeto b. class Derived(b: Base) : Base by b { // Otros métodos } ``` - Delegación y composición vs. herencia - El compilador generará automáticamente en la clase Derived el método print(), que internamente llamará a b.print() --- ### Object ```java= public final class RepositoryImp implements Repository { public static final RepositoryImp INSTANCE = new RepositoryImp(); private RepositoryImp() { } // ... } RepositoryImp repository = RepositoryImp.INSTANCE; ``` ```kotlin= object RepositoryImp : Repository { // ... } val repository = RepositoryImp.INSTANCE ``` - Patrón singleton en modo eager con solo usar object en vez de class --- ### Sealed classes ```kotlin= sealed class Post // Las clases hijas pueden ser clases normales, data classes e incluso objects. data class Status(var text: String) : Post() data class Image(var url: String, var caption: String) : Post() data class Video(var url: String, var timeDuration: Int, var encoding: String): Post() object Headline : Post() ``` - Clase que sólo puede tener unas determinadas clases hijas predefinidas - Es abstracta por definición - Tanto la clase padres como las hijas deben estar definidas en el mismo fichero --- ### No exite la palabra reservada static ```java= // JAVA class Person { public static void callMe() { } } Person.callMe(); ``` ```kotlin= // KOTLIN class Person { companion object { fun callMe() { } } } Person.callMe() ``` - Clases de utilidad no necesarias (extension functions y top level functions) - Companion object asociado a una clase --- ### Sobrecarga de operadores ```kotlin= // KOTLIN data class Point(var x: Double, var y: Double) { operator fun plus(point: Point) = Point(x + point.x, y + point.y) } val p1 = Point(2.9, 5.0) val p2 = Point(2.0, 7.5) val p3 = p1 + p2 ``` - Conjunto predefinido de operadores con representación simbólica; +, - , ... - Al usar un operador internamente se llama al método asociado a él: a + b se traduce a a.plus(b) - Podemos definir el método asociado a un determinado operador en nuestras clases --- ### Asociaciones de operadores | Expresión | Se traduce a | | ----------- | --------------------------------- | | a + b, a - b, a * b | a.plus(b), a.minus(b), a.times(b) | | a..b, a in b | a.rangeTo(b), b.contains(a) | | a[i], a[i] = b | a.get(i), a.set(i, b) | | a() | a.invoke() | | a == b | a?.equals(b) ?: (b === null) | | a > b | a.compareTo(b) > 0 | | a += b | a.plusAssign(b) | --- ### Colecciones mutables e inmutables ```kotlin= // KOTLIN val inmutableList = listOf(1, 2, 3) val mutableList = mutableListOf(1, 2, 3) mutableList.add(4) ``` - Interfaces distintas para colecciones inmutables y mutables --- ### Trabajo funcional con colecciones ```java= // JAVA 9 List.of(4, -1, 2, -8) .stream() .filter(it -> it > 0) .map(it -> it * 2) .forEach(System.out::println); ``` ```kotlin= // KOTLIN listOf(4, -1, 2, -8) .filter { it > 0 } .map { it * 2 } .forEach(::println) ``` - Métodos de filtrado, transformación, reducción, etc. directamente en las colecciones - Por defecto eager aunque puede convertirse en lazy - lambdas y referencias a métodos --- ### Otros cambios - Las clases y los métodos son públicos por defecto - Las clases y los métodos son final por defecto (usar open para abrirlos) - Las clases internas son static por defecto - protected es más restrictivo: sólo subclases - Modificador de acceso internal para visibilidad a nivel de módulo - Un fichero puede tener más de una clase pública - No existen las checked exceptions. Tampoco throws --- ## En resumen... --- ![](https://i.imgur.com/vRZGsFJ.jpg) --- ### Referencias - Web oficial: [https://kotlinlang.org/](https://kotlinlang.org/) - Playground: [https://play.kotlinlang.org](https://play.kotlinlang.org) - Learn Kotlin: [https://kotlinlang.org/docs/reference/](https://kotlinlang.org/docs/reference/) --- ![](https://i.imgur.com/J9Etqb4.jpg)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully