Map.clear()与新地图:哪一个会更好?

我有一个Map语法为Map<String, String> testMap = new HashMap<String, String>(); 。 在这张地图上可以有1000个数据。

当我的应用程序需要新的数据列表,那么我必须清除地图。 但是当我看到Map.clear()的代码为

 /** * Removes all of the mappings from this map. * The map will be empty after this call returns. */ public void clear() { modCount++; Entry[] tab = table; for (int i = 0; i < tab.length; i++) tab[i] = null; size = 0; } 

我意识到清晰的方法循环n次(其中n是Map中的数据数量)。 所以我认为可以有一种方法来重新定义该地图为testMap = new HashMap<String, String>(); 而以前用过的Map会被垃圾收集。

但我不确定这是一个好方法。 我正在开发移动应用程序。

你能指导我吗?

复杂的问题。 让我们看看发生了什么。

你实例化一个新的实例,它是由新的数组支持的。 所以,垃圾收集器应该清除前一个地图中的所有键和值,并清除对自身的引用。 所以O(n)algorithm无论如何都被执行,但是在垃圾回收器线程中。 对于1000条logging,您不会看到任何区别。 但。 性能指南告诉你,如果可以,最好不要创build新的对象。 所以我会去clear()方法。

无论如何,尝试两个变种,并尝试衡量。 总是衡量!

当你在大小为n的地图上说Map.clear() …你要求GC清理2*n (Key&Value)对象。 当你对同一个Map说null ,你要求GC清理2*n+1 (对于Map本身)对象。 然后你将不得不创build一个新的Map实例,但又有一个开销。 所以去Map.clear() 。 在实例化Map时,预先设定Map的大小是明智的。

我认为在java中创build对象在内存方面更加昂贵,所以最好使用.clear() ,所以你使用相同的对象而不是创build新的对象

使用clear()方法的想法是从地图中去除对其他对象的引用,以便如果“地图在其他地方被引用”,那么key /值不会从gcing中被阻止。

但是如果你的地图是一个只用于你的特定代码的地方地图(即“地图不是”在其他地方引用),那么请继续使用新的地图,但是将1000个引用设置为null不会是一个很大的性能影响无论如何。

map.clear()将删除所有数据。 请注意,这只会放弃所有条目,但保留内部数组用于存储条目相同的大小(而不是缩小到初始容量)。 如果你还需要消除这种情况,最简单的方法就是丢弃整个HashMap并用新的实例replace它。 当然,只有当你控制谁有一个指向地图的指针才有效。

至于回收内存,你将不得不让垃圾收集器的工作。

你的价值观是否也是龙? 在这种情况下,您可能希望查看比通用HashMap更多(内存)高效的实现,例如GNU Trove库中的TLongLongHashMap。 这应该可以节省大量的内存。

我认为调用新的HashMap()是一个更好的主意,因为它不需要做像清理散列表一样的处理。 另外,通过创build一个新的散列映射,您将消除散列映射仍然可能绑定到使用该数据的控件的可能性,这将在清除散列映射时导致问题。

不要忘记地图的重新填充

如果你没有在新地图上指定容量,那么在新创build的地图上将会产生相当多的开销,因为重新映射(每个都是O(n)(当时)并且发生O(log(n))而这可能会分摊到O(n)总数,但是如果它们没有发生在第一位,那么你仍然会更好)

这在清除的地图中不会发生,因为容量不会改变