LinkedList.Find

22/06/2006 - 19:13 por UAH | Informe spam
En el siguiente ejemplo, la primera búsqueda en el método Main se realiza
correctamente y la segunda no. Entiendo que eso es porque Find está
comparando la referencia al objeto y no su contenido. Enonces añadí
IComparable.CompareTo a la clase CDatos (objetos a comparar) pero sigue sin
funcionar. ¿Cuál es la solución?
Saludos


using System;
using System.Collections.Generic;
using MisClases.ES;


public class CDatos : IComparable
{
// Atributos
private string nombre;
private double nota;

// Métodos
public CDatos() {} // constructor sin parámetros
public CDatos(string nom, double n) // constructor con parámetros
{
nombre = nom;
nota = n;
}

public string Nombre
{
get { return nombre; }
set { nombre = value; }
}

public double Nota
{
get { return nota; }
set { nota = value; }
}

public int CompareTo(object ob)
{
CDatos obj = (CDatos)ob;
if (nombre.CompareTo(obj.nombre) == 0 && nota == obj.nota)
return 0;
else if (nombre.CompareTo(obj.nombre) < 0)
return -1;
else
return 1;
}
}



public class Test
{
public static void Main(string[] args)
{
// Crear una lista lineal vacía
LinkedList<CDatos> le = new LinkedList<CDatos>();

// Añadir elementos a la lista
le.AddLast(new CDatos("aaa", 5));
le.AddLast(new CDatos("bbb", 6));
le.AddLast(new CDatos("ccc", 7));

CDatos obj1 = new CDatos("abcd", 10.0);
le.AddLast(obj1);

// Buscar
LinkedListNode<CDatos> actual = le.Find(obj1);
if (actual != null)
Console.WriteLine(actual.Value.Nombre); // Ok

// Buscar
CDatos obj = new CDatos("bbb", 6);
actual = le.Find(obj);
if (actual != null)
Console.WriteLine(actual.Value.Nombre); // No Ok
}
}

Preguntas similare

Leer las respuestas

#1 Jose Escrich
22/06/2006 - 19:41 | Informe spam
Hola UAH,

Si quieres alterar el Find para que compare por contenidos debes hacer un
override del Equals, IComparer se utiliza mas que nada para ordenar arrays
y demas. Pero al momento de saber si dos instancias son iguales se utiliza
el Equals. Fijate que esto si esta mal implementado puede tener un comportamiento
impredesible ya que originalmente Equals verifica si dos objetos tienen la
misma referencia.

saludos,

Jose Escrich
mailto: jescrich -a- gmail.com
http://latincoder.com

