Manipulación de valores en una colección Queue

Manipulación de valores en una colección Queue

El método Enqueue( ) añade nuevos valores, que quedan situados al final de la lista, del modo ilustrado en la figura anterior.

Programación con Visual Basic .NET © Grupo EIDOS

Para desarrollar un ejemplo de uso de la clase Queue, vamos a plantear la siguiente situación: necesitamos implementar un sistema de recepción y envío de mensajes. El primer mensaje entrante se situará en la lista de modo que será el primero en enviarse, el segundo mensaje recibido será el siguiente enviado y así sucesivamente.

El Código fuente 381 mostrado a continuación, ilustra el modo de introducción de valores, en un estilo diferente al utilizado en los anteriores ejemplos. En este caso, en lugar de introducir directamente por código los valores en la lista, utilizaremos el método ReadLine( ) del objeto Console, de manera que el usuario introduzca los valores que precise. Cuando pulse [INTRO] sin haber escrito valor alguno, se considerará que ha terminado la introducción de datos.

Sub Main() ' crear objeto Queue, cola de valores Dim aqListaMensa As New Queue()

Console.WriteLine("Introducir mensajes") Dim sMensaje As String ' bucle de recepción de mensajes Do

sMensaje = Console.ReadLine() ' si hemos escrito algo... If sMensaje.Length > 0 Then

' añadimos a la cola aqListaMensa.Enqueue(sMensaje)

Else ' salimos Exit Do

End If Loop

' la propiedad Count nos indica la cantidad de ' elementos en la lista Console.WriteLine("Hay {0} mensajes para procesar", aqListaMensa.Count)

' con un enumerador recorremos la lista Dim oEnumerador = aqListaMensa.GetEnumerator() Console.WriteLine("Contenido del objeto Queue") RecorrerEnumerador(oEnumerador)

Console.ReadLine() End Sub

Public Sub RecorrerEnumerador(ByVal oEnumerador As IEnumerator) While oEnumerador.MoveNext Console.WriteLine(oEnumerador.Current) End While Console.WriteLine()

End Sub

Código fuente 381

Normalmente, en un sistema de gestión de mensajes, una vez que solicitamos un mensaje, este es enviado y borrado de su contenedor. Pues algo similar es lo que haremos seguidamente, ya que después de que el usuario haya introducido todos los mensajes, utilizaremos el método Dequeue( ), que irá extrayendo o desencolando cada uno de los valores de la lista, comenzando por el primero que fue introducido. Este método, además de devolver el valor, lo elimina de la lista. Ver el Código fuente 382.

© Grupo EIDOS 24. Colecciones

Sub Main() Dim aqListaMensa As New Queue() Dim sMensaje As String Dim iContador As Integer

' bucle de recepción de mensajes Do

iContador += 1 Console.WriteLine("Mensaje nro. {0}. " & _

"Pulse [INTRO] para finalizar captura", _ iContador)

sMensaje = Console.ReadLine() ' si hemos escrito algo... If sMensaje.Length > 0 Then

' añadimos a la lista aqListaMensa.Enqueue(sMensaje)

Else ' salimos Exit Do

End If Loop Console.WriteLine()

' la propiedad Count nos indica la cantidad de ' elementos en la lista Console.WriteLine("Hay {0} mensajes para procesar", aqListaMensa.Count) Console.WriteLine()

' procesar los mensajes de la lista iContador = 0 Console.WriteLine("Procesar lista de mensajes") While aqListaMensa.Count > 0

iContador += 1 Console.WriteLine("Mensaje nro. {0} - texto: {1}", _

iContador, aqListaMensa.Dequeue()) Console.WriteLine("Quedan {0} mensajes por procesar", aqListaMensa.Count) Console.WriteLine()

End While

Console.ReadLine() End Sub

Código fuente 382

Pero supongamos que queremos comprobar el contenido del próximo mensaje a procesar antes de sacarlo de la lista. En ese caso, el método Peek( ) de la clase Queue es el indicado, ya que precisamente devuelve el siguiente valor de la lista sin eliminarlo, como ilustra el Código fuente 383.

Console.WriteLine("Obtenemos el primer valor sin eliminar: {0}", aqListaMensa.Peek())

Código fuente 383

Puede ocurrir también, que necesitemos obtener los valores de la lista pero sin eliminarlos, por ejemplo, para poder repetir el proceso posteriormente. ¿Tenemos que volver a pedirlos al usuario?, no en absoluto, ya que mediante el método Clone( ) de la clase Queue, podemos obtener un nuevo objeto independiente, pero con los mismo elementos. A partir de ese momento, aunque procesemos la lista original, mantendremos los datos en una copia del objeto.

Programación con Visual Basic .NET © Grupo EIDOS

Otra técnica consiste en utilizar el método ToArray( ), que copia los valores de la lista a un array estándar. Dicho array deberá haber sido previamente creado con el tamaño adecuado, ya que si tiene menos elementos que el objeto Queue, cuando copiemos los valores al array se producirá un error. Para saber el tamaño del array que tenemos que crear, podemos ayudarnos de la propiedad Count del objeto Queue. El Código fuente 384 muestra unos ejemplos.

Public Sub Main() ' crear objeto Queue e introducir valores Dim aqListaMensa As New Queue() '.... '.... ' crear copia de seguridad de la lista Dim aqCopiaMensajes As Queue = aqListaMensa.Clone()

' o también, podemos crear un array normal con los ' elementos del objeto Queue Dim aListaDatos As Array = Array.CreateInstance(GetType(Object), _

aqListaMensa.Count) aListaDatos = aqListaMensa.ToArray()

' procesar los mensajes de la lista original, ' mantendremos los valores en el objeto clonado ' o en un array '.... '....

End Sub

Código fuente 384

Copiando los valores a un array, tenemos la ventaja de poder ordenarlos, o hacer cualquier operación que nos permita la clase Array.

Y ya para terminar con esta clase, el método Clear( ) elimina todos los valores del array interno que mantiene un objeto Queue. Podemos utilizar este método en el caso de que después de haber obtenido algunos valores de la lista, no queramos seguir extrayendo información, pero necesitemos el objeto vacío para poder repetir el proceso de captura de datos.