Menu
CoddyTech

Cheat sheet Kotlin

Cập nhật lần cuối

Hello World và kiến thức cơ bản

Chương trình Kotlin bắt đầu từ hàm main cấp cao nhất, không cần lớp nào bao ngoài.

Cú phápÝ nghĩa
fun main() { println("Hello") }Điểm bắt đầu chương trình
println("text")In một dòng ra đầu ra chuẩn
print("text")In không xuống dòng ở cuối
// commentChú thích một dòng
/* comment */Chú thích nhiều dòng
val input = readLine()Đọc một dòng từ stdin (kiểu nullable String?)
val line = readln()Đọc một dòng từ stdin (không null, Kotlin 1.6+)

Biến (val / var) và kiểu dữ liệu

Ưu tiên val; chỉ dùng var khi giá trị buộc phải thay đổi.

Cú phápÝ nghĩa
val name = "Ada"Biến chỉ đọc, kiểu được suy luận là String
var count = 0Biến thay đổi được
val age: Int = 30Khai báo kiểu tường minh
Int, Long, Double, FloatKiểu số (42, 42L, 3.14, 3.14f)
Boolean, Char, Stringtrue/false, 'a', "text"
val big = 1_000_000Dấu gạch dưới giúp số dễ đọc hơn
"3".toInt(), "2.5".toDouble()Chuyển chuỗi thành số
42.toString()Chuyển số thành chuỗi
const val MAX = 10Hằng số lúc biên dịch (ở cấp cao nhất hoặc trong một object)

Chuỗi và string template

String template thay cho việc nối chuỗi ở hầu hết mọi chỗ.

Cú phápÝ nghĩa
"Hi, $name"Chèn biến vào chuỗi
"Total: ${price * qty}"Chèn biểu thức
s.lengthSố ký tự
s.uppercase(), s.lowercase()Đổi chữ hoa / chữ thường
s.trim()Xóa khoảng trắng ở đầu và cuối
s.contains("x"), s.startsWith("a")Tìm trong chuỗi
s.substring(0, 3)Cắt theo khoảng chỉ số
s.split(",")Tách thành một List<String>
s[0]Ký tự tại một chỉ số
"""raw text"""Chuỗi thô nhiều dòng, không cần escape
"%.2f".format(3.14159)Đầu ra có định dạng (3.14)

Null safety

Mặc định một kiểu không được null; thêm ? để cho phép null, và trình biên dịch sẽ buộc bạn xử lý trường hợp đó.

Cú phápÝ nghĩa
var s: String? = nullKiểu nullable
s?.lengthGọi an toàn: trả về null nếu s là null
s?.length ?: 0Toán tử Elvis: giá trị dự phòng khi gặp null
s!!.lengthKhẳng định không null: ném lỗi nếu s là null
if (s != null) s.lengthSmart cast sang kiểu không null bên trong phép kiểm tra
s?.let { println(it) }Chỉ chạy khối lệnh khi không phải null
val n = s?.toIntOrNull()Chuyển đổi, hoặc trả về null nếu dữ liệu sai
lateinit var x: StringBiến var không null, khởi tạo sau

Toán tử

Toán tửÝ nghĩa
+ - * / %Số học (/ giữa hai Int là phép chia lấy phần nguyên)
+= -= *= /= %=Gán kết hợp
++ --Tăng / giảm 1
== !=So sánh bằng về cấu trúc (gọi equals)
=== !==So sánh bằng về tham chiếu (cùng một đối tượng)
< > <= >=So sánh
&& || !Logic and / or / not
a in 1..10Kiểm tra thuộc range hoặc collection
x as Int, x as? IntÉp kiểu / ép kiểu an toàn (null nếu thất bại)
x is StringKiểm tra kiểu (tự smart cast nếu đúng)

Luồng điều khiển (if / when)

if và when là biểu thức, nghĩa là chúng trả về một giá trị.

Cú phápÝ nghĩa
if (a > b) x else yif dùng như biểu thức (Kotlin không có toán tử ba ngôi ?:)
if (c) { ... } else if (d) { ... } else { ... }Chuỗi nhánh điều kiện
when (x) { 1 -> "one"; 2 -> "two"; else -> "other" }So khớp một giá trị
when (x) { 1, 2 -> "low" }Nhiều giá trị trong một nhánh
when (x) { in 1..9 -> "digit" }So khớp một range
when (x) { is String -> x.length }So khớp kiểu (kèm smart cast)
when { x < 0 -> "neg"; x == 0 -> "zero"; else -> "pos" }when không có đối tượng so khớp, giống if/else if
val label = when (x) { ... }when dùng như biểu thức (cần có else)

Vòng lặp và range

