6

在我的代码中,我默认对所有列表使用 ArrayList,对所有映射使用 HashMap,对所有集合使用 HashSet。

从实际的角度来看,由于选择了错误的实现,我在灵活性、可扩展性、可读性和性能方面损失了多少?什么时候花时间决定使用一个而不是另一个有意义?

我当然看到了一个非常明确的案例,说明为什么在某些情况下有人会使用 LinkedList 而不是 ArrayList。什么时候有人觉得使用 HashMap 而不是 TreeMap 或 HashTable 很重要?套装呢?

问题:

  1. 选择不当的代价是什么?
  2. 有没有人有关于选择错误的实施和数据中心着火的灾难故事?
  3. 有什么好的经验法则吗?
  4. 有没有你不能没有的晦涩的集合实现?

我已通读:

我发现从理论的角度来看这个问题是相关的,但我对现实世界更感兴趣,在战壕中回答。

4

3 回答 3

7

这是一个非常普遍的问题,但我会提出几个想法。

如果您是面向接口的编程,那么灵活性不会受到很大影响。例如

void foo(List<E> list);

选择不当的代价可以从性能损失中看出。例如,在直接访问(如在 ArrayList 中)时选择 LinkedList 是您要寻找的。

集合有一个类似的问题。如果您想保留没有重复的排序集合,SortedSet 将是比 HashSet 更明智的选择。在后一种情况下,您必须手动对整个 Set 进行排序(这是对 Collections.sort() 的调用)

<EDIT>

至于地图,有很多不同的实现。每个人都有不同的目的。例如,有SortedMap,类似于 SortedSet。然后是WeakHashMap,它不像 HashMap 那样工作,因为垃圾收集器可以删除键。可以想象,在 HashMap 和 WeakHashMap 之间进行选择并非易事。与往常一样,取决于您想用它们实现什么。

</EDIT>

关于这个故事,在我当前的项目中,我们用 SortedSet 替换了 HashSet,因为性能受到了影响。不过,DataCenter 并没有起火。

我的两分钱。

于 2009-06-23T16:03:46.577 回答
1

只要您遵循依赖于抽象类型的良好 OO 实践,这有什么关系?

例如,如果您发现使用错误Map,您只需更改您正在使用的实现,因为您的所有依赖项都Map像以前一样工作,只是具有不同的性能特征。

于 2009-06-23T16:05:42.270 回答
1

我认为您可以使用 HashMap、HashSet 和 ArrayList 作为主要实现。当您需要一个排序集时,最好知道 TreeSet 可用;当你在做递归的事情时,类似地,在你的后兜里有 LinkedList 是件好事。但是编程到接口,然后您可以根据需要交换实现。如果同一个集合需要同时处理(例如)一个 LinkedList 和一个 ArrayList,那么从另一个构建一个并没有什么大不了的。

使用您列出的默认实现。当存在性能问题,并且有理由相信替代实现会更好时,将其换掉 - 并衡量差异。当您需要特殊行为(例如,排序集)时,请使用特殊类。

这种方法还没有烧到我。

于 2009-06-23T18:14:46.080 回答