C#中List<int[]>调用Contains判断坐标数组存在始终返回false怎么办
问题根源
数组是引用类型,List<T>.Contains方法默认使用EqualityComparer<T>.Default做相等性判断,对于引用类型,默认比较的是对象的内存地址,而非对象内部存储的内容。你每次调用new int[] {1,3}都会在堆上创建一个新的数组对象,两次new出来的数组地址完全不同,所以即使元素完全一致,Contains也会返回false。
你用ArrayList得到相同结果也是同样的原因,ArrayList的Contains逻辑和泛型List一致,都是默认比较引用地址。
可行实现方案
下面按推荐优先级给出方案:
方案1:使用值类型存储坐标(最优)
优先选择值类型存储坐标,值类型默认会逐字段比较内容,不需要自定义比较逻辑,性能也更高。
最简便的是使用C#自带的ValueTuple(C# 7.0及以上版本支持):
// 如果需要保留列表的顺序、允许重复坐标,用List<ValueTuple> List<(int X, int Y)> coordList = new List<(int X, int Y)>(); coordList.Add((1, 3)); coordList.Add((3, 6)); bool contains = coordList.Contains((1, 3)); Console.WriteLine(contains); // 输出True
如果你的场景不需要保留顺序、且需要自动去重,直接用HashSet替代List,查找效率从O(n)提升到O(1):
HashSet<(int X, int Y)> coordSet = new HashSet<(int X, int Y)>(); coordSet.Add((1, 3)); coordSet.Add((3, 6)); bool contains = coordSet.Contains((1, 3)); Console.WriteLine(contains); // 输出True
如果使用的C#版本不支持ValueTuple,可以自定义坐标结构体:
public struct Coord { public int X; public int Y; public Coord(int x, int y) { X = x; Y = y; } } // 使用方式和ValueTuple一致 List<Coord> coordList = new List<Coord>(); coordList.Add(new Coord(1,3)); bool contains = coordList.Contains(new Coord(1,3)); // 输出True
方案2:保留数组存储,自定义比较逻辑
如果必须用int[]存储坐标,可以用LINQ的Any方法手动比较数组元素:
List<int[]> coordList = new List<int[]>(); coordList.Add(new int[] {1, 3}); coordList.Add(new int[] {3, 6}); // 手动指定比较规则 int[] target = new int[] {1,3}; bool contains = coordList.Any(c => c.Length == 2 && c[0] == target[0] && c[1] == target[1]); Console.WriteLine(contains); // 输出True
内容的提问来源于stack exchange,提问作者edamamevv
相关产品推荐
相关产品推荐

