集合中Object.equals方法的后台工作?

时间:2016-06-24 13:58:51

标签: java collections equals

    HashSet hs = new HashSet();

    hs.add(10);
    hs.add("sum");
    hs.add(10);
    hs.add(12.3d);

    System.out.println(hs); 

1)在上面的代码中,java如何知道第二个对象传递时,它不需要用第一个对象检查它。并且它如何知道当第三个对象(即10)被传递时,它需要调用Integer类的重写的.equals方法来检查第一个和第三个对象。

2)如果它调用对象类的.equals方法,那么两个整数都有不同的实例,所以两者都应该被添加,但事实并非如此。

我需要在集合中使用.equals方法的后台工作!

3 个答案:

答案 0 :(得分:0)

equals在所有情况下都不会参考帐户中的实例。它基本上是一个自定义实现,它取决于对象的类型,默认情况下只是比较引用。您可以将Integer::equals想象为

boolean equals(Object other) { 
  boolean isSameType = other instanceof Integer;
  return isSameType && ((Integer)other).value == value;
}

因此,具有相同值的两个Integer实例将被视为相等。此外,您正在处理HashSet<T>,因此您必须考虑int hashCode(),这应与equals实施一致。

答案 1 :(得分:0)

您的HashSet未使用通用参数化,因此您认为它将被视为HashSet<Object>

但是,当要添加的元素与集合的当前元素之间进行比较时,对象类型的 equalshashCode方法是考虑到了。因此,当您再次添加1010时,它将使用Integer.equals来确定执行时的相等性。

HashSet<Object>仅处理引用类型 Object,这意味着编译器要求HashSet中的所有对象都是Object的实例或扩展Object obj = new Integer(10); 1}}(当然所有对象都是)。这与方法的执行无关,但是,其行为由实际对象的类型定义。

总之,如果我定义:

obj.equals(anotherObj);

我打电话给:

Object

编译器将确保引用类型equals)有一个名为Integer的方法,并在运行时确保对象类型的行为 var dbQuery = (DbQuery<T>)query; // get the IInternalQuery internal variable from the DbQuery object var iqProp = dbQuery.GetType().GetProperty("InternalQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); var iq = iqProp.GetValue(dbQuery, null); // get the ObjectQuery internal variable from the IInternalQuery object var oqProp = iq.GetType().GetProperty("ObjectQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); var objectQuery = (ObjectQuery<T>)oqProp.GetValue(iq, null); var sqlString = objectQuery.ToTraceString(); foreach (var objectParam in objectQuery.Parameters) { Console.WriteLine($"{objectParam.Name} = {objectParam.Value.ToString()}"); } )已执行。

答案 2 :(得分:0)

Set中的唯一性,在java内部通过 HashMap 。每当你创建一个HashSet对象时,它都会创建一个HashMap对象。正如我们在HashMap中所知,每个键都是唯一的。如果key不为null,则它将在key对象上调用hashfunction,即key.hashCode(),因此在key.hashCode()返回hashValue之后,它看起来像 - int hash = hash(hashValue) ,现在,它将返回的hashValue应用到自己的散列函数中。 final hashvalue用于查找存储Entry对象的存储桶位置。入口对象像这样存储在桶中(散列,键,值,bucketindex)。所以我们遍历链表,使用keys.equals()比较每个条目中的键,直到它返回true。然后返回相应的条目对象Value,即如果两个对象的哈希值相同则equals方法将被调用以验证它是否相同。如果没有,那么对象将在桶中找到它的位置(链接列表)。