看一下Java 6的源代码,HashSet<E>
实际上是通过HashMap<E,Object>
使用Set的每个条目上的伪对象实例来实现的。
我认为这浪费了4字节(在32位计算机上)用于条目本身的大小。
但是,为什么仍然使用它呢?除了使代码维护更容易之外,还有什么理由要使用它?
实际上,不只是HashSet
。 Java 6中该接口的 所有
实现Set
都基于底层Map
。这不是必需的;这只是实现的方式。您可以通过查阅有关的各种实现的文档来自己查看Set
。
您的主要问题是
但是,为什么仍然使用它呢?除了使代码维护更容易之外,还有什么理由要使用它?
我认为代码维护是一个很大的动机。因此防止重复和膨胀。
Set
和Map
相似的接口,因为不允许重复的元素。(我认为唯一Set
不受a
支持的Map
是CopyOnWriteArraySet
,这是一个不寻常的Collection,因为它是不可变的。)
特别:
从以下文档中Set
:
不包含重复元素的集合。更正式地说,集合不包含元素对e1和e2,使得e1.equals(e2)最多包含一个空元素。顾名思义,此接口对数学集合抽象进行建模。
除了从Collection接口继承的规定之外,Set接口还对所有构造函数的协定以及add,equals和hashCode方法的协定规定了其他规定。为了方便起见,还包括其他继承方法的声明。(这些声明随附的规范是针对Set接口量身定制的,但不包含任何其他规定。)
毫不奇怪,对构造函数的附加规定是,所有构造函数都必须创建一个不包含重复元素的集合(如上定义)。
来自Map
:
将键映射到值的对象。映射不能包含重复的键;每个键最多可以映射到一个值。
如果您可以Set
使用现有代码实现,那么您也可以从现有代码中获得任何好处(例如速度)Set
。
如果您选择Set
不带任何Map
支持的实现,则必须复制旨在防止重复元素的代码。啊,好讽刺。
也就是说,没有什么可以阻止您Set
以不同的方式实现。
问题内容: 在Java 实现中基于对象数组。 谁能解释我为什么使用数组而不是数据存储的实现?使用有什么好处? 问题答案: 在Java中,创建通用类型的数组并不容易。 简单的方法不能编译: 替换为,一切都很好(以容器实现中其他地方增加的复杂性为代价)。 有其他方法,但是它们呈现了一组不同的权衡。有关广泛的讨论,请参见如何在Java中创建通用数组?
是否可以使用地图作为支持对象?
问题内容: 今天打开了LinkedHashSet源代码,发现了一些有趣的东西: 问题是:为什么当HashSet已经是Set时,为什么它们既需要“ extends HashSet”又需要“ implements Set”? 问题答案: 我问过乔什·布洛赫(Josh Bloch),他告诉我这是一个错误。很久以前,他曾经认为其中有一些价值,但是他自从“看到了光”。显然,JDK维护人员认为以后不应该撤消此
我正在尝试编写一个服务器,它通过使用唯一生成的ID来跟踪其客户端。这个想法是,如果我是管理员,并且我想从服务器上引导某人,我就为该客户机查找适当的ClientID(它实际上只是一个字符串;唯一的区别是ClientID类负责确保没有两个客户机被分配了相同的ID),然后输入一个命令,如“kick 12”(如果我想要kick的人的ClientID碰巧是12)。我认为这是可行的,因为我认为可能是通过内部使
1.我了解不同的哈希映射机制和处理密钥冲突的方式(开放寻址-线性/二次探测、链接、可扩展哈希等)。哈希集/哈希映射使用哪一种? 2.我意识到好的哈希映射依赖于好的哈希函数。Java的HashSet/HashMap如何散列对象?我知道有一个散列函数,但到目前为止,对于字符串,我不需要实现它。如果我现在想对我创建的Java对象进行散列-我需要实现散列函数吗?或者Java有一种内置的创建哈希代码的方法吗
例如:私有HashMap 我知道HashMap实现Map,不允许重复的键,HashSet实现Set,不允许重复的值,但是在HashMap中放置HashSet的目的是什么?他们不是自己完成相似的任务吗(尽管方式不同,表现不同)?这样做提供了HashMap本身无法提供的功能?