IEqualityComparer VS System.IEquatable

2023-11-01

类似于IComparer<T> VS IComparable<T>.

public interface IComparable<in T>

{    // Methods    

    int CompareTo(T other);

}

public interface IComparer<in T>

{    // Methods    

    int Compare(T x, T y);

}

public interface IEquatable<T>

{    // Methods    

    bool Equals(T other);

}

public interface IEqualityComparer<in T>

{    // Methods   

    bool Equals(T x, T y);    

    int GetHashCode(T obj);

}

IEqualityComparer<T>是用于custom 比较是否相等的,而System.IEquatable<T>是用于default 比较的。即某个class 会实现 IEquatable<T>来定义相等操作,而 IEqualityComparer<T> 则用于自定义判断。例如用在LinkedList.Find(T value)方法中。

EqualityComparer<T> comparer = EqualityComparer<T>.Default;

以string 类为例来说明:

public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>

例如Dictionary<TKey, TValue>的key 不可以重复,当调用Add方法时就会判断是否相等。

对比Container类的构造函数:

public Dictionary(int capacity, IEqualityComparer<TKey> comparer); //Dictionary需要对key进行判断是否相等的操作所以需要实现IEqualityComparer接口的对象

public LinkList();  //不需要sort,也不需要判断添加的对象是否相等所以不需要comparer

public List(); 动态数组. 仅在sort方法中需要提供一个comparer对象,如果没有则使用集合中存储对象默认的比较方法即要求被存储类必须实现IComparable接口

public BinarySearchTree(IComparer<T> comparer);  二叉树需要对添加的元素进行比较。 this.comparer = Comparer<T>.Default;

public SortSet(IComparer<T> comparer);  红黑树也需要对添加的元素进行比较

using System;
    using System.Collections.Generic;

    class Program
    {
        static Dictionary<Box, String> boxes;

        static void Main(string[] args)
        {

            BoxSameDimensions boxDim = new BoxSameDimensions();
            boxes = new Dictionary<Box, string>(boxDim);

            Console.WriteLine("Boxes equality by dimensions:");
            Box redBox = new Box(8, 4, 8);
            Box greenBox = new Box(8, 6, 8);
            Box blueBox = new Box(8, 4, 8);
            Box yellowBox = new Box(8, 8, 8);
            AddBox(redBox, "red");
            AddBox(greenBox, "green");
            AddBox(blueBox, "blue");
            AddBox(yellowBox, "yellow");

            Console.WriteLine();
            Console.WriteLine("Boxes equality by volume:");

            BoxSameVolume boxVolume = new BoxSameVolume();
            boxes = new Dictionary<Box, string>(boxVolume);
            Box pinkBox = new Box(8, 4, 8);
            Box orangeBox = new Box(8, 6, 8);
            Box purpleBox = new Box(4, 8, 8);
            Box brownBox = new Box(8, 8, 4);
            AddBox(pinkBox, "pink");
            AddBox(orangeBox, "orange");
            AddBox(purpleBox, "purple");
            AddBox(brownBox, "brown");
        }

        public static void AddBox(Box bx, string name)
        {
            try
            {
                boxes.Add(bx, name);
                Console.WriteLine("Added {0}, Count = {1}, HashCode = {2}",
                    name, boxes.Count.ToString(), bx.GetHashCode());
            }
            catch (ArgumentException)
            {
                Console.WriteLine("A box equal to {0} is already in the collection.", name);
            }

 


        }
    }
    public class Box
    {
        public Box(int h, int l, int w)
        {
            this.Height = h;
            this.Length = l;
            this.Width = w;
        }
        public int Height { get; set; }
        public int Length { get; set; }
        public int Width { get; set; }
    }


    class BoxSameDimensions : EqualityComparer<Box>
    {

        public override bool Equals(Box b1, Box b2)
        {
            if (b1.Height == b2.Height & b1.Length == b2.Length
                                & b1.Width == b2.Width)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        public override int GetHashCode(Box bx)
        {
            int hCode = bx.Height ^ bx.Length ^ bx.Width;
            return hCode.GetHashCode();
        }

    }

    class BoxSameVolume : EqualityComparer<Box>
    {

        public override bool Equals(Box b1, Box b2)
        {
            if (b1.Height * b1.Width * b1.Length ==
                b2.Height * b2.Width * b2.Length)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        public override int GetHashCode(Box bx)
        {
            int hCode = bx.Height ^ bx.Length ^ bx.Width;
            return hCode.GetHashCode();
        }

    }
    /* This example produces the following output:
     * 
        Boxes equality by dimensions:
        Added red, Count = 1, HashCode = 46104728
        Added green, Count = 2, HashCode = 12289376
        A box equal to blue is already in the collection.
        Added yellow, Count = 3, HashCode = 55530882

        Boxes equality by volume:
        Added pink, Count = 1, HashCode = 30015890
        Added orange, Count = 2, HashCode = 1707556
        A box equal to purple is already in the collection.
        A box equal to brown is already in the collection.
     * 
    */


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IEqualityComparer VS System.IEquatable 的相关文章

随机推荐

  • Mybatis——增删改查的实现

    注意 增删改时一定要提交事务 代码 提交事务 sqlSession commit 1 namespace 命名空间 namespace中的全限定名 包名 类名 要和Dao Mapper接口的全限定名 包名 类名 一致 2 select 选择
  • 灌电流和拉电流简介

    灌电流 sink current 对一个端口而言 如果电流方向是向其内部流动的则是 灌电流 比如一个IO通过一个电阻和一个LED连接至VCC 当该IO输出为逻辑0时能不能点亮LED 去查该器件手册中sink current参数 拉电流 so
  • Flask后端部署到云服务器

    1 本地写好代码 2 码云创建仓库 上传本地代码到创库 git init git remote add origin https gitee com 自己的仓库 git git pull origin master git add git
  • 1 在 Linux 下开机自动重启脚本(亲测)

    etc rc local 开机启动程序 把需要开机自动运行的程序写在这个脚本里 etc init d 这个目录存放的是一些脚本 一般是linux以rpm包安装时设定的一些服务的启动脚本 要重新启动 sendmail 的话 而且你的 send
  • Tensorflow的Bazel编程(二)

    转自 http blog csdn net langb2014 article details 54312697 安装官网 https bazel build versions master docs tutorial Java html
  • springboot整合fisco

    Spring Boot连接Fisco Bcos区块链 使用spring boot连接Fisco Bcos 在Fisco Bcos的官方提供了Java Sdk工具用于连接 Java SDK 提供了访问 FISCO BCOS 节点的Java A
  • 飞机降落(dfs+贪心思想)

    飞机降落 dfs 贪心思想 原题链接 4957 飞机降落 AcWing题库 思路分析 通过读题易知 题目可以翻译为 已知有 n 条线段 每条线段都可以在一定的区域内滑动 需要我们来判断是否可以找到一种线段的分布方案 使得每条线段都不相交 首
  • stl::(8)set容器API

    set根据元素键值自动被排序 迭代器不能修改键值 键值唯一不重复 set 构造函数 set
  • C和C++安全编码笔记:指针诡计

    指针诡计 pointer subterfuge 是通过修改指针值来利用程序漏洞的方法的统称 可以通过覆盖函数指针将程序的控制权转移到攻击者提供的外壳代码 shellcode 当程序通过函数指针执行一个函数调用时 攻击者提供的代码将会取代原本
  • 深度学习之感知机学习算法

    一 感知机模型 感知机是一种较为简单的二分类模型 但由简至繁 感知机却是神经网络和支持向量机的基础 感知机旨在学习能够将输入数据划分为 1 1的线性分离超平面 所以感知机是一种线性模型 由输入空间到输出空间到函数为 其中x为实例的特征向量
  • c语言程序学生籍贯信息记录,C语言程序设计学生籍贯信息记录簿

    C语言程序设计学生籍贯信息记录簿 编制一个学生籍贯信息记录簿 每个学生信息包括 学号 姓名 籍贯 具体功能 1 创建信息链表并以磁盘文件保存 2 读取磁盘文件并显示输出所有学生的籍贯信息 3 按学号或姓名查询其籍贯 4 按籍贯查询并输出该籍
  • 阻止 JetBrains 的 IDE 自动去掉行尾空格

    起因 最近换了电脑 然后重新装了一堆堆 IDE 包括 Pycharm RubyMine 和 GoLand等 发现 RubyMine 修改某一行的代码后 Ctrl S 保存 结果 IDE 将文件的所有行末尾的空格都自动给去掉了 但是这样就会有
  • git报错kex_exchange_identification

    完整报错 环境 windows10电脑 ssh方式拉取git代码 FATAL Unable to connect to relay host errno 10061 kex exchange identification Connectio
  • mysql 默认连接数和timeout_mysql和连接相关的timeout

    MySQL和连接相关的timeout 今天同事问为什么查询mysql库时 在数据量比较大时 会话总断 刚开始以为是mysql的和连接有关timeout的问题 结果是网络的不稳定的原因 下面总结下和连接有关的timeout slave net
  • Windows安装Java并配置环境变量

    jdk 下载 链接 链接 https pan baidu com s 1j F3kJaGePaT6AJy6iMJvQ 提取码 GYHH 来自百度网盘超级会员V1的分享 打开下载好的安装包 全部默认下载即可 下载完成后一定要记住自己的安装路径
  • oracle 怎么去掉小数位,Oracle 去掉小数终了的0的方法

    Oracle 去掉小数末尾的0的方法 Oracle PL SQL查询语句有的时候要将number类型的字段转换成varchar2类型在报表或页面上经常会出现 440 4411 010 100之类的数据 要不就是小数点前面的0被to char
  • FileZilla,读取目录列表失败(425 Can‘t open data connection.)的解决办法

    因为对外FTP客户要求安全升级的原因 针对部分FTP User启用了SSL认证功能 启用方式 1 建立FTP User时 Force SSL for user login 前面打勾 2 启用被动传输模式 进入FileZilla Server
  • SpringMVC如何在web.xml中配置DispatcherServlet呢?

    转自 SpringMVC如何在web xml中配置DispatcherServlet呢 下文讲述SpringMVC中对DispatcherServlet进行配置的方法分享 如下所示 实现思路 只有在web xml中Servlet处理类指向D
  • 如何实现审核功能

    如何实现审核功能 开发工具与关键技术 VS C 作者 撰写时间 2019 7 26 如何实现审核的功能呢 首先是实现弹出审核模态框和重置表单 再通过ID获取要审核的数据和使用post获取到通过ID查询的数据 用loadDatatoForm回
  • IEqualityComparer VS System.IEquatable

    类似于IComparer