Menu
Coddy logo textTech

Kotlin Cheat Sheet

Última actualización

Hello World y conceptos básicos

Un programa Kotlin empieza en una función main de nivel superior: no hace falta una clase.

SintaxisSignificado
fun main() { println("Hello") }Punto de entrada de un programa
println("text")Imprimir una línea en la salida estándar
print("text")Imprimir sin salto de línea al final
// commentComentario de una línea
/* comment */Comentario de varias líneas
val input = readLine()Leer una línea de stdin (String? nullable)
val line = readln()Leer una línea de stdin (no nulo, Kotlin 1.6+)

Variables (val / var) y tipos

Prefiere val; usa var solo cuando el valor tenga que cambiar.

SintaxisSignificado
val name = "Ada"Variable de solo lectura, tipo inferido como String
var count = 0Variable mutable
val age: Int = 30Anotación de tipo explícita
Int, Long, Double, FloatTipos numéricos (42, 42L, 3.14, 3.14f)
Boolean, Char, Stringtrue/false, 'a', "texto"
val big = 1_000_000Guiones bajos para literales legibles
"3".toInt(), "2.5".toDouble()Convertir un string en número
42.toString()Número a string
const val MAX = 10Constante en tiempo de compilación (nivel superior o en un object)

Strings y plantillas

Las plantillas de string sustituyen a la concatenación casi siempre.

SintaxisSignificado
"Hi, $name"Insertar una variable en un string
"Total: ${price * qty}"Insertar una expresión
s.lengthNúmero de caracteres
s.uppercase(), s.lowercase()Cambiar mayúsculas/minúsculas
s.trim()Quitar espacios al principio y al final
s.contains("x"), s.startsWith("a")Buscar dentro de un string
s.substring(0, 3)Cortar por rango de índices
s.split(",")Dividir en una List<String>
s[0]Carácter en un índice
"""raw text"""String crudo de varias líneas, sin escapes
"%.2f".format(3.14159)Salida formateada (3.14)

Null safety

Un tipo no admite nulos por defecto; añade ? para permitir null y el compilador te obliga a tratarlo.

SintaxisSignificado
var s: String? = nullTipo nullable
s?.lengthLlamada segura: devuelve null si s es null
s?.length ?: 0Operador Elvis: valor por defecto cuando es null
s!!.lengthAserción de no nulo: lanza excepción si s es null
if (s != null) s.lengthSmart cast a no nulo dentro de la comprobación
s?.let { println(it) }Ejecutar un bloque solo cuando no es null
val n = s?.toIntOrNull()Convertir, o null si la entrada no es válida
lateinit var x: StringVariable no nula inicializada más tarde

Operadores

OperadorSignificado
+ - * / %Aritmética (/ entre Int es división entera)
+= -= *= /= %=Asignación compuesta
++ --Incremento / decremento
== !=Igualdad estructural (llama a equals)
=== !==Igualdad referencial (mismo objeto)
< > <= >=Comparación
&& || !Y / o / no lógicos
a in 1..10Pertenencia a un rango o colección
x as Int, x as? IntCast / cast seguro (null si falla)
x is StringComprobación de tipo (smart cast si acierta)

Control de flujo (if / when)

if y when son expresiones: devuelven un valor.

SintaxisSignificado
if (a > b) x else yif como expresión (Kotlin no tiene ternario ?:)
if (c) { ... } else if (d) { ... } else { ... }Ramas encadenadas
when (x) { 1 -> "one"; 2 -> "two"; else -> "other" }Comparar con un valor
when (x) { 1, 2 -> "low" }Varios valores en una rama
when (x) { in 1..9 -> "digit" }Comparar con un rango
when (x) { is String -> x.length }Comparar con un tipo (con smart cast)
when { x < 0 -> "neg"; x == 0 -> "zero"; else -> "pos" }when sin sujeto, como if/else if
val label = when (x) { ... }when como expresión (necesita else)

Bucles y rangos