Cú phápÝ nghĩa
for (i in 1..5)Range từ 1 đến 5 (bao gồm 5)
for (i in 1 until 5)Từ 1 đến 4 (không bao gồm giá trị cuối)
for (i in 0..<5)Tương tự, cú pháp range mở (Kotlin 1.9+)
for (i in 10 downTo 1 step 2)Đếm ngược theo bước nhảy
for (item in list)Duyệt một collection
for ((i, item) in list.withIndex())Lấy cả chỉ số lẫn phần tử
for (ch in "abc")Duyệt từng ký tự của chuỗi
while (cond) { ... }Lặp khi điều kiện còn đúng
do { ... } while (cond)Chạy ít nhất một lần
break, continueThoát vòng lặp / bỏ qua sang lần lặp tiếp theo
repeat(3) { println(it) }Chạy một khối lệnh n lần

Hàm

Cú phápÝ nghĩa
fun add(a: Int, b: Int): Int { return a + b }Khai báo hàm
fun add(a: Int, b: Int) = a + bHàm một biểu thức, kiểu trả về được suy luận
fun greet(name: String = "world")Giá trị mặc định của tham số
greet(name = "Ada")Đối số có tên
fun log(vararg items: String)Số lượng đối số tùy ý
fun say(): UnitKhông có giá trị trả về (Unit có thể bỏ qua)
val square = { x: Int -> x * x }Lambda lưu trong biến
fun String.shout() = uppercase() + "!"Hàm mở rộng (extension function)
fun apply(f: (Int) -> Int) = f(2)Hàm làm tham số
list.map { it * 2 }Trailing lambda, it là tham số duy nhất

List

listOf chỉ đọc; mutableListOf thay đổi được.

Cú phápÝ nghĩa
val nums = listOf(1, 2, 3)List chỉ đọc
val items = mutableListOf("a")List thay đổi được
nums[0], nums.first(), nums.last()Truy cập phần tử
nums.getOrNull(9)Truy cập an toàn, null nếu vượt phạm vi
items.add("b"), items.remove("a")Thêm / xóa
items[0] = "z"Thay thế theo chỉ số
nums.size, nums.isEmpty()Kích thước và kiểm tra rỗng
x in nums, nums.contains(x)Kiểm tra phần tử có trong list
nums.indexOf(2)Vị trí của phần tử, -1 nếu không có
nums.subList(0, 2)Cắt list (không bao gồm vị trí cuối)
nums.take(2), nums.drop(1)Lấy n phần tử đầu / bỏ n phần tử đầu
nums.sorted(), nums.reversed()List mới đã sắp xếp / đảo ngược
nums.sum(), nums.average(), nums.maxOrNull()Hàm tổng hợp
nums.joinToString(", ")Nối thành một chuỗi
Pair(1, "a"), 1 to "a", Triple(1, 2, 3)Bộ giá trị nhỏ cố định

Map và set

Cú phápÝ nghĩa
val m = mapOf("a" to 1, "b" to 2)Map chỉ đọc
val mm = mutableMapOf<String, Int>()Map thay đổi được
m["a"]Tra cứu (null nếu không có)
m.getOrDefault("z", 0)Tra cứu kèm giá trị dự phòng
mm["c"] = 3Thêm hoặc cập nhật
for ((k, v) in m)Duyệt các cặp khóa và giá trị bằng destructuring
m.keys, m.valuesTập khóa / tập giá trị
"a" in mKiểm tra khóa có tồn tại
val s = setOf(1, 2, 2)Set các giá trị không trùng lặp ({1, 2})
mutableSetOf<Int>()Set thay đổi được

Thao tác trên collection (lambda)

Cú phápÝ nghĩa
list.map { it * 2 }Biến đổi từng phần tử
list.filter { it > 2 }Giữ các phần tử thỏa điều kiện
list.forEach { println(it) }Xử lý từng phần tử
list.any { it > 2 }, list.all { it > 0 }Có phần tử nào / mọi phần tử đều thỏa điều kiện
list.count { it % 2 == 0 }Đếm số phần tử thỏa điều kiện
list.find { it > 2 }Phần tử đầu tiên thỏa điều kiện hoặc null
list.sortedBy { it.length }Sắp xếp theo khóa
list.groupBy { it.first() }Nhóm thành một Map
list.distinct()Loại bỏ phần tử trùng
list.fold(0) { acc, x -> acc + x }Gộp giá trị từ một giá trị ban đầu
list.zip(other)Ghép cặp hai list
list.flatMap { it.toList() }Map rồi làm phẳng

Lớp và data class

Cú phápÝ nghĩa
class User(val name: String, var age: Int)Lớp có hàm khởi tạo chính và thuộc tính
val u = User("Ada", 36)Tạo instance (không cần new)
u.name, u.age = 37Đọc / ghi thuộc tính
data class Point(val x: Int, val y: Int)Có sẵn equals, hashCode, toString, copy
p.copy(y = 5)Sao chép và đổi một vài thuộc tính
val (x, y) = pKhai báo destructuring
open class Base, class Sub : Base()Kế thừa (mặc định lớp là final)
override fun toString() = "..."Ghi đè một thành viên
object Config { val debug = true }Singleton
companion object { fun create() = User("", 0) }Thành viên kiểu static
enum class Color { RED, GREEN }Enum
sealed class ResultCây lớp giới hạn, when kiểm tra đủ mọi trường hợp
interface Shape { fun area(): Double }Interface

