Collections
Set de objetos homogéneos, en memoria, administrados a través de una clase contenedora. Los Collections
son parecidas a los arreglos, pero sus elementos son usualmente de tipo Object y tiene métodos para
insertar y eliminar. Tiene formas de iterar entre los elementos a través de un enumerador, utilizando la
sentencia For each…
Clase Interfaz y Descripción Cuándo Usarlo
Namespace
0. Arrays (Arreglos) La herramienta más eficiente para
colecciones indexados, de tamaño
fijo. Loa arreglos unidimensionales
son manejados por instrucciones
MSIL que los procesan con mayor
eficiencia.
1. Queue (Cola) Icollection Una colección de Para escenarios en donde recibe
System.Collections objetos first-in, first- datos y necesita procesarlos un
out (FIFO) (primero elemento a la vez, dependiendo del
que entra, primero que orden de llegada.
sale)
2. Stack (Pila) Icollection Una colección de
System.Collections objetos last-in, first-out
(LIFO) (último que
entra, primero que
sale)
3. ArrayList Ilist Una lista de objetos Una alternativa análogo a un
System.Collections weakly typed (tipeado arreglo de tamaño fijo (array),
débilmente, no indica pero que puede crecer (growable),
el tipo) y que puede almacenar cualquier
tipo de objetos. Muchas de las
colecciones utilizan un ArrayList
internamente, y simplemente crean
una interfaz más amigable
alrededor de ella.
4. StringCollection Ilist Una lista de cadenas Una mejor opción que el ArrayList
System.Collections (strings) strongly typed para un arreglo de cadenas
.Specialized (fuertemente tipeado – (strings) de tamaño dinámico,
deben ser cadenas) debido a que provee una interfaz
fuertemente tipeada (strongly
typed).
5. Hashtable Idictionary Una colección de Buenas opciones cuando necesite
System.Collections parejas llave/valor acceso basado en llaves. Utilice
(key/value) ListDictionary para manejar un
organizadas por el número pequeño de items (20 o
código hash de la llave menos) y opte por Hashtable para
mayores cantidades.
6. ListDictionary Idictionary Lista encadenada en
System.Collections una dirección (singly
.Specialized linked), diseñada para
colecciones que
contienen 10 o menos
items.
1
Clase Interfaz y Descripción Cuándo Usarlo
Namespace
7. HybridDictionary Una clase wrapper (envuelve a
otra) que comienza como un
ListDictionary y automáticamente
cambia a Hashtable cuando el
tamaño crece más allá del límite
crítico (Usado por algunas clases
internas de ASP.NET)
8. StringDictionary Idictionary Un hashtable con la Una mejor opción que Hashtables
System.Collections llave strongly typed cuando su colección sólo contiene
.Specialized como cadena (String) cadenas (strings).
en vez de Object
9. SortedList Idictionary Una colección ordenada Un híbrido entre Hashtable y un
System.Collections de parejas llave/valor arreglo. Se comporta como un
(key/value) Hashtable cuando accesa un
elemento por llave (key), y hace
como un array si utiliza un índice.
Utilícelo sólo si necesita mantener
el ordenamiento.
10. Idictionary Una colección ordenada Es la colección más lenta. Utilizarla
NameValueCollection System.Collections de llaves (keys) tipo sólo si desea proveer acceso a los
.Specialized cadena (string) y datos tanto por índice como por
valores tipo string llave (key).
asociados, que puede
ser accesado ya sea
por llave o a través de
un índice
Las Interfaces son las siguientes:
Interfaz Descripción
IEnumerable Define métodos para soportar una iteración simple sobre
una colección
ICollection Agrega capacidades de tamaño (size), copia y
sincronización a colecciones enumerables
IList Define una colección de objetos que pueden accesarse
individualmente por índice
IDictionary Representa una colección de parejas llave/valor
(key/value)
2
Una colección es una lista enumerable (se puede hacer que vaya ciclando por todos sus items), y por ello
implementa una interfaz IEnumerable, la cual expone un objeto enumerator, habilitando los “for each…”.
También implementan interfaces adicionales como ICollection, que agrega la propiedad Count y el método
CopyTo para copiar a un arreglo.
La interfaz IList extiende ICollection con métodos como Add y Remove, además de la propiedad Item para
accesos por índice, parecidos a los de un arreglo.
La interfaz IDictionary define una API para representar una colección de parejas llave/valor (key/value).
IDictionary expone métodos similares a IList, pero con diferente firma (signature), conteniendo
propiedades como Keys y Values.
Las clases de las colecciones no son Thread Safe, eso significa que si varios procesos lo van a accesar
simultáneamente, hay que sincronizarlos para que puedan obtener el valor correcto.
Ejemplo de Uso del Stack (LIFO – Last In, First Out)
Supongamos esta aplicación que registra mercadería que colocaremos en un contenedor. Primero metemos
la caja “1”, luego la “2” y por último la “3). Al sacarla del contenedor, lo haremos en el orden inverso:
primero la caja “3”, luego la “2” y por último la “1”.
frmStack
txtID txtContenido
lblValues
btnPush
btnPop
btnPeek
lblN
Public Class frmStack
Inherits System.Windows.Forms.Form
(Windows Forms Designer generated code)
#Region "Declarations"
Declara un Stack Collection
Private stkCajas As _
New System.Collections.Stack
Private Class clsCaja Clase de ejemplo que
almacenaremos
Public ID As Int32 en el Stack: una Caja con dos
Public Contenido As String propiedades: ID y Contenido
Public Sub New()
End Sub
Public Sub New( _
ByVal newID As Int32, _
ByVal newContenido As String)
ID = newID
Contenido = newContenido
End Sub
End Class
#End Region
3
Código del PUSH
#Region "Push"
Private Sub btnPush_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnPush.Click
Dim Caja As New clsCaja( _
Val(Me.txtID.Text), Me.txtContenido.Text)
Me.txtID.Text = String.Empty
Me.txtContenido.Text = String.Empty
PUSH recibe un objeto y lo
stkCajas.Push(Caja) mete en el stack.
ShowValues()
Me.txtID.Focus()
End Sub
#End Region
Código del POP y PEEK
#Region "Pop & Peek"
Private Sub btnPopPeek_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnPop.Click, btnPeek.Click
If stkCajas.Count > 0 Then
Dim Caja As New clsCaja
If sender Is btnPop Then POP saca el último elemento
Caja = stkCajas.Pop() del stack, y me lo devuelve
Else
Caja = stkCajas.Peek PEEK permite ver el último
End If elemento, sin sacarlo del stack
Me.txtID.Text = Caja.ID
Me.txtContenido.Text = Caja.Contenido
ShowValues()
Else
Me.txtID.Text = String.Empty
Me.txtContenido.Text = String.Empty
End If
End Sub
#End Region
Código para mostrar
#Region "Show Values" contenido del Stack
Enumerando con For each…
Private Sub ShowValues()
Me.lblN.Text = stkCajas.Count Propiedad Count indica cuántos
elementos tiene el stack
Dim sStkOutput As _
New System.Text.StringBuilder For Each itera (enumera) los
For Each caja As clsCaja In stkCajas elementos del stack
sStkOutput.Append( _
"ID: " & caja.ID.ToString & _
" Contenido: " & caja.Contenido & _
vbCrLf)
Next
Me.lblValues.Text = sStkOutput.ToString
End Sub
#End Region
End Class
4
Corriendo el programa de Stack
Haremos Push de varios objetos (cajas, en nuestro ejemplo), y luego Peek para ver el contenido del último
objeto agregado, y Pop para sacar el último objeto agregado.
Cada Push va
empujando los objetos
Peek lee el último objeto,
sin sacarlo del Stack
En cambio, Pop lee el último
objeto y lo saca del Stack
Otro Pop saca el penúltimo
objeto ingresado, etc…
5
Ejemplo de un Queue (FIFO – First In, First Out)
frmQueue
txtID txtContenido
lblValues
btnEnqueue
btnDequeue
btnPeek
lblN
Public Class frmQueue
Inherits System.Windows.Forms.Form
(Windows Forms Designer generated code)
#Region "Declarations"
Declara un Queue Collection
Private queueCajas As _
New System.Collections.Queue
Private Class clsCaja Clase que se almacenará
en el Queue
Public ID As Int32
Public Contenido As String
Public Sub New()
End Sub
Public Sub New( _
ByVal newID As Int32, _
ByVal newContenido As String)
ID = newID
Contenido = newContenido
End Sub
End Class
#End Region
#Region "enQueue" Encolar con enQueue
Private Sub btnEnQueue_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnEnQueue.Click
Dim Caja As New clsCaja( _
Val(Me.txtID.Text), Me.txtContenido.Text)
Me.txtID.Text = String.Empty
Me.txtContenido.Text = String.Empty
Enqueue mete un objeto
queueCajas.Enqueue(Caja) a la cola
ShowValues()
Me.txtID.Focus()
End Sub
#End Region
6
Desencolar con deQueue
#Region "Dequeue & Peek" y “ver” sin desencolar con Peek
Private Sub btnDequeuePeek_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnPeek.Click, btnDequeue.Click
If queueCajas.Count > 0 Then
Dim Caja As New clsCaja
Dequeue saca al objeto que entró de
If sender Is btnDequeue Then
Caja = queueCajas.Dequeue primero de todos y me lo devuelve
Else
Caja = queueCajas.Peek Peek me deja ver el objeto que entró de
End If primero de todos, sin sacarlo de la cola
Me.txtID.Text = Caja.ID
Me.txtContenido.Text = Caja.Contenido
ShowValues()
Else
Me.txtID.Text = String.Empty
Me.txtContenido.Text = String.Empty
End If
End Sub
#End Region
Mostrar los Valores de la cola
#Region "Show Values" Iterar con For Each…
(enumerator)
Private Sub ShowValues()
Me.lblN.Text = queueCajas.Count
Dim sStkOutput As _
New System.Text.StringBuilder
For Each caja As clsCaja In queueCajas
sStkOutput.Append( _
"ID: " & caja.ID.ToString & _
" Contenido: " & caja.Contenido & _
vbCrLf)
Next
Me.lblValues.Text = sStkOutput.ToString
End Sub
#End Region
End Class
Enqueue los va poniendo
detrás de los que entraron
previamente
7
Peek me devuelve el objeto
que entró de primero, sin
sacarlo de la cola
Dequeue me devuelve el objeto
que entró de primero, pero
sacándolo de la cola
Collection SortedList (Lista Ordenada)
Es una colección que combina el acceso tipo Arreglo, por índice; con acceso por un valor de llave (key).
Además, mantiene ordenada la lista por el valor de la llave.
Hay un grupo de colecciones (de las cuales el SortedList es uno de ellos), que mantienen sus items como
parejas de llave/valor (key/value pair). Tanto la llave como el valor son objetos, salvo en colecciones
especializadas que utilizan tipos fijos en vez de objetos.
txtID txtContenido
TxtPosition
lblValues
btnAdd
btnGetByIndex
TxtPosition
btnRemoveAt
btnRemoveByKey
btnGetByKey
lblN
8
Public Class frmSortedList
Inherits System.Windows.Forms.Form
(Windows Forms Designer generated code)
#Region "Declarations"
Private srtlstCajas As _
New System.Collections.SortedList
Private Class clsCaja
Public ID As String
Public Contenido As String
Public Sub New()
End Sub
Public Sub New( _
ByVal newID As String, _
ByVal newContenido As String)
ID = newID
Contenido = newContenido
End Sub
End Class
#End Region
#Region "Add"
Private Sub btnPush_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAdd.Click
Dim Caja As New clsCaja( _
Me.txtID.Text, Me.txtContenido.Text)
srtlstCajas.Add(Me.txtID.Text, Caja)
ShowValues()
Me.txtID.Text = String.Empty
Me.txtContenido.Text = String.Empty
Me.txtID.Focus()
End Sub
#End Region
#Region "Remove"
Private Sub btnRemove_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnRemove.Click
If srtlstCajas.Count > 0 Then
Dim Caja As New clsCaja
If srtlstCajas.ContainsKey(Me.txtID.Text) Then
srtlstCajas.Remove(Me.txtID.Text)
Me.txtID.Text = Caja.ID
Me.txtContenido.Text = Caja.Contenido
End If
ShowValues()
Else
Me.txtID.Text = String.Empty
Me.txtContenido.Text = String.Empty
End If
End Sub
9
Private Sub btnRemoveAt_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnRemoveAt.Click
Dim posToRemove As Int32 = Val(Me.txtPosition.Text)
If posToRemove <= srtlstCajas.Count - 1 Then
srtlstCajas.RemoveAt(posToRemove)
Me.txtPosition.Text = String.Empty
Else
MessageBox.Show("No existe esa posición")
End If
ShowValues()
End Sub
#End Region
#Region "Get"
Private Sub btnGetByIndex_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGetByIndex.Click
Dim posToShow As Int32 = Val(Me.txtPosition.Text)
Dim Caja As clsCaja
If posToShow <= srtlstCajas.Count - 1 Then
Caja = CType(srtlstCajas.GetByIndex(posToShow), clsCaja)
Me.txtID.Text = Caja.ID
Me.txtContenido.Text = Caja.Contenido
Else
Me.txtID.Text = String.Empty
Me.txtContenido.Text = String.Empty
MessageBox.Show("No existe esa posición")
End If
ShowValues()
End Sub
Private Sub btnGetByKey_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGetByKey.Click
Dim Caja As clsCaja
Caja = CType(srtlstCajas.Item(Me.txtID.Text), clsCaja)
If Not Caja Is Nothing Then
Me.txtID.Text = Caja.ID
Me.txtContenido.Text = Caja.Contenido
ShowValues()
Else
MessageBox.Show("No encontro objeto")
Me.txtContenido.Text = String.Empty
End If
End Sub
#End Region
10
#Region "Show Values"
Private Sub ShowValues()
Me.lblN.Text = srtlstCajas.Count
Dim sOutput As _
New System.Text.StringBuilder
For Each cajaEntry As DictionaryEntry In srtlstCajas
sOutput.Append( _
"ID: " & cajaEntry.Key.ToString & _
" Contenido: " & _
CType(cajaEntry.Value, clsCaja).Contenido & _
vbCrLf)
Next
Me.lblValues.Text = sOutput.ToString
End Sub
#End Region
End Class
11