Как добавить элемент в список kotlin
Перейти к содержимому

Как добавить элемент в список kotlin

  • автор:

Как добавить элемент в список kotlin

На этом шаге мы рассмотрим способы изменения содержимогосписка .

Если посетитель пришел или ушел в середине ночи, внимательный трактирщик должен добавить или убрать имя посетителя из переменной patronList . В настоящее время это невозможно.

Функция listOf() возвращает список, доступный только для чтения, в котором нельзя менять содержимое: вы не сможете добавить, убрать, обновить или заменить данные. Доступные только для чтения списки — хорошее решение, потому что они предотвращают досадные ошибки, например, возможность выгнать посетителя на улицу, убрав его имя из списка случайно.

Природа доступа только для чтения у списка не имеет ничего общего с ключевым словом val или var , использованным для объявления переменной списка. Заменив в объявлении переменной patronList c val (как сейчас) на var , вы не сделаете список доступным для изменения. Вам просто будет разрешено присвоить переменной patronList другое значение, то есть создать новый список.

Возможность изменять список напрямую зависит от его типа, который и определяет возможность изменять элементы в списке. Поскольку посетители постоянно приходят и уходят, мы должны изменить тип patronList , чтобы разрешить обновление. В языке Kotlin модифицируемый список известен как изменяемый список , и вы должны вызвать функцию mutableListOf() , чтобы его создать.

Измените код Tavern.kt и используйте mutableListOf() вместо listOf() . Изменяемые списки поддерживают множество функций для добавления, удаления и обновления содержимого. Смоделируйте приход и уход нескольких посетителей, использовав функции add() и remove() .

import kotlin.math.roundToInt const val TAVERN_NAME = "Taernyl's Folly" var playerGold = 10 var playerSilver = 10 val patronList = mutableListOf("Eli", "Mordoc", "Sophie") fun main() < . . . . placeOrder("shandy,Dragon's Breath,5.91") println(patronList) patronList.remove("Eli") patronList.add("Alex") println(patronList) > . . . .

Файл с проектом можно взять здесь.

Рис.1. Создание изменяемого списка посетителей (Tavern.kt)

Запустите Tavern.kt . В консоли появится следующее сообщение:

Madrigal exclaims Ah, d3l1c10|_|s Dr4g0n's Br34th! [Eli, Mordoc, Sophie] [Mordoc, Sophie, Alex]

Рис.2. Результат работы приложения

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

Обратите внимание, что новый элемент был добавлен в конец списка. Можно добавить посетителя в конкретное место списка. Например, если VIP -гость придет в таверну, трактирщик может отдать ему предпочтение в очереди.

Добавьте VIP -гостя — пусть это будет посетитель с таким же именем Алекс ( Alex ) — в начало списка посетителей. (Алекс хорошо известен в городе и пользуется такими привилегиями, как покупка пинты Dragon’s Breath раньше всех остальных, что, конечно, не нравится другому Алексу.) Список может содержать несколько элементов с одинаковым значением, как, например, два посетителя с одинаковыми именами, поэтому добавление еще одного Алекса — это не проблема для списка.

. . . . fun main() < . . . . placeOrder("shandy,Dragon's Breath,5.91") println(patronList) patronList.remove("Eli") patronList.add("Alex") patronList.add(0, "Alex") println(patronList) > . . . .

Файл с проектом можно взять здесь.

Рис.3. Добавление еще одного Alex (Tavern.kt)

Запустите Tavern.kt снова. Вы увидите следующий вывод:

[Eli, Mordoc, Sophie] [Alex, Mordoc, Sophie, Alex]

Рис.4. Результат работы приложения

Чтобы сделать список patronList изменяемым, нам пришлось заменить в своем коде listOf() на mutableListOf() . Но List имеет функции, позволяющие превращать неизменяемые списки в изменяемые и обратно прямо в процессе выполнения: toList() и toMutableList() . Например, снова сделайте изменяемый patronList() доступным только для чтения, используя toList() :

val patronList = mutablelistOf("Eli", "Mordoc", "Sophie") val readOnlyPatronList = patronList.toList()