U> En el siguiente ejemplo, la primera búsqueda en el método Main se
U> realiza
U> correctamente y la segunda no. Entiendo que eso es porque Find está
U> comparando la referencia al objeto y no su contenido. Enonces añadí
U> IComparable.CompareTo a la clase CDatos (objetos a comparar) pero
U> sigue sin
U> funcionar. ¿Cuál es la solución?
U> Saludos
U> using System;
U> using System.Collections.Generic;
U> using MisClases.ES;
U> public class CDatos : IComparable
U> {
U> // Atributos
U> private string nombre;
U> private double nota;
U> // Métodos
U> public CDatos() {} // constructor sin parámetros
U> public CDatos(string nom, double n) // constructor con parámetros
U> {
U> nombre = nom;
U> nota = n;
U> }
U> public string Nombre
U> {
U> get { return nombre; }
U> set { nombre = value; }
U> }
U> public double Nota
U> {
U> get { return nota; }
U> set { nota = value; }
U> }
U> public int CompareTo(object ob)
U> {
U> CDatos obj = (CDatos)ob;
U> if (nombre.CompareTo(obj.nombre) == 0 && nota == obj.nota)
U> return 0;
U> else if (nombre.CompareTo(obj.nombre) < 0)
U> return -1;
U> else
U> return 1;
U> }
U> }
U> public class Test
U> {
U> public static void Main(string[] args)
U> {
U> // Crear una lista lineal vacía
U> LinkedList<CDatos> le = new LinkedList<CDatos>();
U> // Añadir elementos a la lista
U> le.AddLast(new CDatos("aaa", 5));
U> le.AddLast(new CDatos("bbb", 6));
U> le.AddLast(new CDatos("ccc", 7));
U> CDatos obj1 = new CDatos("abcd", 10.0);
U> le.AddLast(obj1);
U> // Buscar
U> LinkedListNode<CDatos> actual = le.Find(obj1);
U> if (actual != null)
U> Console.WriteLine(actual.Value.Nombre); // Ok
U> // Buscar
U> CDatos obj = new CDatos("bbb", 6);
U> actual = le.Find(obj);
U> if (actual != null)
U> Console.WriteLine(actual.Value.Nombre); // No Ok
U> }
U>
Respuesta Responder a este mensaje
#2 Daniel A. Calvin
22/06/2006 - 20:20 | Informe spam
Hola UAH

Tenes que implementar otro interface:
public class CDatos :IEquatable<CDatos>

para probar facil implemente asi:

#region IEquatable<CDatos> Members
public bool Equals(CDatos other)
{
CDatos obj = (CDatos)other;
return (obj.nombre == this.nombre);
}
#endregion

Anduvo bien.

Espero te sirva

Un abrazo


Daniel A. Calvin
MCP


"UAH" escribió:

En el siguiente ejemplo, la primera búsqueda en el método Main se realiza
correctamente y la segunda no. Entiendo que eso es porque Find está
comparando la referencia al objeto y no su contenido. Enonces añadí
IComparable.CompareTo a la clase CDatos (objetos a comparar) pero sigue sin
funcionar. ¿Cuál es la solución?
Saludos


using System;
using System.Collections.Generic;
using MisClases.ES;


public class CDatos : IComparable
{
// Atributos
private string nombre;
private double nota;

// Métodos
public CDatos() {} // constructor sin parámetros
public CDatos(string nom, double n) // constructor con parámetros
{
nombre = nom;
nota = n;
}

public string Nombre
{
get { return nombre; }
set { nombre = value; }
}

public double Nota
{
get { return nota; }
set { nota = value; }
}

public int CompareTo(object ob)
{
CDatos obj = (CDatos)ob;
if (nombre.CompareTo(obj.nombre) == 0 && nota == obj.nota)
return 0;
else if (nombre.CompareTo(obj.nombre) < 0)
return -1;
else
return 1;
}
}



public class Test
{
public static void Main(string[] args)
{
// Crear una lista lineal vacía
LinkedList<CDatos> le = new LinkedList<CDatos>();

// Añadir elementos a la lista
le.AddLast(new CDatos("aaa", 5));
le.AddLast(new CDatos("bbb", 6));
le.AddLast(new CDatos("ccc", 7));

CDatos obj1 = new CDatos("abcd", 10.0);
le.AddLast(obj1);

// Buscar
LinkedListNode<CDatos> actual = le.Find(obj1);
if (actual != null)
Console.WriteLine(actual.Value.Nombre); // Ok

// Buscar
CDatos obj = new CDatos("bbb", 6);
actual = le.Find(obj);
if (actual != null)
Console.WriteLine(actual.Value.Nombre); // No Ok
}
}

Respuesta Responder a este mensaje
#3 UAH
22/06/2006 - 22:46 | Informe spam
Muchas gracias. Lo he probado y funciona correctamente.

"Jose Escrich" escribió:

Hola UAH,

Si quieres alterar el Find para que compare por contenidos debes hacer un
override del Equals, IComparer se utiliza mas que nada para ordenar arrays
y demas. Pero al momento de saber si dos instancias son iguales se utiliza
el Equals. Fijate que esto si esta mal implementado puede tener un comportamiento
impredesible ya que originalmente Equals verifica si dos objetos tienen la
misma referencia.

saludos,

Jose Escrich
mailto: jescrich -a- gmail.com
http://latincoder.com

U> En el siguiente ejemplo, la primera búsqueda en el método Main se
U> realiza
U> correctamente y la segunda no. Entiendo que eso es porque Find está
U> comparando la referencia al objeto y no su contenido. Enonces añadí
U> IComparable.CompareTo a la clase CDatos (objetos a comparar) pero
U> sigue sin
U> funcionar. ¿Cuál es la solución?
U> Saludos
U> using System;
U> using System.Collections.Generic;
U> using MisClases.ES;
U> public class CDatos : IComparable
U> {
U> // Atributos
U> private string nombre;
U> private double nota;
U> // Métodos
U> public CDatos() {} // constructor sin parámetros
U> public CDatos(string nom, double n) // constructor con parámetros
U> {
U> nombre = nom;
U> nota = n;
U> }
U> public string Nombre
U> {
U> get { return nombre; }
U> set { nombre = value; }
U> }
U> public double Nota
U> {
U> get { return nota; }
U> set { nota = value; }
U> }
U> public int CompareTo(object ob)
U> {
U> CDatos obj = (CDatos)ob;
U> if (nombre.CompareTo(obj.nombre) == 0 && nota == obj.nota)
U> return 0;
U> else if (nombre.CompareTo(obj.nombre) < 0)
U> return -1;
U> else
U> return 1;
U> }
U> }
U> public class Test
U> {
U> public static void Main(string[] args)
U> {
U> // Crear una lista lineal vacía
U> LinkedList<CDatos> le = new LinkedList<CDatos>();
U> // Añadir elementos a la lista
U> le.AddLast(new CDatos("aaa", 5));
U> le.AddLast(new CDatos("bbb", 6));
U> le.AddLast(new CDatos("ccc", 7));
U> CDatos obj1 = new CDatos("abcd", 10.0);
U> le.AddLast(obj1);
U> // Buscar
U> LinkedListNode<CDatos> actual = le.Find(obj1);
U> if (actual != null)
U> Console.WriteLine(actual.Value.Nombre); // Ok
U> // Buscar
U> CDatos obj = new CDatos("bbb", 6);
U> actual = le.Find(obj);
U> if (actual != null)
U> Console.WriteLine(actual.Value.Nombre); // No Ok
U> }
U> }



Respuesta Responder a este mensaje
#4 UAH
22/06/2006 - 22:47 | Informe spam
Muchas gracias. Lo he probado y funciona correctamente.


"Daniel A. Calvin" escribió:

Hola UAH

Tenes que implementar otro interface:
public class CDatos :IEquatable<CDatos>

para probar facil implemente asi:

#region IEquatable<CDatos> Members
public bool Equals(CDatos other)
{
CDatos obj = (CDatos)other;
return (obj.nombre == this.nombre);
}
#endregion

Anduvo bien.

Espero te sirva

Un abrazo


Daniel A. Calvin
MCP


"UAH" escribió:

> En el siguiente ejemplo, la primera búsqueda en el método Main se realiza
> correctamente y la segunda no. Entiendo que eso es porque Find está
> comparando la referencia al objeto y no su contenido. Enonces añadí
> IComparable.CompareTo a la clase CDatos (objetos a comparar) pero sigue sin
> funcionar. ¿Cuál es la solución?
> Saludos
>
>
> using System;
> using System.Collections.Generic;
> using MisClases.ES;
>
>
> public class CDatos : IComparable
> {
> // Atributos
> private string nombre;
> private double nota;
>
> // Métodos
> public CDatos() {} // constructor sin parámetros
> public CDatos(string nom, double n) // constructor con parámetros
> {
> nombre = nom;
> nota = n;
> }
>
> public string Nombre
> {
> get { return nombre; }
> set { nombre = value; }
> }
>
> public double Nota
> {
> get { return nota; }
> set { nota = value; }
> }
>
> public int CompareTo(object ob)
> {
> CDatos obj = (CDatos)ob;
> if (nombre.CompareTo(obj.nombre) == 0 && nota == obj.nota)
> return 0;
> else if (nombre.CompareTo(obj.nombre) < 0)
> return -1;
> else
> return 1;
> }
> }
>
>
>
> public class Test
> {
> public static void Main(string[] args)
> {
> // Crear una lista lineal vacía
> LinkedList<CDatos> le = new LinkedList<CDatos>();
>
> // Añadir elementos a la lista
> le.AddLast(new CDatos("aaa", 5));
> le.AddLast(new CDatos("bbb", 6));
> le.AddLast(new CDatos("ccc", 7));
>
> CDatos obj1 = new CDatos("abcd", 10.0);
> le.AddLast(obj1);
>
> // Buscar
> LinkedListNode<CDatos> actual = le.Find(obj1);
> if (actual != null)
> Console.WriteLine(actual.Value.Nombre); // Ok
>
> // Buscar
> CDatos obj = new CDatos("bbb", 6);
> actual = le.Find(obj);
> if (actual != null)
> Console.WriteLine(actual.Value.Nombre); // No Ok
> }
> }
>
Respuesta Responder a este mensaje
#5 Xavier Jorge Cerdá
25/06/2006 - 04:11 | Informe spam
Hola a ambos,

Como bien indica Jose, para solucionar tu problema se ha de sobreescribir el
método Equals, pero cuidado al sobreescribir este método, ya que también se
ha de sobreescribir el método GetHashCode.

Existe algunos tipos de colecciones (por ejemplo las coleciones Hashtable,
HybridDictionary, ...) que antes de comparar dos objetos utilizan esta
función hash para acelerar el proceso de búsqueda, por lo que puede decirte
que no lo encuentra porque no coincide el valor de retorno de esta función.

*** El método GetHashCode debe asegurar que dos objetos que son iguales
(según la función que has sobreescrito) devuelven EL MISMO valor en la
función GetHashCode ***



Por ejemplo en tu caso podrías utilizar (cuidado que no he compilado el
código porque en el ordenador donde estoy escribiendo no tengo instalado el
VS y lo he realizado de cabeza):

public override int GetHashCode()
{
return nombre.GetHashCode() + nota.GetHashCode();
}

Un saludo,

Xavi


"UAH" escribió en el mensaje
news:
Muchas gracias. Lo he probado y funciona correctamente.

"Jose Escrich" escribió:

Hola UAH,

Si quieres alterar el Find para que compare por contenidos debes hacer un
override del Equals, IComparer se utiliza mas que nada para ordenar
arrays
y demas. Pero al momento de saber si dos instancias son iguales se
utiliza
el Equals. Fijate que esto si esta mal implementado puede tener un
comportamiento
impredesible ya que originalmente Equals verifica si dos objetos tienen
la
misma referencia.

saludos,

Jose Escrich
mailto: jescrich -a- gmail.com
http://latincoder.com

U> En el siguiente ejemplo, la primera búsqueda en el método Main se
U> realiza
U> correctamente y la segunda no. Entiendo que eso es porque Find está
U> comparando la referencia al objeto y no su contenido. Enonces añadí
U> IComparable.CompareTo a la clase CDatos (objetos a comparar) pero
U> sigue sin
U> funcionar. ¿Cuál es la solución?
U> Saludos
U> using System;
U> using System.Collections.Generic;
U> using MisClases.ES;
U> public class CDatos : IComparable
U> {
U> // Atributos
U> private string nombre;
U> private double nota;
U> // Métodos
U> public CDatos() {} // constructor sin parámetros
U> public CDatos(string nom, double n) // constructor con parámetros
U> {
U> nombre = nom;
U> nota = n;
U> }
U> public string Nombre
U> {
U> get { return nombre; }
U> set { nombre = value; }
U> }
U> public double Nota
U> {
U> get { return nota; }
U> set { nota = value; }
U> }
U> public int CompareTo(object ob)
U> {
U> CDatos obj = (CDatos)ob;
U> if (nombre.CompareTo(obj.nombre) == 0 && nota == obj.nota)
U> return 0;
U> else if (nombre.CompareTo(obj.nombre) < 0)
U> return -1;
U> else
U> return 1;
U> }
U> }
U> public class Test
U> {
U> public static void Main(string[] args)
U> {
U> // Crear una lista lineal vacía
U> LinkedList<CDatos> le = new LinkedList<CDatos>();
U> // Añadir elementos a la lista
U> le.AddLast(new CDatos("aaa", 5));
U> le.AddLast(new CDatos("bbb", 6));
U> le.AddLast(new CDatos("ccc", 7));
U> CDatos obj1 = new CDatos("abcd", 10.0);
U> le.AddLast(obj1);
U> // Buscar
U> LinkedListNode<CDatos> actual = le.Find(obj1);
U> if (actual != null)
U> Console.WriteLine(actual.Value.Nombre); // Ok
U> // Buscar
U> CDatos obj = new CDatos("bbb", 6);
U> actual = le.Find(obj);
U> if (actual != null)
U> Console.WriteLine(actual.Value.Nombre); // No Ok
U> }
U> }



email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida