1. HashSet是一个集合,也就是说是无序,且惟一的;

2. Contains进行比较时,如果是Object对象,会比较地址计算出的HashCode;如果是String则比较字符串内容的HashCode

3. HashSet有缓存,第一次Contains完成后,会缓存所有的HashCode,以备以后使用。所以说HashSet最好只用来存储不可变对象,否则contains方法的返回值是不准确的

 

切记:

1:对于不可变类(String、Integer、以及自己定义的不可变类等),要保证equals返回true的时候,它们的hashcode的值相等。 
2:对于不可变类,也要尽量满足1。以避免出现上面说的Set比较时出现的问题。 
3:覆盖一个类的equals方法的时候,要注意可交换性,要保证a.equals(b)的值一定等于b.equals(a)的数值。 

 

当GetHashCode可以直接分辨出不相等时,Equals就没必要调用了,而当GetHashCode返回相同结果时,Equals方法会被调用从而确保判断对象是否真的相等。

所以,还是那句话:GetHashCode没必要一定把对象分辨得很清楚(况且它也不可能,一个int不可能代表所有的可能出现的值),有Equals在后面做保障。GetHashCode仅需要对对象进行快速判断

 

String 的 hashCode 是按字符的hashCode 排列的,然后字符相同,hashCode就想同,而且hashCode 没有set方法,也不能改变。。

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HashSetEqual
{
    class Program
    {
        static void Main(string[] args)
        {
            var o1 = new a(1); //GetHashCode返回1
            var o2 = new a(2); //GetHashCode返回0
            var o3 = new a(3); //GetHashCode返回1

            var dic = new Dictionary<a, object>();
            dic.Add(o1, 123);
            Console.WriteLine("分隔符");
            Console.WriteLine(dic.ContainsKey(o2));
            Console.WriteLine("分隔符");
            Console.WriteLine(dic.ContainsKey(o3));
        }
    }

    class a
    {
        public int Id { get; private set; }
        public a(int i)
        {
            Id = i;
        }

        public override bool Equals(object obj)
        {
            Console.WriteLine("Equals");
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            return Id == ((a)obj).Id;
        }

        //返回余2的结果
        public override int GetHashCode()
        {
            Console.WriteLine("GetHashCode");
            return Id % 2;
        }
    }
}

  

Hashes 的命令 HSET 和 EXPIRE 来实现 hashset contain_不可变类

 

JAVA:

hashcode是通过将内部存储地址映射成一个整型值,这个整型值就是hashcode。java语言规范对hashcode的实现不做要求,这是JVM的实现。需要注意的是:
对于有些架构(例如64位),内存地址空间超过int的表示范围,所以不同对象地址的映射值必然会有相同的,所以hashcode不能确定两个是否相等

C#:

Object.GetHashCode方法的实现同样是基于对象引用(其实就是对象的内部存储地址)来计算。而且MSDN文档同样明确表明:
.NET Framework 不充当防护措施 GetHashCode 方案的默认值实现,因此,此方法返回的值可能不同于 .NET Framework 版本和平台之间,如 32 位和 64 位平台。

1. 如果两个对象equal,则hashcode必须一致
2. 如果两个对象的hashcode一致,但两个对象不一定equal