The List class implements a circular, double-linked list of elements. The classification as “double-linked” means that each item in the list is linked to a previous and next item in the list. In a “circular” list, the successor of the last element is again the first element and the predecessor of the first element is the last element.
So one can run through these kind of lists ring-shaped both forward and backward. The elements in a chained list are of type Variant. This allows you to save everything in a chained list - from integer to float and string to objects.
The properties of a concatenated list are manageable in number and are shown in the following table:
|.Backwards||.List.backwards (ReadOnly)||Virtual object for enumeration backward|
|.Count||Integer (ReadOnly)||Number of elements of the List|
|.Current||Variant||Value of the current list element|
Table 18.104.22.168.1.1: Properties of the List class
A concatenated list always has a virtual root element that has no value. When a list object is instantiated, only the root element exists. It is its own predecessor and successor. In this case, the list is also called “empty”.
The root element is logically always between the first and the last element. However, you do not have access to this root element. It is ignored in all operations because it has no value, but the root element helps explain some methods.
|Clear ()||Remove all elements|
|Append (aElement)||add aElement to the beginning; after the root-element|
|Prepend (pElement)||add pElement to the end; before the root-element|
|Take (Optional iIndex)||Return and remove the current item. Optionally, an index can be transferred. If this is the case, the element with the specified index relative to the root element is returned and removed. Negative indices are allowed. They run backwards from the root element.|
|MoveFirst ()||Let the current element point to the first of the list|
|MoveLast ()||Let the current element point to the last of the list|
|MoveNext ()||Let the current element point to its successor|
|MovePrev ()||Synonym for MovePrevious ()|
|MovePrevious ()||Let the current element point to its predecessor|
|FindFirst (vValue)||Show the current element on the first find of a certain value in the list|
|FindLast (vValue)||Let the current element point to the last find of a value|
|FindNext (vValue)||Beginning with the successor of the current element, search for a value forward. This method can use the end of the list to switch back to the beginning and continue searching there. After each element has been examined once, the method terminates.|
|FindPrev ()||Synonym for FindPrevious (vValue)|
|FindPrevious (vValue)||Search backwards starting from the predecessor of the current element. This method can switch back to the end via the top of the list.|
Table 22.214.171.124.1: Methods of the List class
Note that the Find* () methods do not work well with the CPU data caches. The list elements are allocated separately, individually, in the memory of the computer and are then loosely connected to each other. Modern computers profit greatly from their fast cache caches, which store values according to heuristics, the spatiality of accesses, for example, in order to be able to access them very quickly at a later date. Thus, when a program accesses a memory block, the computer assumes that it will access another memory block nearby shortly afterwards. However, this is not the case for lists, since their elements can be distributed anywhere in the main memory. The iteration over many list elements (as when searching for values in the list) renders all data in the CPU data caches unusable, which in turn slows down the execution of the entire program.
In this context, it is also possible to access the ith element in a list with' hList[i]'. However, this is a very time-consuming operation, since all elements from the first to the third element have to be run through. Similar to List. Take (), the index' i' can be negative to count elements backwards from the end of the list.
A list is not meant for arbitrary access to the elements as you are used to from an array, but for sequential access patterns (MoveNext () and MovePrev ()). A list can be much more efficient than an array if you don't use it too often to find values or move through all the elements. The advantage of saving the elements of the list separately is that a very low and above all constant effort must be used if a list element is to be added or removed. However, if an element is added or removed from an array, the entire array may have to be copied to a different location, which is very time-consuming for large arrays.
Whether a list or an array is used depends on the intended access pattern and must be carefully considered beforehand. In case of doubt, you should always use an array. For all stress tests carried out, the Variant class was superior to the List class.