【发布时间】:2011-01-24 15:30:59
【问题描述】:
在 Java 中,ArrayList 和 HashMap 用作集合。但是我不明白在什么情况下应该使用ArrayList,以及在什么时候使用HashMap。两者的主要区别是什么?
【问题讨论】:
-
不仅在 Java 中......“一般”!
标签: java collections arraylist hashmap
在 Java 中,ArrayList 和 HashMap 用作集合。但是我不明白在什么情况下应该使用ArrayList,以及在什么时候使用HashMap。两者的主要区别是什么?
【问题讨论】:
标签: java collections arraylist hashmap
如果使用ArrayList,则必须使用索引(int 类型)访问元素。使用HashMap,您可以通过另一种类型的索引(例如,String)访问它们
HashMap<String, Book> books = new HashMap<String, Book>();
// String is the type of the index (the key)
// and Book is the type of the elements (the values)
// Like with an arraylist: ArrayList<Book> books = ...;
// Now you have to store the elements with a string key:
books.put("Harry Potter III", new Book("JK Rownling", 456, "Harry Potter"));
// Now you can access the elements by using a String index
Book book = books.get("Harry Potter III");
对于ArrayList,这是不可能的(或者更困难的)。访问ArrayList 中元素的唯一好方法是通过索引号获取元素。
因此,这意味着有了HashMap,您可以使用您想要的任何类型的密钥。
另一个有用的例子是在游戏中:你有一组图像,你想翻转它们。所以,你写一个图像翻转方法,然后存储翻转的结果:
HashMap<BufferedImage, BufferedImage> flipped = new HashMap<BufferedImage, BufferedImage>();
BufferedImage player = ...; // On this image the player walks to the left.
BufferedImage flippedPlayer = flip(player); // On this image the player walks to the right.
flipped.put(player, flippedPlayer);
// Now you can access the flipped instance by doing this:
flipped.get(player);
您翻转播放器一次,然后将其存储。您可以使用BufferedImage 作为HashMap 的键类型访问BufferedImage。
希望你能理解我的第二个例子。
【讨论】:
并不是一个真正的 Java 特定问题。看来您需要数据结构的“入门”。尝试谷歌搜索“你应该使用什么数据结构”
试试这个链接http://www.devx.com/tips/Tip/14639
来自链接:
以下是一些将最常用的数据结构与特定需求相匹配的技巧。
如果要以键值对的形式访问存储的数据,则哈希表或类似的数据结构是很好的候选者。例如,如果您要获取员工的姓名,则可以将结果以哈希表的形式作为(名称,值)对返回。但是,如果您要返回多个员工的姓名,则直接返回哈希表不是一个好主意。请记住,键必须是唯一的,否则您之前的值将被覆盖。
当您需要顺序甚至随机访问时,这是一个不错的选择。此外,如果数据大小最初是未知的,和/或将动态增长,则使用 List 或 Vector 是合适的。例如,要存储 JDBC ResultSet 的结果,可以使用 java.util.LinkedList。然而,如果您正在寻找可调整大小的数组,请使用 java.util.ArrayList 类。
永远不要低估数组。大多数时候,当我们必须使用对象列表时,我们倾向于考虑使用向量或列表。但是,如果集合的大小已知并且不会改变,则可以将数组视为潜在的数据结构。访问数组元素比访问向量或列表更快。这很明显,因为您只需要一个索引。没有额外的 get 方法调用的开销。
4.组合
有时,最好结合使用上述方法。例如,您可以使用哈希表列表来满足特定需求。
从 JDK 1.2 开始,您还拥有像 java.util.TreeSet 这样的集合类,这对于没有重复的有序集合很有用。这些类最好的事情之一是它们都遵守特定的接口,这样你就不必担心细节。例如,看看下面的代码。
// ...
List list = new ArrayList();
list.add(
【讨论】:
地图与列表。
在 Map 中,您有键/值对。要访问一个值,您需要知道密钥。键和值之间存在一种关系,这种关系持续存在并且不是任意的。它们以某种方式相关。示例:一个人的 DNA 是唯一的(键)和一个人的名字(值)或一个人的 SSN(键)和一个人的名字(值)有很强的关系。
在列表中,您拥有的只是值(人名),要访问它,您需要知道它在列表(索引)中的位置才能访问它。但是值在列表中的位置和它的索引之间没有永久的关系,它是任意的。
【讨论】:
您专门询问 ArrayList 和 HashMap,但我认为要完全了解发生了什么,您必须了解 Collections 框架。所以 ArrayList 实现了 List 接口,而 HashMap 实现了 Map 接口。所以真正的问题是你什么时候想使用List,什么时候想使用Map。这就是 Java API 文档大有帮助的地方。
列表:
有序集合(也称为 顺序)。该界面的用户 有精确的控制在哪里 列出每个插入的元素。这 用户可以通过他们的访问元素 整数索引(列表中的位置), 并在列表中搜索元素。
地图:
将键映射到值的对象。一种 map 不能包含重复的键; 每个键最多可以映射到一个值。
正如其他答案所讨论的那样,列表接口 (ArrayList) 是您使用索引访问的对象的有序集合,很像数组(就 ArrayList 而言,顾名思义,它只是一个数组在后台,但处理数组的很多细节都为你处理)。当您想要按排序顺序(添加顺序,或者实际上是您在添加对象时指定的列表中的位置)时,您可以使用 ArrayList。
另一方面,Map 接受一个对象并将其用作另一个对象(值)的键(索引)。因此,假设您有具有唯一 ID 的对象,并且您知道您将希望在某个时候通过 ID 访问这些对象,地图将使您非常轻松(并且更快/更高效)。 HashMap 实现使用键对象的哈希值来定位它的存储位置,因此不再保证值的顺序。然而,Java API 中还有其他类可以提供此功能,例如LinkedHashMap 除了使用哈希表来存储键/值对之外,还按照添加顺序维护键的列表(LinkedList),因此您始终可以按照添加顺序再次访问项目(如果需要)。
【讨论】:
将列表用于仅值的有序集合。例如,您可能有一个要处理的文件列表。
使用映射进行从键到值的(通常是无序的)映射。例如,您可能有一个从用户 ID 到该用户详细信息的映射,因此您可以有效地找到仅给定 ID 的详细信息。 (您可以通过仅存储键列表和值列表来实现 Map 接口,但通常会有更有效的实现 - HashMap 在内部使用哈希表来获取例如,摊销 O(1) 密钥查找。)
【讨论】: