Рассмотрим изменения стандартной библиотеки, относящиеся к версии Kotlin 1.5.
1. Новые функции коллекции
Допустим, есть список объектов, в каждом из которых имеется свойство, допускающее значение «null». Как получить первое, отличное от «null» значение этого свойства в коллекции?
Обычно с помощью функции mapNotNull()
сначала получают коллекцию всех значений, отличных от «null». А затем для получения искомого значения вызывают firstOrNull()
.
В Kotlin 1.5 имеются функции firstNotNullOf()
и firstNotNullOfOrNull()
. Функция firstNotNullOf()
возвращает первое, отличное от «null» значение переданного селектора либо исключение, когда нет ни одного подходящего элемента. Вторая функция ведет себя аналогично, но в случае отсутствия подходящего элемента возвращает «null».
firstNotNullOf()
работает за две функции: mapNotNull()
и first()
. Так же и firstNotNullOfOrNull()
работает за функции mapNotNull()
и firstOrNull()
.
Проиллюстрируем это кодом:
data class Employee(val name: String, val designation: String?)
val employees = listOf(
Employee("Felix", null),
Employee("Vee", null),
Employee("Ram", "Developer"),
Employee("Vivek", "Senior Developer"),
Employee("Joe", "Developer"),
)
// Старый метод
val firstDesignation = employees.mapNotNull { it.designation }.firstOrNull()
// Метод Kotlin 1.5
val newfirstDesignation = employees.firstNotNullOfOrNull { it.designation }
2. Целочисленные типы без знака Ubyte, UShort, UInt и ULong
Они применяются там, где надо, чтобы тип содержал только неотрицательные значения. Эти типы более интуитивно понятны в работе на уровне битов и байтов и при манипулировании пикселями в растровой графике, байтами в файле или другими двоичными данными.
UByte
: 8-разрядное целое число без знака в диапазоне от 0 до 255.UShort
: 16-разрядное целое число без знака от 0 до 65 535.UInt
: 32-разрядное целое число без знака от 0 до 2³² – 1.ULong
: 64-разрядное целое число без знака от 0 до 2⁶⁴ – 1.
3. Целочисленное деление с округлением вниз и оператор mod
Появилась новая функция floorDiv()
для деления целых чисел с округлением результата в меньшую сторону:
(5).floorDiv(3) -> returns 1
(-5).floorDiv(3) -> returns -2
Функция вычисления остатка mod
возвращает остаток от деления, а результат при этом округляется вниз. Она совершенно отличается от оператора %
, который в Kotlin называется rem
.
Вот пример кода:
val a = -4
val b = 3
println(-4 % 3) -> -1
println(a.mod(b)) -> 2
Здесь оператор %
возвращает остаток –1
. Но a.mod(b)
— это разница между a
и a.floorDiv(b) * b
. Она либо равна нулю, либо имеет тот же знак, что и b
, хотя a % b
может иметь другой знак.
4. API преобразования символов в целые числа
В Kotlin появились функции, которые делают преобразование отдельных символов в числа более выразительным.
При таком преобразовании во внимание принимается одно из двух: либо код символов для соответствующего символа, либо фактическая цифра, которую представляет символ, выполняя парсинг числа.
И то и другое лаконично выражается с помощью нового API преобразования. Здесь появились преобразования Char
, которые разделены на следующие наборы функций с четкими наименованиями:
- Функции для получения кода с целыми числами
Char
и построенияChar
из данного кода:
fun Char(code: Int): Char
fun Char(code: UShort): Char
val Char.code: Int
- Функции для преобразования
Char
в числовое значение цифры, которую представляет символ:
fun Char.digitToInt(radix: Int): Int
fun Char.digitToIntOrNull(radix: Int): Int?
- Функция-расширение для
Int
для преобразования представляемого им неотрицательного числа, состоящего из одной цифры, в соответствующем видеChar
:
fun Int.digitToChar(radix: Int): Char
5. Категория символов в мультиплатформенном коде
Появились функции для проверки свойств символов, доступных в общем коде. С их помощью проверяется символ (это цифра, буква либо цифра или буква) и буква (прописная, строчная или заглавная), а также определено ли его представление в Юникоде или это последовательность ISO.
'1'.isDigit() -> true
'A'.isLetter() -> true
'!'.isLetterOrDigit() -> false
'C'.isLowerCase() -> false
'C'.isUpperCase() -> true
'b'.isTitleCase() -> false
'?'.isDefined() -> true
'\n'.isISOControl() -> true
6. Функции преобразования строк/символов с учетом регистра
В Kotlin 1.5 появился новый, не зависящий от локали API для преобразования текста верхнего/нижнего регистров. «Не зависящий от локали» означает: какими бы ни были языковые настройки в целевой системе, вы получите последовательные результаты преобразования с учетом регистра.
То есть новый API помогает избежать ошибок, обусловленных различными настройками языковых стандартов. Вот старый и новый способы преобразований:
Функции преобразования строк String
:
Функции преобразования символов Char
:
Нужно преобразование на основе локали? Тогда необходимо прямо указать ее:
“kotlin”.uppercase(Locale.forLanguageTag(“tr-TR”))
7. Строгая версия String?.toBoolean()
Появились также функции String.toBooleanStrict()
и String.toBooleanStrictOrNull()
. Функция .toBooleanStrict()
выбрасывает исключение для всех входных данных, кроме литералов true
или false
.
Здесь тоже учитывается регистр. Поэтому в примере "true".toBooleanStrict()
выдает true
, а "True".toBooleanStrict()
выбрасывает исключения.
Функция String.toBooleanStrictOrNull()
вместо исключения выдаст null
для всех входных данных, кроме литералов true
или false
. И здесь также учитывается регистр.
"true".toBooleanStrictOrNull()
-> возвращает true
"True".toBooleanStrictOrNull()
-> возвращает null
.
Вот и все об изменениях стандартной библиотеки Kotlin. Хотите узнать больше? Воспользуйтесь документацией.
Читайте также:
- Модификатор Kotlin, которого не должно было быть
- Корутины Kotlin: как работать асинхронно в Android
- Как избежать утечек памяти с помощью Kotlin
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Shalu T D: Exploring the Kotlin 1.5 Standard Library