Допустим, популярный Alex решил сменить имя на Alexis . Исполнить его желание можно, изменив patronList при помощи оператора присваивания ([]=), то есть присвоив строке с первым индексом новое значение.

. . . . fun main() < . . . . placeOrder("shandy,Dragon's Breath,5.91") println(patronList) patronList.remove("Eli") patronList.add("Alex") patronList.add(0, "Alex") patronList[0] = "Alexis" println(patronList) > . . . .

Файл с проектом можно взять здесь.

Рис.5. Модифицирование изменяемого списка с помощью оператора присваивания (Tavern.kt)

Запустите Tavern.kt . Вы увидите, что patronList обновился и содержит новое имя Alexis .

[Eli, Mordoc, Sophie] [Alexis, Mordoc, Sophie, Alex]

Рис.6. Результат работы приложения

Функции, которые изменяют содержимое изменяемых списков, называют мутаторами . В таблице 1 перечислены самые распространенные мутаторы для списков.

Таблица 1. Мутаторы изменяемых списков
Функция Описание Примеры
[]= (оператор присваивания) Присваивает значение по индексу; возбуждает исключение, если индекс не существует val patronList = mutableListOf(«Eli», «Mordoc», «Sophie»)
patronList[4] = «Reggie»
IndexOutOfBoundsException
add Добавляет элемент в конец списка, увеличивая размер на один элемент val patronList = mutableListOf(«Eli», «Mordoc», «Sophie»)
patronList.add(«Reggie»)
[Eli, Mordoc, Sophie, Reggie]
patronList.size
4
add (по индексу) Добавляет элемент в список по индексу, увеличивая размер на один элемент. Возбуждает исключение, если индекс не существует val patronList = mutableListOf(«Eli», «Mordoc», «Sophie»)
patronList.add(0, «Reggie»)
[Reggie, Eli, Mordoc, Sophie]
patronList.add(5, «Sophie»)
IndexOutOfBoundsException
addAll Добавляет все элементы из другой коллекции, если они того же типа val patronList = mutableListOf(«Eli», «Mordoc», «Sophie»)
patronList.addAll(listOf(«Reginald», «Alex»))
[Eli, Mordoc, Sophie, Reginald, Alex]
+= (оператор сложения с присваиванием) Добавляет элемент или коллекцию элементов в список mutableListOf(«Eli», «Mordoc», «Sophie») += «Reginald»
[Eli, Mordoc, Sophie, Reginald]
mutableListOf(«Eli», «Mordoc», «Sophie») += listOf(«Alex», «Shruti»)
[Eli, Mordoc, Sophie, Alex, Shruti]
-= (оператор вычитания с присваиванием) Удаляет элемент или коллекцию элементов из списка mutableListOf(«Eli», «Mordoc», «Sophie») -= «Eli»
[Mordoc, Sophie]
val patronList = mutableListOf(«Eli», «Mordoc», «Sophie»)
patronList -= listOf(«Eli», Mordoc»)
[Sophie]
clear Удаляет все элементы из списка mutableListOf(«Eli», «Mordoc», Sophie»).clear()
[]
removeIf Удаляет все элементы из списка, которые удовлетворяют условию в лямбде val patronList = mutableListOf(«Eli», «Mordoc», «Sophie»)
patronList.removeIf < it.contains("o") >
[Eli]

На следующем шаге мы рассмотрим итерацию .

Как добавить элемент в список kotlin

List представляет последовательный список элементов. При этом List представляет неизменяемую (immutable) коллекцию, которая в основном только обеспечивает получение элементов по позиции.

Интерфейс List расширяет интерфейс Collection , поэтому перенимает его возможности.

Для создания объекта List применяется метод listOf() :

var numbers = listOf(1, 2, 3, 4, 5) // объект List val people = listOf(«Tom», «Sam», «Kate», «Bob», «Alice») // объект List

Списки поддерживают перебор с помощью цикла for, кроме для списка по умолчанию задача реализация toString, которая выводит все элементы списка в удобочитаемом виде:

val people = listOf("Tom", "Sam", "Kate", "Bob", "Alice") for(person in people) println(person) println(people) // [Tom, Sam, Kate, Bob, Alice]
Методы списков