Xử lý lỗi

Cú phápÝ nghĩa
try { ... } catch (e: Exception) { ... }Bắt ngoại lệ
try { ... } finally { ... }Luôn chạy phần dọn dẹp
val n = try { s.toInt() } catch (e: NumberFormatException) { 0 }try dùng như biểu thức
throw IllegalArgumentException("bad")Ném ngoại lệ
require(x > 0) { "x must be positive" }Kiểm tra đối số (ném IllegalArgumentException)
check(ready) { "not ready" }Kiểm tra trạng thái (ném IllegalStateException)
s.toIntOrNull()Trả về null thay vì ném lỗi
runCatching { risky() }.getOrDefault(0)Bọc lời gọi trong một Result

Scope function

Năm hàm nhỏ giúp làm việc với một đối tượng bên trong một khối lệnh.

Cú phápÝ nghĩa
x.let { it + 1 }it là đối tượng, trả về kết quả của khối lệnh
x.run { this + 1 }this là đối tượng, trả về kết quả của khối lệnh
x.apply { field = 1 }this là đối tượng, trả về chính đối tượng
x.also { println(it) }it là đối tượng, trả về chính đối tượng
with(x) { field }Không phải hàm mở rộng; this là x, trả về kết quả của khối lệnh
x?.let { ... }Cách kiểm tra null rồi dùng giá trị chuẩn Kotlin

Mọi cú pháp Kotlin bạn hay dùng, gói gọn trong một trang. Cheat sheet Kotlin này là bảng tra cứu nhanh cho ngôn ngữ đứng sau Android và phần lớn hệ sinh thái JVM hiện đại: khai báo biến, xử lý null an toàn, rẽ nhánh với when, lặp qua range, viết hàm, và làm việc với list và map.

Mọi thứ ở đây đều là Kotlin chuẩn, chạy được trên JVM, Android lẫn Kotlin Multiplatform. Sao chép đoạn bạn cần, hoặc thử ngay trong playground Kotlin: dán đoạn code, nhấn Chạy và xem đầu ra ngay trên trình duyệt.

Câu hỏi thường gặp về cheat sheet Kotlin

Cheat sheet Kotlin này có miễn phí không?
Có. Cheat sheet Kotlin này hoàn toàn miễn phí và không cần đăng ký. Lưu trang lại và quay lại bất cứ khi nào bạn cần tra một nhánh when, một toán tử null safety hay một phương thức của collection.
Trong Kotlin, val và var khác nhau thế nào?
val khai báo một tham chiếu chỉ đọc: được gán một lần và không gán lại được. var khai báo biến thay đổi được, có thể gán lại. Lưu ý val chỉ cố định tham chiếu: với val list = mutableListOf(1), bạn vẫn thêm được phần tử. Phong cách Kotlin là dùng val ở mọi nơi và chỉ chuyển sang var khi thực sự cần gán lại.
Null safety trong Kotlin hoạt động thế nào?
Mặc định các kiểu không được null, nên String không bao giờ chứa null, còn String? thì có thể. Trình biên dịch không cho bạn gọi phương thức trên giá trị nullable nếu chưa xử lý trường hợp null: dùng lời gọi an toàn (s?.length), giá trị dự phòng với Elvis (s?.length ?: 0), phép kiểm tra null kèm smart cast (if (s != null)), hoặc cách cuối cùng là khẳng định không null s!!, sẽ ném NullPointerException nếu giá trị thực sự là null.
Khi nào nên dùng when thay cho if trong Kotlin?
Dùng when mỗi khi bạn so sánh một giá trị với nhiều khả năng: hằng số, range, kiểu, hoặc kết hợp các loại đó; còn if/else cho một điều kiện đúng hoặc sai đơn lẻ. Cả hai đều là biểu thức, nên val label = when (x) { ... } và val label = if (c) a else b đều là cách viết chuẩn Kotlin. Khi when được dùng như biểu thức, nó phải bao quát mọi trường hợp, thường có nghĩa là thêm nhánh else (sealed class và enum có thể bao quát đủ mà không cần nhánh này).
Có thể luyện tập Kotlin online không?
Có. Mở playground Kotlin để chạy bất kỳ đoạn code nào trong cheat sheet này ngay trên trình duyệt, không cần cài JDK hay IntelliJ. Khi muốn học có lộ trình, khóa học Kotlin tương tác miễn phí của Coddy dẫn bạn từ Hello World qua null safety, when, vòng lặp, hàm và collection, và cấp giấy chứng nhận hoàn thành miễn phí khi kết thúc.
Hình minh họa các ngôn ngữ lập trình của Coddy

Học Kotlin cùng Coddy

Bắt đầu