Java中HashMap和ArrayList的区别是什么?

45
在Java中,ArrayListHashMap被用作集合。但我不明白应该在什么情况下使用ArrayList和什么时候使用HashMap。它们之间的主要区别是什么?

4
不仅在Java中如此,而是“总体上”都是如此! - Andrei Ciobanu
6个回答

82
您特别询问ArrayList和HashMap,但我认为要完全理解发生了什么,您必须理解集合框架。所以一个ArrayList实现了List接口,而一个HashMap实现了Map接口。因此,真正的问题是何时使用列表,何时使用映射。这就是Java API文档帮助很多的地方。
List:
有序集合(也称为序列)。该接口的用户可以精确控制列表中每个元素插入的位置。用户可以按其整数索引(在列表中的位置)访问元素,并在列表中搜索元素。
Map:
将键映射到值的对象。映射不包含重复键;每个键最多可以映射到一个值。
因此,正如其他答案所讨论的那样,列表接口(ArrayList)是一组有序的对象,您可以使用索引访问它们,就像数组一样(在ArrayList的情况下,正如名称所暗示的那样,它只是后台中的一个数组,但处理数组的大部分细节都为您处理)。当您想要保持排序(添加的顺序或者确切指定的位置)时,会使用ArrayList。
另一方面,Map采用一个对象并将其用作另一个对象(值)的键(索引)。因此,假设您具有具有唯一ID的对象,并且您知道您将来要按ID访问这些对象,Map将使您非常轻松(更快/更高效)。 HashMap实现使用键对象的哈希值来定位其存储位置,因此不再保证值的顺序。但是,Java API中还有其他类可以提供此功能,例如LinkedHashMap。除了使用哈希表存储键/值对之外,LinkedHashMap还维护一个按它们添加的顺序的键列表(LinkedList),因此如果需要,您始终可以再次按添加顺序访问项目。

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);

你翻转了玩家一次,然后将其存储。你可以使用HashMapBufferedImage作为键类型来访问BufferedImage

希望你能理解我的第二个示例。


14

这不是一个特定于Java的问题。看起来你需要了解数据结构的基础知识。尝试搜索“您应该使用哪种数据结构”。

可以尝试这个链接:http://www.devx.com/tips/Tip/14639

以下是一些关于如何匹配常用数据结构和特定需求的提示:

  1. 什么时候使用Hashtable?

如果存储的数据以键值对的形式访问,则hashtable或类似的数据结构是很好的选择。例如,如果您要获取雇员的名称,则结果可以作为哈希表中的(名称,值)对返回。但是,如果您要返回多个雇员的名称,则直接返回哈希表可能不是一个好主意。请记住,键必须是唯一的,否则您以前的值将被覆盖。

  1. 什么时候使用List或Vector?

当需要按顺序或随机访问时,这是一个很好的选择。而且,如果初始数据大小未知,或者会动态增长,那么使用List或Vector是适合的。例如,要存储JDBC ResultSet的结果,可以使用java.util.LinkedList。而如果您正在寻找一个可调整大小的数组,则使用java.util.ArrayList类。

  1. 什么时候使用数组?

永远不要低估数组的作用。大多数情况下,当我们需要使用对象列表时,我们倾向于使用向量或列表。然而,如果集合的大小已知且不会改变,则可以考虑数组作为潜在的数据结构。访问数组元素比vector或list更快。这是显而易见的,因为您只需要一个索引。没有额外的get方法调用的开销。

4.组合

有时,最好使用以上方法的组合。例如,您可以使用哈希表的列表来满足特定需求。

  1. Set类

从JDK 1.2开始,您还可以使用集合类,如java.util.TreeSet,它对于没有重复项的排序集很有用。这些类中最好的事情之一是它们都遵循某些接口,因此您无需真正担心具体实现。例如,请看以下代码:

  // ...
  List list = new ArrayList();
  list.add(

我添加了链接中的信息,因为它可能会在以后失效。 - Blaze Tama

4
使用列表来存储有序的值集合。例如,您可能有一个要处理的文件列表。
使用映射来存储(通常是无序的)从键到值的映射关系。例如,您可能有一个从用户ID到该用户详细信息的映射,这样您就可以在只知道ID的情况下高效地查找详细信息。(您可以通过仅存储键列表和值列表来实现Map接口,但通常会有更有效的实现方式-例如,HashMap在内部使用哈希表以获得平摊O(1)的键查找时间复杂度。)

4

Map和List的区别。

在Map中,你有键/值对。要访问一个值,你需要知道它的键。键和值之间存在一种关系,这种关系是持久存在且不是任意的。例如:人类的DNA是独一无二的(键),人名(值)或社会安全号码(键)和人名(值)之间存在着强烈的关系。

而在List中,你只有值(比如人名),要访问这些值,你需要知道它们在列表中的位置(索引)。但是值在列表中的位置和它的索引之间没有永久的关系,这是任意的。


0
在使用ArrayList和HashMap之前,我们应该考虑以下几点。
ArrayList:
- Java的ArrayList实现了List接口 - ArrayList始终保持元素的插入顺序 - ArrayList只存储值或元素 - ArrayList可以包含重复元素 - 我们可以在ArrayList中有任意数量的null元素 - ArrayList的get()方法始终具有O(1)的性能
HashMap:
  • Java的HashMap实现了Map接口
  • HashMap不保持插入顺序。
  • HashMap存储键值对
  • HashMap不包含重复的键,但可以包含重复的值。
  • HashMap中,我们只能有一个空键和任意数量的空值
  • HashMapget()方法在最好的情况下可以是O(1),在最坏的情况下可以是O(n)

示例:

// Importing all utility classes
import java.util.*;

// Main class
class Demo {
    public static void main(String args[]) {
        // Creating ArrayList of string type
        ArrayList<String> list = new ArrayList<String>();

        // Adding values in ArrayList using standard add() method
        list.add("A");
        list.add(null); // Adding first null value
        list.add("C");
        list.add(null); // Adding second null value
        list.add(null); // Adding third null value

        // Printing ArrayList object
        System.out.println("ArrayList: " + list);

        //Creating HashMap object of integer and string type
        HashMap<Integer, String> hm = new HashMap<Integer, String>();

        // Adding value in HashMap using standard put method
        hm.put(1, "A");
        hm.put(2, "B");
        hm.put(null, "C"); // Adding first null key
        hm.put(null, null); // Again adding null key which replace value of first insert null key value
        hm.put(3, null); // Adding second null value with different key

        // Printing the elements of Hashmap
        System.out.println("HashMap: " + hm);
    }
}

输出

ArrayList: [A, null, C, null, null]
HashMap: {null=null, 1=A, 2=B, 3=null}

在上面的输出中,我们可以看到ArrayList包含重复的null值,而Hashmap包含重复的null值,但键不重复。 当我们使用已存在的键添加值时,HashMap会替换为新值。
参考:https://www.geeksforgeeks.org/difference-between-arraylist-and-hashmap-in-java/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接