Кроме унаследованных методов класс List имеет ряд специфичных. Рассмотрим некоторые из них.

Для получения элемента по индексу можно применять метод get(index) , который возвращает элемент по индексу

val people = listOf("Tom", "Sam", "Kate", "Bob", "Alice") val first = people.get(0) val second = people.get(1) println(first) // Tom println(second) // Sam

Вместо метода get для обращения по индексу можно использовать квадратные скобки [] :

val people = listOf("Tom", "Sam", "Kate", "Bob", "Alice") val first = people[0] val second = people[1] println(first) // Tom println(second) // Sam

Однако, если индекс выходит за границы списка, то при использовании метода get() и квадратных скобок генерируется исключение. Чтобы избежать подобной ситуации, можно применять метод getOrNull() , который возвращает null, если индекс находится вне границ списка:

val people = listOf("Tom", "Sam", "Kate", "Bob", "Alice") val first = people.getOrNull(0) val tenth = people.getOrNull(10) println(first) // Tom println(tenth) // null

Либо в качестве альтернативы можно применять метод getOrElse() :

getOrElse(index: Int, defaultValue: (Int) -> T): T

Первый параметр представляет индекс, а второй параметр — функция, которая получает запрошенный индекс и возвращает значение, которое возвращается, если индекс выходит за границы списка:

val people = listOf("Tom", "Sam", "Kate", "Bob", "Alice") val first = people.getOrElse(0) val seventh = people.getOrElse(7) val tenth = people.getOrElse(10) println(first) // Tom println(seventh) // Invalid index 7 println(tenth) // Undefined
Получение части списка

Метод subList() возвращает часть списка и в качестве параметров принимает начальный и конечный индексы извлекаемых элементов:

subList(fromIndex: Int, toIndex: Int): List

Например, получим подсписок с 1 по 4 индексы:

val people = listOf("Tom", "Sam", "Kate", "Bob", "Alice", "Mike") val subPeople = people.subList(1, 4) println(subPeople) // [Sam, Kate, Bob]

Изменяемые списки

Изменяемые списки представлены интерфейсом MutableList . Он расширяет интерфейс List и позволяют добавлять и удалять элементы. Данный интерфейс реализуется классом ArrayList .

Для создания изменяемых списков можно использовать ряд методов:

  • arrayListOf() : создает объект ArrayList
  • mutableListOf() : создает объект MutableList

Создание изменяемых списков:

var numbers : ArrayList = arrayListOf(1, 2, 3, 4, 5) var numbers2: MutableList = mutableListOf(5, 6, 7)

Если необходимо добавлять или удалять элементы, то надо использовать методы MutableList:

  • add(index, element) : добавлят элемент по индексу
  • add(element) : добавляет элемент
  • addAll(collection) : добавляет коллекцию элементов
  • remove(element) : удаляет элемент
  • removeAt(index) : удаляет элемент по индексу
  • clear() : удаляет все элементы коллекции
fun main() < val numbers1 : ArrayList= arrayListOf(1, 2, 3, 4, 5) numbers1.add(4) numbers1.clear() val numbers2: MutableList = mutableListOf(5, 6, 7) numbers2.add(12) numbers2.add(0, 23) numbers2.addAll(0, listOf(-3, -2, -1)) numbers2.removeAt(0) numbers2.remove(5) for (n in numbers2) < println(n) >>

Урок 9: Списки в Kotlin, функции для работы с коллекциями

По определению коллекции – это группы с переменным количеством элементов (или нулем элементов). Объекты внутри как правило имеют единый тип. Коллекции называются коллекциями, потому что корнем их иерархии в языке является класс Collection. Позже, при изучении наследования это станет понятнее, пока не будем сильно углубляться.

Коллекции могут подразделяться на следующие типы:

  • List (список) – упорядоченный набор элементов, к ним можно обращаться по индексам. В списке могут встречаться дубликаты.
  • Set (множество) – коллекция уникальных элементов. То есть повторяющиеся элементы исключены. Порядок элементов может быть любым.
  • Map (словарь или ассоциативным список) – определенный набор пар. Пара содержит в себе ключ и значение. Зная ключ, можно обратиться к какому-нибудь значению. Ключи строго уникальны, а значения могут иметь дубликаты.

