- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Python 和 Java 等语言提供基于对象标识符的默认哈希和相等实现。这允许在基于哈希的数据结构(如集合)中使用任何新的类类型。
根据我的经验,这是一个陷阱。开发人员编写他们的对象,然后遇到奇怪的(但技术上正确的)行为,例如:
>>> len(set([Foo(5), Foo(5)]))
2
这种默认行为背后的理由是什么?基于身份的哈希和相等何时有用?与仅仅抛出未实现的异常来强制程序员创建对该对象有意义的行为相比,这样做有什么好处?
最佳答案
显然,我们只能推测为什么这些方法是这样设计的。与许多语言一样,有时设计者希望他们可以回去改变他们设计某个功能的方式。
例如,有些人会争辩说,如果 Java 从头开始重新设计,也许会出现类似 checked exceptions 的情况。不会被包括在内。或者,Object 类可能不包含 wait
、notify
方法等。那么,至少在涉及 Object 时,有可能吗? hashCode()
方法,如果今天从头开始重新设计 Java,该功能的设计会有所不同?
说到equals
方法。我认为每个对象都拥有它并且其默认实现执行引用相等是非常有意义的。
至于 hashCode
方法,那么我必须同意 OP 的观点,很多时候,使用起来很尴尬。有时,有些对象我们永远不想在哈希表中使用,但我们想重新定义相等的逻辑。因此,要么您重新定义 hashCode
(浪费精力),只是为了确保以后不会有人意外地在哈希表中不正确地使用它,或者您不这样做,然后您会遇到令人讨厌的意外当有人决定将对象放入哈希表时,这条路。
我个人发现了这个article由 C# 编译器团队的开发人员 Eric Lippert 撰写,非常有启发性,而且讨论也非常适用于 Java。他特别说了以下内容(最后一段很有趣):
What is GetHashCode used for?
It is by design useful for only one thing: putting an object in a hash table. Hence the name.
Why do we have this method on Object in the first place?
It makes perfect sense that every object in the type system should provide a GetType method; data's ability to describe itself is a key feature of the CLR type system. And it makes sense that every object should have a ToString, so that it is able to print out a representation of itself as a string, for debugging purposes. It seems plausible that objects should be able to compare themselves to other objects for equality. But why should it be the case that every object should be able to hash itself for insertion into a hash table? Seems like an odd thing to require every object to be able to do.
I think if we were redesigning the type system from scratch today, hashing might be done differently, perhaps with an IHashable interface. But when the CLR type system was designed there were no generic types and therefore a general-purpose hash table needed to be able to store any object.
关于java - 提供默认哈希和相等方法的语言有哪些优点/缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31075769/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!