Почему мы используем в Kotlin только коллекции [List, Map, Set]?

Я изучал Kotlin и столкнулся с Collections API. До Kotlin я изучал Java и знаю, что в Java существует множество различных типов API коллекций. Например, вместо общего List, Map, Queue, Set мы используем ArrayList, HashMap, LinkedList, LinkedMap и т. д. Хотя в Котлине мы используем только общие типы, такие как Map, List, Set, но также можем использовать HashMap и т. д. Итак, что там происходит? Можете ли вы помочь мне разобраться?

В Kotlin мы используем все коллекции, которые существуют в Java. Каков ваш вопрос снова?

Saeed Entezari 14.07.2019 13:45

@SaeedEntezari на официальном сайте я видел, где документы писали о List, Map, Set на вкладке «Коллекции», но не о чем-то другом.

John Walker 14.07.2019 14:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
487
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хотя исходной и основной целью Kotlin является JVM, JetBrains прилагает огромные усилия, чтобы сделать его мультиплатформенный, а также поддерживать JS и Native.

Если вы используете Kotlin на JVM, реализации любых коллекций, которые вы используете, по-прежнему будут исходными классами JDK, например. java.util.ArrayList или java.util.HashSet. Они не переопределяются стандартной библиотекой Kotlin, что имеет ряд больших преимуществ:

  • Это хорошо протестированные реализации, которые в любом случае поддерживаются.
  • Использование одних и тех же классов упрощает взаимодействие с Java, поскольку вы можете передавать их туда и обратно без необходимости выполнять какие-либо преобразования или сопоставления.

Что делает Kotlin, так это вводит свою собственную семантику коллекций над этих существующих реализаций в виде интерфейсов стандартной библиотеки, таких как List, Map, MutableList, MutableMap и так далее. Небольшая часть магия компилятора делает так, что эти интерфейсы также реализуются существующими классами JDK.


Если вам не нужна конкретная реализация определенного типа коллекции, вы можете использовать свои коллекции через эти интерфейсы плюс соответствующие фабричные методы стандартной библиотеки (listOf, mapOf, mutableListOf, mutableMapOf и т. д.). Это делает ваш код более общим и независимым от конкретных базовых реализаций. Вы не знаете, какой конкретный класс будет создавать для вас функция стандартной библиотеки mutableListOf, только то, что это будет объект, который удовлетворяет контракту интерфейса MutableList.

В основном вы должны использовать эти интерфейсы по умолчанию в своем коде, особенно в общедоступном API:

  • В случае параметров функции это позволяет клиентам предоставлять функции любую реализацию коллекции, которую они хотят вам предоставить. Если ваша функция может работать с чем-либо, что является List, вы должны запросить только этот интерфейс — нет причин требовать ArrayList или LinkedList конкретно.
  • Если это возвращаемый тип, использование этих интерфейсов позволяет изменить конкретную реализацию, которую вы создадите внутри в будущем, не нарушая клиентский код. Вы можете пообещать просто вернуть MutableList вещей, и какая реализация поддерживает этот список, не раскрывается вашим клиентам.

Если вы посмотрите на все функции обработки коллекций стандартной библиотеки Kotlin, вы увидите, что на первый взгляд они работают почти исключительно с этими интерфейсами. Если вы копнете достаточно глубоко, вы обнаружите ArrayList экземпляры, которые создаются, но это не отображается для клиентского кода, поскольку большую часть времени ему не нужно заботиться о конкретной реализации.


Возвращаясь еще раз к мультиплатформенности, если вы пишете свой код таким образом, что он опирается только на типы, определенные стандартной библиотекой Kotlin, этот код будет легко использовать для целей, отличных от JVM. Если вы ссылаетесь на kotlin.MutableList в своем импорте, это может быть немедленно скомпилировано в код JS, потому что на каждой платформе есть реализация этого интерфейса в стандартной библиотеке Kotlin. Сопоставляется ли это с существующим классом напрямую, каким-то образом обертывает существующий класс или реализуется для Kotlin с нуля, опять же, вас не должно волновать. Но если вы ссылаетесь на java.util.TreeSet в своем коде, это не сработает для цели JS, поскольку классы платформы Java там недоступны.


Можете ли вы по-прежнему использовать такие классы, как java.util.ArrayList напрямую? Конечно.

  • Если вы не видите, что ваш код в какой-то момент становится многоплатформенным, использование коллекций Java напрямую вполне нормально.
  • Если вам нужна конкретная реализация для List или Set из соображений производительности, иногда вам придется напрямую использовать классы Java.

Интересно, что в последних выпусках Kotlin эти конкретные типы реализаций (например, список на основе массива) также заключены в псевдонимы стандартных библиотек, так что по умолчанию они не зависят от платформы: см. kotlin.collections.ArrayList или kotlin.collections.HashSet для примеров этого. Эти типы, определенные в Kotlin, обычно появляются первыми при завершении IntelliJ, поэтому вы обнаружите, что вас подталкивают к их использованию везде, где это возможно. То же самое касается большинства исключений, например. IllegalArgumentException.


TL;DR: вы можете использовать в Kotlin любые типы коллекций Kotlin для типов Java, но вам, вероятно, следует использовать первое, когда это возможно.

Другие вопросы по теме