在Java中,ArrayList
和HashMap
用作集合。但我无法理解我们应该在哪些情况下使用ArrayList
以及使用HashMap
的时间。两者之间的主要区别是什么?
答案 0 :(得分:76)
您具体询问有关ArrayList和HashMap的内容,但我认为要完全理解您需要了解的集合框架。因此,ArrayList实现List接口,HashMap实现Map接口。所以真正的问题是你何时想要使用List以及何时想要使用Map。这是Java API文档有用的地方。
列表:
有序集合(也称为 序列)。此界面的用户 精确控制在哪里 列表中插入了每个元素。该 用户可以通过他们访问元素 整数索引(列表中的位置), 并搜索列表中的元素。
地图:
将键映射到值的对象。一个 map不能包含重复键; 每个键最多可以映射一个值。
正如其他答案所讨论的那样,列表接口(ArrayList)是您使用索引访问的对象的有序集合,非常类似于数组(在ArrayList的情况下,顾名思义,它只是一个数组在后台,但很多处理数组的细节都是为你处理的)。当你想要按照排序顺序(它们被添加的顺序,或者你添加对象时指定的列表中的位置)保存事物时,你会使用ArrayList。
另一方面,Map获取一个对象并将其用作另一个对象(值)的键(索引)。因此,假设您拥有具有唯一ID的对象,并且您知道您希望在某些时候通过ID访问这些对象,Map将使您更容易(并且更快/更高效)。 HashMap实现使用密钥对象的哈希值来定位它的存储位置,因此不再保证值的顺序。但是,Java API中还有其他类可以提供此类,例如, LinkedHashMap,以及使用哈希表来存储键/值对,还按照添加顺序维护键的List(LinkedList),因此您可以按照添加的顺序再次访问项目(如果需要的话。)
答案 1 :(得分:16)
如果您使用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
作为BufferedImage
的密钥类型访问HashMap
。
我希望你理解我的第二个例子。
答案 2 :(得分:14)
不是特定于Java的问题。看来你需要一个关于数据结构的“入门”。尝试谷歌搜索“你应该使用什么数据结构”
试试此链接http://www.devx.com/tips/Tip/14639
从链接:
以下是将最常用的数据结构与特定需求相匹配的一些技巧。
如果要以键值对的形式访问存储的数据,则哈希表或类似的数据结构是很好的候选者。例如,如果您正在获取员工的姓名,则结果可以以哈希表的形式作为(名称,值)对返回。但是,如果要返回多个员工的名称,则直接返回哈希表并不是一个好主意。请记住,密钥必须是唯一的,否则您的先前值将被覆盖。
当您需要连续或甚至随机访问时,这是一个不错的选择。此外,如果数据大小最初未知,和/或将动态增长,则使用List或Vector是合适的。例如,要存储JDBC ResultSet的结果,可以使用java.util.LinkedList。然而,如果您正在寻找可调整大小的数组,请使用java.util.ArrayList类。
永远不要低估数组。大多数情况下,当我们必须使用对象列表时,我们倾向于考虑使用向量或列表。但是,如果集合的大小已知并且不会更改,则可以将数组视为潜在的数据结构。访问数组的元素比使用向量或列表更快。这很明显,因为你需要的只是一个索引。额外的get方法调用没有开销。
4.Combinations
有时,最好使用上述方法的组合。例如,您可以使用哈希表列表来满足特定需求。
从JDK 1.2开始,您还设置了类java.util.TreeSet,这对于没有重复项的排序集非常有用。这些课程最好的一点是他们都遵守某些界面,所以你不必担心具体细节。例如,请查看以下代码。
// ...
List list = new ArrayList();
list.add(
答案 3 :(得分:4)
将列表用于仅有值的有序集合。例如,您可能有一个要处理的文件列表。
使用映射表示从键到值的(通常是无序的)映射。例如,您可能有一个从用户ID到该用户详细信息的映射,因此您可以有效地查找仅给出ID的详细信息。 (你可以通过存储密钥列表和值列表来实现Map
接口,但通常会有更高效的实现 - HashMap
使用哈希例如,内部表用于分摊O(1)键查找。)
答案 4 :(得分:4)
地图与列表。
在地图中,您有键/值对。要访问值,您需要知道密钥。密钥和值之间存在关系,该关系持续存在且不是任意的。它们以某种方式相关。例如:人的DNA是唯一的(钥匙)和人名(价值)或人SSN(钥匙)和人名(价值)有很强的关系。
在列表中,您拥有的只是值(人名),要访问它,您需要知道它在列表(索引)中的位置才能访问它。但是列表中的值的位置与其索引之间没有永久关系,它是任意的。