В этот раз подробнее остановимся на списках. Поведение напоминает работу с массивами, однако, есть существенные отличия в принципе работы. Вот основные из них:

  • Первое. Массив имеет строго фиксированный размер и не может уменьшаться или увеличиваться. Изменить размер массива можно только создав его копию с дополнительными или утраченными элементами. Списки же имеют методы add и remove для добавления/удаления элементов.
  • Второе. Массив предоставляется классом Array. List является интерфейсом и имеет разные реализации со своим функционалом.
  • Третье. Массивы оптимизированы для примитивов и меют отдельные типа IntArray, CharArray и т.д. Списки такой оптимизации не имеют.
  • Четвертое. Различается процесс сравнивания элементов друг с другом. В массивах сравниваются адреса ячеек в памяти, в списках же идет сравнение самого значения.

В целом хорошей практикой считается использовать списки вместо массивов везде, где это позволяет техническая реализация. Однако, с точки зрения производительности, массивы имеют над списками преимущество.

Создание списков в Котлин

Списки создаются с помощью функции listOf() из стандартной библиотеки Kotlin. Короткая запись создания целочисленного списка выглядит так:

val list = listOf(4, 4, 2)

Если принудительно проставить тип списка, получим List. Это базовый интерфейс для всех неизменяемых списков:

val list: List = listOf(4, 4, 2)

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

Изменяемые списки в Kotlin

В таких списках мы можем читать конкретное значение по индексу, а также пробегать циклом по всем значениям вместе. Но для того, чтобы создать изменяемый список, необходимо использовать функцию mutableListOf().

При данной инициализации тип переменной будет MutableList . Это второй базовый интерфейс для списков, на основе которого создаются изменяемые списки. Это List с возможностью добавления или удаления элементов:

val list3: MutableList = mutableListOf(1, 2, 3)

Функции для работы со списками

Теперь переходим к инструментарию по работе со списками. В уроке примеры будут представлены на примере целочисленного списка. А в практике, прилагаемой к уроку, будут оформлены задачи с применением различных типов с неким прикладным контекстом.

Еще раз создадим изменяемый список с некоторым количеством чисел.

val mutableList = mutableListOf(11, 15, 20, 12, 9, 14)

Сначала будем добавлять значения в список с помощью функции add(). Чтобы воспользоваться ей, необходимо написать переменную со списком и вызвать для нее этот метод с помощью обращения через точку.

Метод add() может принимать два набора параметров и в зависимости от этого, будет произведены разные действия.

Первый вариант – это всего один параметр, который является новым элементом, который нужно добавить в список. Этот элемент по умолчанию добавляется в конец списка. Результат в консоли:

val mutableList = mutableListOf(11, 15, 20, 12, 9, 14) println(mutableList) mutableList.add(42) println(mutableList)

Второй вариант – это когда метод add() принимает два параметра. На первом месте прописывается индекс – то место, куда должен быть вставлен элемент. Проставим ноль. На втором месте, через запятую, сам элемент. Функция, принимающая два параметра, выглядит так. Результат – число 42 добавлено в начало списка.

mutableList.add(0, 42) println(mutableList)

Кстати, во время занесения параметров в функцию можно вывести подсказку о том, какой именно параметр сейчас нужно ввести. Это окошко не всегда появляется, но оно вызовется с помощью сочетаний клавиш ctrl + P или cmd + P на маке. Курсор при этом должен находиться внутри скобок, где вводятся параметры метода.

Следующая функция проверит наличие элемента в списке и вернет Boolean значение true или false. По тому же принципу, как делали это с помощью in в уроке про диапазоны. Сейчас применим метод contains() к списку со значением 42 и получим true. Число 42 содержится в списке mutableList.

println(mutableList.contains(42))

Следующие функции часто пригождаются на практике при создании условий, когда нужно проверять: содержит ли список хоть какой элемент или же он пуст. Это методы isEmpty() и isNotEmpty(). Соответственно методы возвращают значения true или false.

println(mutableList.isEmpty()) println(mutableList.isNotEmpty())

Следующие функции помогут узнать индекс какого-либо элемента, если таковой присутствует в списке. Вызываем метод indexOf() с параметром 42 и получаем индекс 0. Все так. Если одинаковых значений в списке несколько, будет возвращено будет первое, которое встретится. Чтобы узнать последний индекс встречающегося элемента воспользуемся функцией lastIndexOf():

println(mutableList.indexOf(42)) println(mutableList.lastIndexOf(42))
Функция sort

Чтобы отсортировать список есть удобные функции. sort() отсортирует по возрастанию и sortDescending() по убыванию соответственно. Кроме того можно воспользоваться функцией reverse() для изменения порядка элементов в списке на обратный. После применения этих трех методов элементы будут расположены по возрастанию.

mutableList.forEach

Мы еще не изучали лямбды, но еще немного задержимся тут с точки зрения возможностей оформления. Автоматически задекларированную переменную it можно:

  • во-первых: явно прописать, вызвав контекстное меню и выбрав принудительную простановку сигнатуры лямбды,
  • во-вторых: задать произвольное имя переменной, которая будет использоваться внутри тела лямбды. Часто этот прием нужен для повышения читабельности кода. Для этого it меняем на произвольное название и теперь эту переменную можно использовать внутри.

Ок. Очень похоже на принцип работы цикла for, не правда ли? Способ с forEach() выглядит более аккуратным и без дополнительных переменных из-за его стилистики функционального программирования. Но есть нюансы, связанные с удобностью и производительностью для списков или интервалов. Просто перечислю результаты наблюдений из которых можно выбрать собственный способ исходя из ситуации:

  • Если используется интервал, следует использовать цикл for.
  • Если используется коллекция, типа списка, то следует использовать forEach.
  • Если есть необходимость использовать операторы continue или break, то удобнее всего делать это в цикле for.

Расскажу еще про пару популярных функций, обязательных к изучению.

Функция filter()

Основная функция для фильтрации коллекций – filter(). Условие задается фигурных скобках, где указывается логическое выражение, которое возвращает true или false. Так как функция не изменяет список, ее можно использовать и с изменяемыми списками.

Напишем этот пример. Отфильтрованный список будет помещен в новую переменную. В фигурных скобках пишем условие. it (элемент коллекции) равен, например, 42. Ниже сделаем вывод нового списка через forEach(). Таким образом каждый элемент будет проверяться на равенство с числом 42 и если оно верно, элемент запишется в новый список.

val mutableList2 = mutableList.filter < it == 42 >mutableList2.forEach
Функция map()

И еще одна полезная функция для коллекций – map(). Используется, если нам нужно взаимодействовать со всеми элементами. Конечно, все это можно сделать в цикле for, но так изящнее и соответствует стилю функционального программирования. Применив функцию map(), можно обойти все элементы списка и записать их преобразования в новый список. Для демонстрации подойдет любая простая операция. Умножим на 2 все элементы из списка mutableList2 – там сейчас содержится два числа 42. Сохраним результат преобразования в новый список mutableList3 и выведем его в консоль:

val mutableList3 = mutableList2.map < it * 2 >println(mutableList3)

Далее на практике написания приложений мы часто будем сталкиваться с функциями-расширениями и даже научимся создавать свои. Сейчас это все, что я хотел сказать по стандартным функциям для коллекций.

Для тех, кто собрался стать Android-разработчиком

Пошаговая
схема

Описание процесса обучения от основ Kotlin до Android-разработчика

Бесплатные
уроки

Авторский бесплатный курс по основам языка программирования Kotlin

Обучающий
бот

Тренажер и самоучитель по Котлин – бесплатные тесты и практика

Операции записи коллекций

Изменяемые коллекции поддерживают операции, изменяющие её содержимое, например, операции по добавлению и удалению элементов. В этом разделе описаны операции записи, доступные для всех реализаций MutableCollection . Более конкретные операции, доступные для List и Map , описаны в разделах List: специфичные операции и Map: специфичные операции.

Добавление элементов

