Перейти к содержимому

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

  • автор:

Как добавить элемент в список 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) >>

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

Изменяемые коллекции поддерживают операции, изменяющие её содержимое, например, операции по добавлению и удалению элементов. В этом разделе описаны операции записи, доступные для всех реализаций 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—2024 Open Source Community

Списки в Kotlin

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

Списки являются разновидностью коллекций – особой группы типов данных, или классов. Коллекции разных типов имеют во многом похожие функции-методы. Разные коллекции можно передавать в одни и те же функции. Коллекции связаны между собой наследованием и общими интерфейсами.

С другой стороны, в Kotlin списки (как и другие типы коллекций) делятся на неизменяемые и изменяемые. В неизменяемых нельзя менять количество элементов и изменять значение элементов. Это сделано с целью защиты данных. Если программист не планирует изменение списка при последующей разработке программы или ее выполнении, то, делая список неизменяемым, он его защищает от случайных изменений. Ведь val по отношению к списку не делает его неизменяемым. Как и в случае массивов val-список можно менять, нельзя только присвоить переменной другой список.

В Kotlin неизменяемый список обычно создается вызовом функции listOf() , которой передается список элементов. Также можно использовать конструктор класса List (по аналогии с массивами).

fun main() { val a = listOf("one", "two", 3) val b = listOf(1.2, 4.5, 3.2, 1.8) val c: ListDouble> c = b + listOf(4.3, 2.5) println(a) println(b) println(c) }

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

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

Получить отдельный элемент из списка можно по индексу, также как в случае с массивами. Например, выражение println(b[0]) выведет на экран первый элемент списка b .

Попытка присвоить новое значение какому-нибудь элементу неизменяемого списка вернет ошибку. Например, если b – это переменная типа List , то выражение b[0] = 1.1 недопустимо.

Другое дело – изменяемые списки. Такие списки в Kotlin относятся к типу MutableList . Слово «mutable» переводится как изменяемый.

fun main() { val b = mutableListOf(1.2, 4.5, 3.2, 1.8) println(b[0]) b[0] = 10.0 println(b[0]) for (i in b.indices) { b[i] += 0.3 } println(b) }

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

Выражение b.indices возвращает диапазон от 0 до индекса последнего элемента массива. Так в примере выше это будет диапазон 0..3.

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

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

fun main() { val b = mutableListOf(1.2, 4.5, 3.2, 1.8) println(b.size) b.add(10.0) b.add(0, 12.5) b.addAll(b.size / 2, listOf(-3.4, -8.9) ) println(b.size) for (i in b) { print("$i ") } }

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

Если в функцию add() передается только один аргумент, то он расценивается как значение и добавляется в конец списка. Если передается два аргумента, то первый считается индексом, а второй – значением, которое надо вставить в указанное место списка.

Для удаления элементов из списка используются методы removeAt() , который удаляет элемент по индексу, и remove() , удаляющий из списка указанное значение, а также ряд других.

