List.Count Свойство
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Получает число элементов, содержащихся в интерфейсе List .
public: property int Count < int get(); >;
public int Count
member this.Count : int
Public ReadOnly Property Count As Integer
Значение свойства
Число элементов, содержащихся в интерфейсе List .
Реализации
Примеры
В следующем примере показано, как проверить емкость и количество объектов , List содержащих простой бизнес-объект, и демонстрируется использование TrimExcess метода для удаления дополнительной емкости.
using System; using System.Collections.Generic; // Simple business object. A PartId is used to identify a part // but the part name be different for the same Id. public class Part : IEquatable < public string PartName < get; set; >public int PartId < get; set; >public override string ToString() < return "ID: " + PartId + " Name: " + PartName; >public override bool Equals(object obj) < if (obj == null) return false; Part objAsPart = obj as Part; if (objAsPart == null) return false; else return Equals(objAsPart); >public override int GetHashCode() < return base.GetHashCode(); >public bool Equals(Part other) < if (other == null) return false; return (this.PartId.Equals(other.PartId)); >// Should also override == and != operators. > public class Example < public static void Main() < Listparts = new List(); Console.WriteLine("\nCapacity: ", parts.Capacity); parts.Add(new Part() < PartName = "crank arm", PartId = 1234 >); parts.Add(new Part() < PartName = "chain ring", PartId = 1334 >); parts.Add(new Part() < PartName = "seat", PartId = 1434 >); parts.Add(new Part() < PartName = "cassette", PartId = 1534 >); parts.Add(new Part() < PartName = "shift lever", PartId = 1634 >); ; Console.WriteLine(); foreach (Part aPart in parts) < Console.WriteLine(aPart); >Console.WriteLine("\nCapacity: ", parts.Capacity); Console.WriteLine("Count: ", parts.Count); parts.TrimExcess(); Console.WriteLine("\nTrimExcess()"); Console.WriteLine("Capacity: ", parts.Capacity); Console.WriteLine("Count: ", parts.Count); parts.Clear(); Console.WriteLine("\nClear()"); Console.WriteLine("Capacity: ", parts.Capacity); Console.WriteLine("Count: ", parts.Count); > /* This code example produces the following output. Capacity: 0 ID: 1234 Name: crank arm ID: 1334 Name: chain ring ID: 1434 Name: seat ID: 1534 Name: cassette ID: 1634 Name: shift lever Capacity: 8 Count: 5 TrimExcess() Capacity: 5 Count: 5 Clear() Capacity: 5 Count: 0 */ >
Imports System.Collections.Generic ' Simple business object. A PartId is used to identify a part ' but the part name can change. Public Class Part Implements IEquatable(Of Part) Public Property PartName() As String Get Return m_PartName End Get Set(value As String) m_PartName = Value End Set End Property Private m_PartName As String Public Property PartId() As Integer Get Return m_PartId End Get Set(value As Integer) m_PartId = Value End Set End Property Private m_PartId As Integer Public Overrides Function ToString() As String Return "ID: " & PartId & " Name: " & PartName End Function Public Overrides Function Equals(obj As Object) As Boolean If obj Is Nothing Then Return False End If Dim objAsPart As Part = TryCast(obj, Part) If objAsPart Is Nothing Then Return False Else Return Equals(objAsPart) End If End Function Public Overrides Function GetHashCode() As Integer Return MyBase.GetHashCode() End Function Public Overloads Function Equals(other As Part) As Boolean Implements IEquatable(Of Part).Equals If other Is Nothing Then Return False End If Return (Me.PartId.Equals(other.PartId)) End Function ' Should also override == and != operators. End Class Public Class Example Public Shared Sub Main() Dim parts As New List(Of Part)() Console.WriteLine(vbLf & "Capacity: ", parts.Capacity) ' Add parts to the list. parts.Add(New Part() With < _ .PartName = "crank arm", _ .PartId = 1234 _ >) parts.Add(New Part() With < _ .PartName = "chain ring", _ .PartId = 1334 _ >) parts.Add(New Part() With < _ .PartName = "regular seat", _ .PartId = 1434 _ >) parts.Add(New Part() With < _ .PartName = "banana seat", _ .PartId = 1444 _ >) parts.Add(New Part() With < _ .PartName = "cassette", _ .PartId = 1534 _ >) parts.Add(New Part() With < _ .PartName = "shift lever", _ .PartId = 1634 _ >) Console.WriteLine() For Each aPart As Part In parts Console.WriteLine(aPart) Next Console.WriteLine(vbLf & "Capacity: ", parts.Capacity) Console.WriteLine("Count: ", parts.Count) parts.TrimExcess() Console.WriteLine(vbLf & "TrimExcess()") Console.WriteLine("Capacity: ", parts.Capacity) Console.WriteLine("Count: ", parts.Count) parts.Clear() Console.WriteLine(vbLf & "Clear()") Console.WriteLine("Capacity: ", parts.Capacity) Console.WriteLine("Count: ", parts.Count) End Sub ' ' This code example produces the following output. ' Capacity: 0 ' ' ID: 1234 Name: crank arm ' ID: 1334 Name: chain ring ' ID: 1434 Name: seat ' ID: 1534 Name: cassette ' ID: 1634 Name: shift lever ' ' Capacity: 8 ' Count: 6 ' ' TrimExcess() ' Capacity: 6 ' Count: 6 ' ' Clear() ' Capacity: 6 ' Count: 0 ' End Class
В следующем примере показано значение свойства в Count различных точках жизни списка. После создания и заполнения списка и отображения Capacity его элементов отображаются свойства и Count . Эти свойства снова отображаются после TrimExcess вызова метода и после очистки содержимого списка.
using namespace System; using namespace System::Collections::Generic; void main() < List^ dinosaurs = gcnew List(); Console::WriteLine("\nCapacity: ", dinosaurs->Capacity); dinosaurs->Add("Tyrannosaurus"); dinosaurs->Add("Amargasaurus"); dinosaurs->Add("Mamenchisaurus"); dinosaurs->Add("Deinonychus"); dinosaurs->Add("Compsognathus"); Console::WriteLine(); for each(String^ dinosaur in dinosaurs ) < Console::WriteLine(dinosaur); >Console::WriteLine("\nCapacity: ", dinosaurs->Capacity); Console::WriteLine("Count: ", dinosaurs->Count); Console::WriteLine("\nContains(\"Deinonychus\"): ", dinosaurs->Contains("Deinonychus")); Console::WriteLine("\nInsert(2, \"Compsognathus\")"); dinosaurs->Insert(2, "Compsognathus"); Console::WriteLine(); for each(String^ dinosaur in dinosaurs ) < Console::WriteLine(dinosaur); >Console::WriteLine("\ndinosaurs[3]: ", dinosaurs[3]); Console::WriteLine("\nRemove(\"Compsognathus\")"); dinosaurs->Remove("Compsognathus"); Console::WriteLine(); for each(String^ dinosaur in dinosaurs ) < Console::WriteLine(dinosaur); >dinosaurs->TrimExcess(); Console::WriteLine("\nTrimExcess()"); Console::WriteLine("Capacity: ", dinosaurs->Capacity); Console::WriteLine("Count: ", dinosaurs->Count); dinosaurs->Clear(); Console::WriteLine("\nClear()"); Console::WriteLine("Capacity: ", dinosaurs->Capacity); Console::WriteLine("Count: ", dinosaurs->Count); > /* This code example produces the following output: Capacity: 0 Tyrannosaurus Amargasaurus Mamenchisaurus Deinonychus Compsognathus Capacity: 8 Count: 5 Contains("Deinonychus"): True Insert(2, "Compsognathus") Tyrannosaurus Amargasaurus Compsognathus Mamenchisaurus Deinonychus Compsognathus dinosaurs[3]: Mamenchisaurus Remove("Compsognathus") Tyrannosaurus Amargasaurus Mamenchisaurus Deinonychus Compsognathus TrimExcess() Capacity: 5 Count: 5 Clear() Capacity: 5 Count: 0 */
List dinosaurs = new List(); Console.WriteLine("\nCapacity: ", dinosaurs.Capacity); dinosaurs.Add("Tyrannosaurus"); dinosaurs.Add("Amargasaurus"); dinosaurs.Add("Mamenchisaurus"); dinosaurs.Add("Deinonychus"); dinosaurs.Add("Compsognathus"); Console.WriteLine(); foreach(string dinosaur in dinosaurs) < Console.WriteLine(dinosaur); >Console.WriteLine("\nCapacity: ", dinosaurs.Capacity); Console.WriteLine("Count: ", dinosaurs.Count); Console.WriteLine("\nContains(\"Deinonychus\"): ", dinosaurs.Contains("Deinonychus")); Console.WriteLine("\nInsert(2, \"Compsognathus\")"); dinosaurs.Insert(2, "Compsognathus"); Console.WriteLine(); foreach(string dinosaur in dinosaurs) < Console.WriteLine(dinosaur); >// Shows accessing the list using the Item property. Console.WriteLine("\ndinosaurs[3]: ", dinosaurs[3]); Console.WriteLine("\nRemove(\"Compsognathus\")"); dinosaurs.Remove("Compsognathus"); Console.WriteLine(); foreach(string dinosaur in dinosaurs) < Console.WriteLine(dinosaur); >dinosaurs.TrimExcess(); Console.WriteLine("\nTrimExcess()"); Console.WriteLine("Capacity: ", dinosaurs.Capacity); Console.WriteLine("Count: ", dinosaurs.Count); dinosaurs.Clear(); Console.WriteLine("\nClear()"); Console.WriteLine("Capacity: ", dinosaurs.Capacity); Console.WriteLine("Count: ", dinosaurs.Count); /* This code example produces the following output: Capacity: 0 Tyrannosaurus Amargasaurus Mamenchisaurus Deinonychus Compsognathus Capacity: 8 Count: 5 Contains("Deinonychus"): True Insert(2, "Compsognathus") Tyrannosaurus Amargasaurus Compsognathus Mamenchisaurus Deinonychus Compsognathus dinosaurs[3]: Mamenchisaurus Remove("Compsognathus") Tyrannosaurus Amargasaurus Mamenchisaurus Deinonychus Compsognathus TrimExcess() Capacity: 5 Count: 5 Clear() Capacity: 5 Count: 0 */
Imports System.Collections.Generic Public Class Example Public Shared Sub Main() Dim dinosaurs As New List(Of String) Console.WriteLine(vbLf & "Capacity: ", dinosaurs.Capacity) dinosaurs.Add("Tyrannosaurus") dinosaurs.Add("Amargasaurus") dinosaurs.Add("Mamenchisaurus") dinosaurs.Add("Deinonychus") dinosaurs.Add("Compsognathus") Console.WriteLine() For Each dinosaur As String In dinosaurs Console.WriteLine(dinosaur) Next Console.WriteLine(vbLf & "Capacity: ", dinosaurs.Capacity) Console.WriteLine("Count: ", dinosaurs.Count) Console.WriteLine(vbLf & "Contains(""Deinonychus""): ", _ dinosaurs.Contains("Deinonychus")) Console.WriteLine(vbLf & "Insert(2, ""Compsognathus"")") dinosaurs.Insert(2, "Compsognathus") Console.WriteLine() For Each dinosaur As String In dinosaurs Console.WriteLine(dinosaur) Next ' Shows how to access the list using the Item property. Console.WriteLine(vbLf & "dinosaurs(3): ", dinosaurs(3)) Console.WriteLine(vbLf & "Remove(""Compsognathus"")") dinosaurs.Remove("Compsognathus") Console.WriteLine() For Each dinosaur As String In dinosaurs Console.WriteLine(dinosaur) Next dinosaurs.TrimExcess() Console.WriteLine(vbLf & "TrimExcess()") Console.WriteLine("Capacity: ", dinosaurs.Capacity) Console.WriteLine("Count: ", dinosaurs.Count) dinosaurs.Clear() Console.WriteLine(vbLf & "Clear()") Console.WriteLine("Capacity: ", dinosaurs.Capacity) Console.WriteLine("Count: ", dinosaurs.Count) End Sub End Class ' This code example produces the following output: ' 'Capacity: 0 ' 'Tyrannosaurus 'Amargasaurus 'Mamenchisaurus 'Deinonychus 'Compsognathus ' 'Capacity: 8 'Count: 5 ' 'Contains("Deinonychus"): True ' 'Insert(2, "Compsognathus") ' 'Tyrannosaurus 'Amargasaurus 'Compsognathus 'Mamenchisaurus 'Deinonychus 'Compsognathus ' 'dinosaurs(3): Mamenchisaurus ' 'Remove("Compsognathus") ' 'Tyrannosaurus 'Amargasaurus 'Mamenchisaurus 'Deinonychus 'Compsognathus ' 'TrimExcess() 'Capacity: 5 'Count: 5 ' 'Clear() 'Capacity: 5 'Count: 0
[] let main argv = // We refer to System.Collections.Generic.List by its type // abbreviation ResizeArray to avoid conflict with the List module. // Note: In F# code, F# linked lists are usually preferred over // ResizeArray when an extendable collection is required. let dinosaurs = ResizeArray() // Write out the dinosaurs in the ResizeArray. let printDinosaurs() = printfn "" dinosaurs |> Seq.iter (fun p -> printfn "%O" p) printfn "\nCapacity: %i" dinosaurs.Capacity dinosaurs.Add("Tyrannosaurus") dinosaurs.Add("Amargasaurus") dinosaurs.Add("Mamenchisaurus") dinosaurs.Add("Deinonychus") dinosaurs.Add("Compsognathus") printDinosaurs() printfn "\nCapacity: %i" dinosaurs.Capacity printfn "Count: %i" dinosaurs.Count printfn "\nContains(\"Deinonychus\"): %b" (dinosaurs.Contains("Deinonychus")) printfn "\nInsert(2, \"Compsognathus\")" dinosaurs.Insert(2, "Compsognathus") printDinosaurs() // Shows accessing the list using the Item property. printfn "\ndinosaurs[3]: %s" dinosaurs.[3] printfn "\nRemove(\"Compsognathus\")" dinosaurs.Remove("Compsognathus") |> ignore printDinosaurs() dinosaurs.TrimExcess() printfn "\nTrimExcess()" printfn "Capacity: %i" dinosaurs.Capacity printfn "Count: %i" dinosaurs.Count dinosaurs.Clear() printfn "\nClear()" printfn "Capacity: %i" dinosaurs.Capacity printfn "Count: %i" dinosaurs.Count 0 // return an integer exit code (* This code example produces the following output: Capacity: 0 Tyrannosaurus Amargasaurus Mamenchisaurus Deinonychus Compsognathus Capacity: 8 Count: 5 Contains("Deinonychus"): true Insert(2, "Compsognathus") Tyrannosaurus Amargasaurus Compsognathus Mamenchisaurus Deinonychus Compsognathus dinosaurs[3]: Mamenchisaurus Remove("Compsognathus") Tyrannosaurus Amargasaurus Mamenchisaurus Deinonychus Compsognathus TrimExcess() Capacity: 5 Count: 5 Clear() Capacity: 5 Count: 0 *)
Комментарии
Capacity — это количество элементов, которое List может храниться до необходимости изменения размера. Count — это количество элементов, которые фактически находятся в List .
Capacity значение всегда больше или равно Count. При Count превышении при добавлении Capacity элементов емкость увеличивается путем автоматического перераспределения внутреннего массива перед копированием старых элементов и добавлением новых элементов.
Получение значения данного свойства является операцией порядка сложности O(1).
Как узнать размер односвязного списка, указателей, элементов списка через sizeof()
Обычно указатель в 64 битной версии занимает 8 байт Но хочу удостоверится в этом, ну и вообще понять как работает sizeof() Так-же, вопрос в размере элемента этого списка. Можно проверить так? printf_s(«%lu\n», sizeof(l->next->elem)); Если это так, то следующий вопрос, как проверить размер всех элементов списка? printf_s(«%lu\n», sizeof(l->elem)); Но компилятор мне говорит, что там 4 байта, но элементов три. Должно же быть 12? или я где-то тупой:?)
Отслеживать
219k 15 15 золотых знаков 119 119 серебряных знаков 230 230 бронзовых знаков
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
Связный список — Основы алгоритмов и структур данных
В этом уроке мы начнем изучать структуры данных и связанные с ними алгоритмы. Чтобы разобраться во всех деталях, мы рассмотрим два примера из реальной жизни — склад и библиотеку.
На складе кладовщик записывает все пришедшие товары в специальный журнал. Рабочий день кладовщика состоит из приема и выдачи товаров. Очень важно записывать прием и выдачу как можно быстрее, поэтому кладовщик просто пишет все операции друг за другом, подряд.
Из-за специфики работы склада кладовщик составляет базу данных, в которой:
- Сложно найти товар на складе
- Просто сделать новую запись в журнале
Ситуация в библиотеке совсем другая. Основная работа библиотекаря — поиск книг по фамилии автора, по названию книги или по тематике. Для быстрого поиска книг библиотекари используют картотеку. Для каждой книги заводятся несколько карточек и размещаются в разных ящиках. В одном они упорядочены по фамилии автора, в другом — по названию. Благодаря порядку карточки ищутся очень быстро.
Так в библиотеке составляется база данных с совсем другими свойствами:
- Просто найти книгу в библиотеке
- Сложно сделать новую запись в картотеке
И на складе, и в библиотеке нам приходится записывать и искать похожую информацию, однако скорость записи и поиска получается разная:
Журнал
Картотека
Как видите, мы не можем выбрать один универсальный способ записи, который подойдет для всех случаев. Для склада больше подходит Журнал, а для библиотеки — Картотека.
В обоих примерах своя структура данных — то есть способ хранения данных в памяти компьютера. Для каждой структуры существует набор основных операций — добавление, поиск, удаление. Из-за особенностей структуры, добавление и поиск могут быть быстрыми или медленными.
Программисты изучают основные структуры данных и запоминают скорость основных операций. Это помогает им выбирать самые подходящие структуры для решения задач пользователя. В этом уроке мы познакомимся со связным списком и сравним его с массивом.
Как устроен массив
Чтобы освоиться с понятием структуры данных и ее операциями, давайте исследуем структуру, которая нам хорошо известна — массив.
В JavaScript все данные относятся к примитивным или ссылочных типам. Числа и булевы значения хранятся непосредственно в переменных:
let a = 1; let b = false;