Чтобы добавить один элемент в список или множество ( Set ), используйте функцию add() . Указанный объект будет добавлен в конец коллекции.

fun main() < val numbers = mutableListOf(1, 2, 3, 4) numbers.add(5) println(numbers) // [1, 2, 3, 4, 5] >

Функция addAll() добавляет все элементы из переданного в качестве аргумента объекта в список или множество. Аргументом может быть Iterable , Sequence , или Array . Типы объекта-получателя и аргумента могут быть разными, например, вы можете добавить все элементы из Set в List .

При вызове к списку addAll() добавляет новые элементы в том же порядке, в котором они находятся в коллекции-аргументе. Вы также можете передать addAll() позицию, в которую будет вставлен первый элемент из коллекции-аргумента. За ним последуют другие элементы из коллекции-аргумента, сдвигая элементы коллекции-получателя в конец.

fun main() < val numbers = mutableListOf(1, 2, 5, 6) numbers.addAll(arrayOf(7, 8)) println(numbers) // [1, 2, 5, 6, 7, 8] numbers.addAll(2, setOf(3, 4)) println(numbers) // [1, 2, 3, 4, 5, 6, 7, 8] >

Вы также можете добавлять элементы, используя in-place версию оператора plus — plusAssign ( += ). При применении к изменяемой коллекции += добавляет второй операнд (элемент или другую коллекцию) в конец коллекции.

fun main() < val numbers = mutableListOf("one", "two") numbers += "three" println(numbers) // [one, two, three] numbers += listOf("four", "five") println(numbers) // [one, two, three, four, five] >

Удаление элементов

Чтобы удалить элемент из изменяемой коллекции, используйте функцию remove() . Она принимает значение элемента в качестве аргумента и удаляет из коллекции одно вхождение этого значения.

fun main() < val numbers = mutableListOf(1, 2, 3, 4, 3) numbers.remove(3) // удаляет только первое значение `3` println(numbers) // [1, 2, 4, 3] numbers.remove(5) // ничего не удаляет println(numbers) // [1, 2, 4, 3] >

Для одновременного удаления нескольких элементов существуют следующие функции:

  • removeAll() — удаляет все элементы, присутствующие в коллекции-аргументе. В качестве альтернативы вы можете вызвать её с предикатом; в этом случае функция удаляет все элементы, для которых предикат возвращает true .
  • retainAll() — противоположность removeAll() : удаляет все элементы кроме тех, что находятся в коллекции-аргументе. При использовании с предикатом она оставляет только те элементы, которые ему соответствуют.
  • clear() — удаляет все элементы из списка, оставляя его пустым.
fun main() < val numbers = mutableListOf(1, 2, 3, 4) println(numbers) // [1, 2, 3, 4] numbers.retainAll < it >= 3 > println(numbers) // [3, 4] numbers.clear() println(numbers) // [] val numbersSet = mutableSetOf("one", "two", "three", "four") numbersSet.removeAll(setOf("one", "two")) println(numbersSet) // [three, four] > 

Еще один способ для удаления элементов из коллекции — оператор minusAssign ( -= ) — это in-place версия оператора minus . Второй аргумент может быть либо одним элементом, либо другой коллекцией. Если второй аргумент — это элемент, то оператор -= удалит первое вхождение этого элемента. Если же второй аргумент — это коллекция, то будут удалены все вхождения её элементов. Например, если список содержит повторяющиеся элементы, то они все будут удалены. Второй операнд может содержать элементы, которых нет в коллекции. Такие элементы не влияют на выполнение операции.

fun main() < val numbers = mutableListOf("one", "two", "three", "three", "four") numbers -= "three" println(numbers) // [one, two, three, four] numbers -= listOf("four", "five") //numbers -= listOf("four") // делает то же самое, что и выше println(numbers) // [one, two, three] >

Обновление элементов

Списки и ассоциативные списки также предоставляют операции для обновления элементов. Они описаны в разделах List: специфичные операции и Map: специфичные операции. Для Set обновление элементов не имеет смысла, поскольку фактически он удаляет элемент и добавляет другой.

© 2015—2023 Open Source Community

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *