【问题标题】:comparing List<Object> values C#比较 List<Object> 值 C#
【发布时间】:2012-04-16 08:08:00
【问题描述】:

我遇到了列表对象值的问题。 Object 是一个包含两个整数的类的对象。

喜欢

List<Object> container;
container.Add(new Coordinates(x_axis, y_axis));  // x_axis=200, y_axis=300

我每次都必须添加唯一坐标,意味着下次x_axis,y_axis如果分别为200、300,则永远无法添加到列表中。

如何检查列表对象中已经存在的项目?

谢谢

【问题讨论】:

  • 覆盖Equals & GetHashCode of Coordinates 并使用HashSet
  • 您使用List&lt;Object&gt;而不是List&lt;Coordinates&gt;的任何原因?
  • +1 表示EqualsGetHashCode。您也可以通过检查Contains(coordinate) 来保留列表(如果您要存储许多坐标,它会很慢)

标签: c# list object compare


【解决方案1】:

为您的 Coordinates 类覆盖 Equals 和 GetHashCode:

public class Coordinates
{
    public Coordinates(int x, int y)
    {
        X = x;
        Y = y;
    }

    public int X { get; private set; }
    public int Y { get; private set; }

    public override bool Equals(object obj)
    {
        if (!(obj is Coordinates))
        {
            return false;
        }
        Coordinates coordinates = (Coordinates)obj;
        return ((coordinates.X == this.X) && (coordinates.Y == this.Y));
    }

    public override int GetHashCode()
    {
        return (X ^ Y);
    }
}

并使用您的 Coordinates 对象的通用 List 或 HashSet:

List<Coordinates> container = new List<Coordinates>();
Coordinates coordinates = new Coordinates(x_axis, y_axis);

if (!container.Contains(coordinates)
    container.Add(coordinates);

还有 HashSet:

HashSet<Coordinates> container = new HashSet<Coordinates>();
container.Add(new Coordinates(x_axis, y_axis));

【讨论】:

  • 关于 GetHashCode 覆盖 - 我的做法与微软在 Point 类中所做的相同。
  • 是的,但这不是最佳实践,因为X = 10, Y = 20X = 20, Y = 10 时的结果是相同的。更好地使用我在下面的帖子中描述的做法。
  • 同意,xor 为二进制 010101101010110001 等给出相同的值。这就是为什么我指出为什么我使用这种奇怪的哈希码生成。
【解决方案2】:

请改用List&lt;Coordinates&gt;

要检查列表中是否存在一组坐标,您必须遍历列表并比较属性值:

Coordinates point = new Coordinates(200, 300);

if (!container.Any(c => c.x_axis == point.x_axis && c.y_axis = point.y_axis)) {
  container.Add(point);
}

【讨论】:

  • 如果我使用List&lt;Coordinates&gt; .. 有错误Inconsistent accessibility: field type 'System.Collections.Generic.List&lt;MyNameSpace.Coordinates&gt;' is less accessible than field 'MyNameSpace.MyClass.Container'
  • @rana:将 Coordinates 类设为公开,或将列表设为私有。
【解决方案3】:

您可以将您从容器中拉出的项目投射回坐标,然后检查它们的 x 和 y 值。或者,如果它继承自 ICombparable,则只需使用 = 运算符。 如果不是 IComparable,您可以创建自己的类,并继承 IComparable 接口。

    var myCoord = (Coordinates) container(0);

这一切都假设你真的不想让你的容器直接保存坐标。

编辑:修正了一堆错别字

【讨论】:

    【解决方案4】:

    您可以像这样使用 LINQ:

    if (!container.Any(c => (Coordinates)c.x_axis == x_axis &&
                            (Coordinates)c.y_axis == y_axis))
        container.Add(new Coordinates(x_axis, y_axis));
    

    【讨论】:

      【解决方案5】:

      您最好使用HashSetDictionary(如果您需要按特定顺序保存它们)以确保它们真正独一无二。

      那么你应该重写GetHashCodeEquals 来检查相等性。

      GetHashCode 的最佳实践:What is the best algorithm for an overridden System.Object.GetHashCode?

      实施

      public class Coordinate
      {
          public Int32 X { get; set; }
          public Int32 Y { get; set; }
      
          public override int GetHashCode()
          {
              Int32 hash = 17;
              hash = hash * 23 + X;
              hash = hash * 23 + Y;
              return hash;
          }
          public override Boolean Equals(object obj)
          {
              Coordinate other = obj as Coordinate;
              if (other != null)
              {
                  return (other.X == X) && (other.Y == Y);
              }
              return false;
          }
      }
      

      字典

      Int32 count = 0;
      Dictionary<Coordinate, Int32> cords = new Dictionary<Coordinate, Int32>();
      // TODO : You need to check if the coordinate exists before adding it
      cords.Add(new Coordinate() { X = 10, Y = 20 }, count++);
      // To get the coordinates in the right order
      var sortedOutput = cords.OrderBy(p => p.Value).Select(p => p.Key);
      

      哈希集

      HashSet<Coordinate> cords = new HashSet<Coordinate>();
      cords.Add(new Coordinate() { X = 10, Y = 20 });
      

      【讨论】:

        猜你喜欢
        • 2019-03-13
        • 2017-09-07
        • 1970-01-01
        • 2020-01-26
        • 2022-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-25
        相关资源
        最近更新 更多