fun main() { val b = mutableListOf(1.2, 4.5, 3.2, 1.8, 3.2) b.removeAt(0) b.remove(3.2) println(b) // вывод: [4.5, 1.8, 3.2] }

Если в списке есть повторы значения, то remove() удаляет только одно из них.

Практическая работа:

  1. Заполните список числами. Выведите на экран. Примените к списку функцию-метод shuffle() . Снова выведите список на экран. Что делает метод shuffle() ?
  2. Заполните список случайными числами, отсортируйте его с помощью метода sort() , удалите из списка минимальное и максимальное значения.

X Скрыть Наверх

Kotlin с нуля. Курс для начинающих

List: специфичные операции

List — самый популярный из всех типов коллекций в Kotlin. Он предоставляет мощный набор операций благодаря наличию доступа к элементам по индексу.

Получение элементов по индексу

Списки поддерживают все стандартные операции для получения элементов: elementAt() , first() , last() и другие, перечисленные в разделе Выбор одного элемента. Списки характерны тем, что предоставляют доступ к элементам по индексу, поэтому именно по индексу проще всего получить необходимый элемент. Это осуществляется с помощью функции get() , которая принимает индекс в качестве аргумента. Также можно использовать сокращённый синтаксис — [index] .

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

  • getOrElse() — позволяет вам предоставить функцию для вычисления значения по умолчанию. Если по указанному индексу элемент не был найден, то будет возвращён результат вычисления этой функции.
  • getOrNull() — возвращает null в качестве значения по умолчанию.
fun main() < val numbers = listOf(1, 2, 3, 4) println(numbers.get(0)) // 1 println(numbers[0]) // 1 //numbers.get(5) // exception! println(numbers.getOrNull(5)) // null println(numbers.getOrElse(5, )) // 5 > 

Получение части списка

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

fun main() < val numbers = (0..13).toList() println(numbers.subList(3, 6)) // [3, 4, 5] >

Поиск позиции элемента

Линейный поиск

В любом списке вы можете найти позицию элемента с помощью функций indexOf() и lastIndexOf() . Они возвращают первую и последнюю позицию элемента, равного заданному аргументу. Если таких элементов нет, то обе функции возвращают -1 .

fun main() < val numbers = listOf(1, 2, 3, 4, 2, 5) println(numbers.indexOf(2)) // 1 println(numbers.lastIndexOf(2)) // 4 >

Также существуют две функции, которые принимают предикат и ищут соответствующие ему элементы:

  • indexOfFirst() — возвращает индекс первого элемента, соответствующего заданному предикату или -1 , если таких элементов нет.
  • indexOfLast() — возвращает индекс последнего элемента, соответствующего заданному предикату или -1 , если таких элементов нет.
fun main() < val numbers = mutableListOf(1, 2, 3, 4) println(numbers.indexOfFirst < it >2>) // 2 println(numbers.indexOfLast < it % 2 == 1>) // 2 > 

Бинарный поиск в отсортированном списке

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

Чтобы найти элемент в отсортированном списке, вызовите функцию binarySearch() , передав ей искомое значение в качестве аргумента. Если такой элемент существует, функция вернёт его индекс; в противном случае она вернёт (-insertionPoint — 1) , где insertionPoint — это индекс, в который этот элемент должен быть вставлен, чтобы список оставался отсортированным. Если существует более одного элемента с указанным значением, функция может вернуть любой из их индексов.

Вы также можете указать диапазон индексов для поиска: в этом случае функция выполняет поиск только между двумя предоставленными индексами.

fun main() < val numbers = mutableListOf("one", "two", "three", "four") numbers.sort() println(numbers) // [four, one, three, two] println(numbers.binarySearch("two")) // 3 println(numbers.binarySearch("z")) // -5 println(numbers.binarySearch("two", 0, 2)) // -3 >
Бинарный поиск с Comparator

Если элементы списка не являются Comparable , вы должны предоставить Comparator , который будет использован в бинарном поиске. Список должен быть отсортирован по возрастанию в соответствии с этим Comparator . Давайте посмотрим на пример:

data class Product(val name: String, val price: Double) fun main() < val productList = listOf( Product("WebStorm", 49.0), Product("AppCode", 99.0), Product("DotTrace", 129.0), Product("ReSharper", 149.0)) println( productList .binarySearch(Product("AppCode", 99.0), compareBy < it.price >.thenBy < it.name >) ) // 1 > 

В данном примере есть:

  • список из экземпляров класса Product , которые не являются Comparable .
  • Comparator , который определяет порядок: продукт p1 предшествует продукту p2 , если цена p1 меньше, чем цена p2 . Итак, имея список, отсортированный по возрастанию в соответствии с этим порядком, мы используем binarySearch() , чтобы найти индекс указанного Product .

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

fun main() < val colors = listOf("Blue", "green", "ORANGE", "Red", "yellow") println(colors.binarySearch("RED", String.CASE_INSENSITIVE_ORDER)) // 3 >
Бинарный поиск с функцией сравнения

Бинарный поиск с функцией сравнения (comparison) позволяет находить элементы без предоставления явных значений для поиска. Вместо этого он принимает элементы функции сравнения, преобразованные в Int , и ищет элемент, для которого функция возвращает ноль. Список должен быть отсортирован по возрастанию в соответствии с порядком, предоставленным функцией; другими словами, возвращаемые функцией значения должны расти от одного элемента списка к следующему.

import kotlin.math.sign data class Product(val name: String, val price: Double) fun priceComparison(product: Product, price: Double) = sign(product.price - price).toInt() fun main() < val productList = listOf( Product("WebStorm", 49.0), Product("AppCode", 99.0), Product("DotTrace", 129.0), Product("ReSharper", 149.0)) println(productList.binarySearch < priceComparison(it, 99.0) >) // 1 > 

Бинарный поиск как с компаратором, так и с функцией сравнения может выполняться для диапазонов списков.

Операции записи

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

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

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

fun main() < val numbers = mutableListOf("one", "five", "six") numbers.add(1, "two") numbers.addAll(2, listOf("three", "four")) println(numbers) // [one, two, three, four, five, six] >

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

Списки также предоставляют функцию для замены элемента в заданной позиции — set() , у которой есть операторная форма [] . set() не меняет индексы других элементов.

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

Функция fill() просто заменяет все элементы коллекции на указанное значение.

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

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

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

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

Сортировка

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

Подобные функции сортировки названы похожими именами, но без суффикса ed/d :

  • sort* вместо sorted* в именах всех функций сортировки: sort() , sortDescending() , sortBy() и так далее.
  • shuffle() вместо shuffled() .
  • reverse() вместо reversed() .

Функция asReversed() , вызываемая к изменяемому списку, возвращает другой изменяемый список, который является перевёрнутым представлением исходного списка. Вместе с изменением этого представления вы изменяете и исходный список.

В следующем примере показаны функции сортировки для изменяемых списков:

fun main() < val numbers = mutableListOf("one", "two", "three", "four") numbers.sort() println("Sort into ascending: $numbers") // Sort into ascending: [four, one, three, two] numbers.sortDescending() println("Sort into descending: $numbers") // Sort into descending: [two, three, one, four] numbers.sortBy < it.length >println("Sort into ascending by length: $numbers") // Sort into ascending by length: [two, one, four, three] numbers.sortByDescending < it.last() >println("Sort into descending by the last letter: $numbers") // Sort into descending by the last letter: [four, two, one, three] numbers.sortWith(compareBy < it.length >.thenBy < it >) println("Sort by Comparator: $numbers") // Sort by Comparator: [one, two, four, three] numbers.shuffle() println("Shuffle: $numbers") // Shuffle: [one, two, three, four] numbers.reverse() println("Reverse: $numbers") // Reverse: [four, three, two, one] > 

© 2015—2024 Open Source Community

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

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