SintaxisSignificado
for (i in 1..5)Rango inclusivo de 1 a 5
for (i in 1 until 5)De 1 a 4 (fin exclusivo)
for (i in 0..<5)Lo mismo con la sintaxis de rango abierto (Kotlin 1.9+)
for (i in 10 downTo 1 step 2)Contar hacia atrás por pasos
for (item in list)Recorrer una colección
for ((i, item) in list.withIndex())Índice y elemento a la vez
for (ch in "abc")Recorrer los caracteres de un string
while (cond) { ... }Repetir mientras sea verdadero
do { ... } while (cond)Ejecutar al menos una vez
break, continueSalir del bucle / saltar a la siguiente iteración
repeat(3) { println(it) }Ejecutar un bloque n veces

Funciones

SintaxisSignificado
fun add(a: Int, b: Int): Int { return a + b }Declarar una función
fun add(a: Int, b: Int) = a + bFunción de una sola expresión, tipo de retorno inferido
fun greet(name: String = "world")Valor por defecto de un parámetro
greet(name = "Ada")Argumento con nombre
fun log(vararg items: String)Número variable de argumentos
fun say(): UnitSin valor de retorno (Unit es opcional)
val square = { x: Int -> x * x }Lambda guardada en una variable
fun String.shout() = uppercase() + "!"Función de extensión
fun apply(f: (Int) -> Int) = f(2)Función como parámetro
list.map { it * 2 }Lambda final, it es el único parámetro

Listas

listOf es de solo lectura; mutableListOf se puede modificar.

SintaxisSignificado
val nums = listOf(1, 2, 3)Lista de solo lectura
val items = mutableListOf("a")Lista mutable
nums[0], nums.first(), nums.last()Acceder a elementos
nums.getOrNull(9)Acceso seguro, null si está fuera de rango
items.add("b"), items.remove("a")Añadir / eliminar
items[0] = "z"Reemplazar por índice
nums.size, nums.isEmpty()Tamaño y si está vacía
x in nums, nums.contains(x)Pertenencia
nums.indexOf(2)Posición de un elemento, -1 si no está
nums.subList(0, 2)Sublista (fin exclusivo)
nums.take(2), nums.drop(1)Los primeros n / todos menos los primeros n
nums.sorted(), nums.reversed()Nueva lista ordenada / invertida
nums.sum(), nums.average(), nums.maxOrNull()Agregados
nums.joinToString(", ")Unir en un solo string
Pair(1, "a"), 1 to "a", Triple(1, 2, 3)Tuplas pequeñas de tamaño fijo

Mapas y sets

SintaxisSignificado
val m = mapOf("a" to 1, "b" to 2)Mapa de solo lectura
val mm = mutableMapOf<String, Int>()Mapa mutable
m["a"]Búsqueda (null si no existe)
m.getOrDefault("z", 0)Búsqueda con valor por defecto
mm["c"] = 3Insertar o actualizar
for ((k, v) in m)Recorrer entradas con desestructuración
m.keys, m.valuesColecciones de claves / valores
"a" in mPertenencia de una clave
val s = setOf(1, 2, 2)Set de valores únicos ({1, 2})
mutableSetOf<Int>()Set mutable

Operaciones sobre colecciones (lambdas)

SintaxisSignificado
list.map { it * 2 }Transformar cada elemento
list.filter { it > 2 }Conservar los elementos que cumplen la condición
list.forEach { println(it) }Hacer algo con cada elemento
list.any { it > 2 }, list.all { it > 0 }¿Algún / todo elemento cumple la condición?
list.count { it % 2 == 0 }Contar coincidencias
list.find { it > 2 }Primera coincidencia o null
list.sortedBy { it.length }Ordenar por una clave
list.groupBy { it.first() }Agrupar en un Map
list.distinct()Eliminar duplicados
list.fold(0) { acc, x -> acc + x }Reducir con un valor inicial
list.zip(other)Emparejar dos listas
list.flatMap { it.toList() }Transformar y luego aplanar

Clases y data classes

SintaxisSignificado
class User(val name: String, var age: Int)Clase con constructor primario y propiedades
val u = User("Ada", 36)Crear una instancia (sin new)
u.name, u.age = 37Leer / escribir propiedades
data class Point(val x: Int, val y: Int)equals, hashCode, toString, copy gratis
p.copy(y = 5)Copia con algunas propiedades cambiadas
val (x, y) = pDeclaración de desestructuración
open class Base, class Sub : Base()Herencia (las clases son final por defecto)
override fun toString() = "..."Sobrescribir un miembro
object Config { val debug = true }Singleton
companion object { fun create() = User("", 0) }Miembros de tipo estático
enum class Color { RED, GREEN }Enum
sealed class ResultJerarquía de clases restringida, exhaustiva en when
interface Shape { fun area(): Double }Interfaz

