Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,为什么我们不能在所有场景中通用地使用像HashMap这样的公共数据结构?_Java_Data Structures - Fatal编程技术网

在Java中,为什么我们不能在所有场景中通用地使用像HashMap这样的公共数据结构?

在Java中,为什么我们不能在所有场景中通用地使用像HashMap这样的公共数据结构?,java,data-structures,Java,Data Structures,因为,硬件现在变得非常便宜,并且有非常巨大的可用内存。为什么我们不能在所有场景中通用地使用像HashMap这样的通用数据结构呢?如果没有,是否有一个简短的指南,可以让您知道在哪种场景中使用哪种数据结构 (编辑:此答案假设您是在存储键->值映射的上下文中提问的。如果您的数据不能自然地表示映射,例如字符串列表,那么任何类型的映射都是一种糟糕的表示方式,无论是在性能方面还是在混淆查看您代码的其他人方面) 一般来说,您可以。如果您使用的映射具有不可变键,并且具有适当的hashCode()实现(例如Str

因为,硬件现在变得非常便宜,并且有非常巨大的可用内存。为什么我们不能在所有场景中通用地使用像HashMap这样的通用数据结构呢?如果没有,是否有一个简短的指南,可以让您知道在哪种场景中使用哪种数据结构

(编辑:此答案假设您是在存储
键->值
映射的上下文中提问的。如果您的数据不能自然地表示映射,例如字符串列表,那么任何类型的
映射
都是一种糟糕的表示方式,无论是在性能方面还是在混淆查看您代码的其他人方面)

一般来说,您可以。如果您使用的映射具有不可变键,并且具有适当的
hashCode()
实现(例如
String
,任何自动装箱原语),那么HashMap通常是完全可以接受的

然而,不同的数据结构存在是有原因的——它们都提供了不同的性能(有时是正确性)语义,因此在某些情况下,您可能希望选择其他数据结构

例如,如果希望在迭代过程中以特定顺序访问映射条目(基于键),可以使用
TreeMap
。如果希望迭代顺序基于它们插入的顺序,请使用
LinkedHashMap
。如果希望在简单并发访问下获得良好的性能(使用put if EXPENCE语义)使用
ConcurrentHashMap
。如果键是枚举,则
EnumMap
是最有效的实现。如果要将键存储为弱引用,请使用
WeakHashMap
。如果要基于所使用的确切对象执行查找(使可变键安全),使用
IdentityHashMap

更不用说,如果您知道(但无法更改)键的
hashCode()

您可能还希望数据结构具有许多其他可能的功能,但这些功能不包括(但不限于):

  • 不是键排序或插入顺序的特定迭代顺序
  • 大小有界性(特别是可自定义选择要退出的条目)
  • 键的软/幻影参考
  • 对不存在的密钥执行
    get()
    时的延迟初始化
诸如此类。如果您自己的域对象具有特定的属性,特定的
Map
实现可以利用这些属性来实现更快/更干净/增强的性能(当然,通用库实现永远无法做到这一点),则这种情况尤其可能发生


解决“硬件便宜”的问题语句-这是正确的,但程序员时间和用户时间不是。在某些情况下,应用程序的关键循环可能涉及大量的映射查找,因此加快这些查找将对性能产生显著影响。当然,通常情况并非如此,但如果是这样,请针对特定情况选择性能更好的映射n(我想到的一个简单示例是在适当的情况下使用
EnumMap
)将产生性能提升,这可能非常重要

或者,一些map实现只是使周围的代码更容易编写、更容易理解,并且不太可能隐藏bug。这里的一个例子可能是惰性初始化map(类似于googlecollections的ComputingMap)。虽然您可以围绕标准的
HashMap
编写一些具有lazy init语义的代码,但通过将所有这些逻辑打包到map实现本身中,可以更容易地测试正确性,并且客户机逻辑更简单

因此,廉价的硬件/空间并不意味着HashMaps对任何事情都是最优的。事实上,如果有什么相反的说法的话——与您可能采用的更定制的替代方案相比,HashMaps具有合理的空间效率。有了大量廉价的可用空间,完全有可能在空间和时间之间进行权衡,存储大量信息以加快查找速度



请注意,我将您的问题解释为“为什么您有时会使用其他类的
Map
?”而不是“您应该使用哪些其他
映射以及何时使用?”如果是后者,请随意重新措辞或提出另一个更具体的问题。

因为Hashmap不是有序的,因为稳定的hashcode有时很难定义……由于许多原因,还有其他结构。Java集合教程是一个很好的介绍:

,而Hashmap在许多情况下都很有用iTunes,是的,硬件变得非常便宜,有些情况下信息应该按顺序保存,或者至少按某种类型的顺序保存。此外,在用户可能需要重新排序的数据结构的情况下(例如,学生目录,可以按姓、名、生日、GPA等排序)HashMap可能不是最容易使用的。HashMap仍然可以在我能想到的任何情况下使用,但在许多情况下使用不同的结构可能更容易,而且在计算效率上肯定更高

以下是一些阅读材料:


(CTRL+F“8.4”)

要部分回答问题的第一部分,请注意集合类之间存在重要的差异。选择其中一个作为“默认值”将很棘手

HashMap是一个映射,它并不总是您想要的—有时列表或堆栈是最合适的

要回答问题的第二部分,信不信由你,但我做过的最好的事情之一是阅读集合包的javadoc;每个类都有我发现非常有用的注释