Manejo de errores

SintaxisSignificado
try { ... } catch (e: Exception) { ... }Capturar una excepción
try { ... } finally { ... }Ejecutar siempre la limpieza
val n = try { s.toInt() } catch (e: NumberFormatException) { 0 }try como expresión
throw IllegalArgumentException("bad")Lanzar una excepción
require(x > 0) { "x must be positive" }Comprobación de argumento (lanza IllegalArgumentException)
check(ready) { "not ready" }Comprobación de estado (lanza IllegalStateException)
s.toIntOrNull()Devolver null en lugar de lanzar
runCatching { risky() }.getOrDefault(0)Envolver una llamada en un Result

Funciones de ámbito

Cinco pequeñas ayudas para trabajar con un objeto dentro de un bloque.

SintaxisSignificado
x.let { it + 1 }it es el objeto, devuelve el resultado del bloque
x.run { this + 1 }this es el objeto, devuelve el resultado del bloque
x.apply { field = 1 }this es el objeto, devuelve el objeto
x.also { println(it) }it es el objeto, devuelve el objeto
with(x) { field }No es una extensión; this es x, devuelve el resultado del bloque
x?.let { ... }La comprobación de nulo idiomática + uso

Toda la sintaxis de Kotlin que buscas, en una sola página. Este cheat sheet de Kotlin es una referencia rápida del lenguaje detrás de Android y de buena parte de la JVM moderna: declarar variables, manejar nulos con seguridad, ramificar con when, recorrer rangos, escribir funciones y trabajar con listas y mapas.

Todo lo que hay aquí es Kotlin estándar y funciona igual en la JVM, en Android y con Kotlin Multiplatform. Copia lo que necesites o pruébalo en vivo en el playground de Kotlin: pega un fragmento, pulsa Run y mira la salida en tu navegador.

Preguntas frecuentes sobre el cheat sheet de Kotlin

¿Este cheat sheet de Kotlin es gratis?
Sí. Este cheat sheet de Kotlin es totalmente gratuito y no requiere registro. Guárdalo en favoritos y vuelve cuando necesites consultar una rama de when, un operador de null safety o un método de colección.
¿Cuál es la diferencia entre val y var en Kotlin?
val declara una referencia de solo lectura: se asigna una vez y no puede reasignarse. var declara una variable mutable que sí puede reasignarse. Ten en cuenta que val solo fija la referencia: a una val list = mutableListOf(1) todavía se le pueden añadir elementos. El estilo Kotlin es usar val en todas partes y pasar a var solo cuando la reasignación es realmente necesaria.
¿Cómo funciona el null safety en Kotlin?
Los tipos no admiten nulos por defecto, así que String nunca puede contener null; String? sí. El compilador no te deja llamar a un método sobre un valor nullable sin tratar el caso null: con una llamada segura (s?.length), un valor por defecto con Elvis (s?.length ?: 0), una comprobación de nulo con smart cast (if (s != null)) o, como último recurso, la aserción de no nulo s!!, que lanza una NullPointerException si el valor es realmente null.
¿Cuándo debo usar when en lugar de if en Kotlin?
Usa when siempre que compares un valor contra varias posibilidades (constantes, rangos, tipos o una mezcla) y usa if/else para una única condición de sí o no. Ambos son expresiones, así que val label = when (x) { ... } y val label = if (c) a else b son idiomáticos. Un when usado como expresión debe ser exhaustivo, lo que normalmente significa añadir una rama else (las sealed classes y los enums pueden serlo sin ella).
¿Puedo practicar Kotlin online?
Sí. Abre el playground de Kotlin para ejecutar cualquier fragmento de este cheat sheet en tu navegador, sin instalar el JDK ni IntelliJ. Cuando quieras estructura, el curso interactivo y gratuito de Kotlin de Coddy te lleva desde Hello World hasta null safety, when, bucles, funciones y colecciones, y emite un certificado gratuito al final.
Coddy programming languages illustration

Aprende Kotlin con Coddy

COMENZAR