Java集合框架

集合框架被设计成要满足以下几个目标

  • 该框架必须时高性能的,基本集合(动态数组,链表,树,哈希表)的实现也必须时高效的
  • 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性
  • 对一个集合的扩展和适应必须时简单的

为此,整个集合框架就围绕一组标准接口而设计。你可以直接使用这些接口的标准实现的,诸如:LinkedList,HashSet和TreeSet等,除此之外你也可以通过这些接口实现自己的集合
image.png
从上面的集合框架图可以看到,Java集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一中是图(Map),存储键/值对映射;Collecation接口又有3种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkHashSet、HashMap、LinkedHashMap等等
集合框架是一个用来代表和操纵集合的统一架构,所有的集合框架都包含如下内容:

  • 接口:是代表集合的抽象数据类型,例如 Collection、List、Set、Map等。之所以定义多个接口,是为了以不同的方式操作集合对象
  • 实现(类):是集合接口的具体实现,从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap
  • 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序,这些算法被称为多态,那是因为相同的方法可以再相似的接口上有着不同的实现

除了集合,该框架也定义了几个Map接口和类,Map里存储的是键/值对;尽管Map不是集合,但是它们完全整合再集合中

集合框架体系如图所示

image.png
Java集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中,所以当使用集合框架的时候需要进行导包

集合接口

集合框架定义了一些接口,本节提供了每个接口的概述:
image.png

Set和List的区别

  • Set接口实例存储的是无序的,不重复的数据;List接口实例存储的是有序的,可以重复的元素
  • Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变<实现类有HashSet,TreeSet>
  • List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度;查找元素效率高,插入删除效率低,因为会引起其他元素改变<实现类有ArrayList,LinkedList,Vector>

    集合实现类

    Java提供了一套实现了Collerction接口的标准集合类,其中一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现
    标准集合类汇总于下表:
    image.png
    image.png
    在前面的教程中已经讨论通过java.util包中定义的类,如下所示:
    image.png

    集合算法

    集合框架定义了几种算法,可用于集合和映射;这些算法被定义为集合类的静态方法。
    在尝试比较不兼容的类型时,一些方法能够抛出ClassCastException异常;当试图修改一个不可修改的集合时,抛出UnsupportedOperationException异常
    集合定义三个静态的变量:EMPTY_SET,EMPTY_LIST,EMPTY_MAP的;这些变量都不可改变
    image.png

    如何使用迭代器

    通常情况下,你会希望遍历一个集合中的元素;例如,显示集合中的每个元素
    一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但时还有一种方法时采用迭代器遍历集合框架,它是一个对象,实现了 lterator接口或Listlterator接口
    迭代器,使你能够通过循环来得到或删除集合的元素;Listlterator继承了lterator,以允许双向遍历列表和修改元素\
    image.png

    遍历ArrayList

    ```java import java.util.*;

public class Test{ public static void main(String[] args) { List list=new ArrayList(); list.add(“Hello”); list.add(“World”); list.add(“HAHAHAHA”); //第一种遍历方法使用 For-Each 遍历 List for (String str : list) { //也可以改写 for(int i=0;i<list.size();i++) 这种形式 System.out.println(str); }

  1. //第二种遍历,把链表变为数组相关的内容进行遍历
  2. String[] strArray=new String[list.size()];
  3. list.toArray(strArray);
  4. for(int i=0;i<strArray.length;i++) //这里也可以改写为 for(String str:strArray) 这种形式
  5. {
  6. System.out.println(strArray[i]);
  7. }
  8. //第三种遍历 使用迭代器进行相关遍历
  9. Iterator<String> ite=list.iterator();
  10. while(ite.hasNext())//判断下一个元素之后有值
  11. {
  12. System.out.println(ite.next());
  13. }

} }

  1. <a name="zFWvZ"></a>
  2. ### 解析
  3. 三种方法都是用来遍历ArrayList集合,第三种方法是采用迭代器的方法,该方法可以不用担心在遍历的过程中会超出集合的长度
  4. <a name="qCXIs"></a>
  5. ## 遍历Map
  6. ```java
  7. import java.util.*;
  8. public class Test{
  9. public static void main(String[] args) {
  10. Map<String, String> map = new HashMap<String, String>();
  11. map.put("1", "value1");
  12. map.put("2", "value2");
  13. map.put("3", "value3");
  14. //第一种:普遍使用,二次取值
  15. System.out.println("通过Map.keySet遍历key和value:");
  16. for (String key : map.keySet()) {
  17. System.out.println("key= "+ key + " and value= " + map.get(key));
  18. }
  19. //第二种
  20. System.out.println("通过Map.entrySet使用iterator遍历key和value:");
  21. Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
  22. while (it.hasNext()) {
  23. Map.Entry<String, String> entry = it.next();
  24. System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
  25. }
  26. //第三种:推荐,尤其是容量大时
  27. System.out.println("通过Map.entrySet遍历key和value");
  28. for (Map.Entry<String, String> entry : map.entrySet()) {
  29. System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
  30. }
  31. //第四种
  32. System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
  33. for (String v : map.values()) {
  34. System.out.println("value= " + v);
  35. }
  36. }
  37. }

如何使用比较器

TreeSet和TreeMap的按照排序顺序来存储元素,然而,这是通过比较器来精确定义按照什么样的排序顺序
这个接口可以让我们以不同的方式来排序一个集合
image.png

总结

Java集合框架为程序员提供了预先包装的数据结构和算法来操纵他们
集合是一个对象,可容纳其他对象的引用;集合接口声明对每一种类型的集合可以执行的操作
集合框架的类和接口均在java.util包中
任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换

Java ArrayList

ArrayList类是一个可以动态修改的数组,于普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素
ArrayList继承了AbstractList,并实现了List接口
image.png
ArrayList类位于java.util包中,使用前需要引入它,语法格式如下:

  1. import java.util.ArrayList; // 引入 ArrayList 类
  2. ArrayList<E> objectName =new ArrayList<>();  // 初始化
  • E:泛型数据类型,用于设置objectName的数据类型,只能为引用数据类型
  • objectName:对象名

ArrayList是一个数组队列,提供了相关的添加、删除、修改、遍历等功能

添加元素

ArrayList类提供了很多有用的方法,添加元素到ArrayList可以使用add()方法:

  1. import java.util.ArrayList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. ArrayList<String> sites = new ArrayList<String>();
  5. sites.add("Google");
  6. sites.add("Runoob");
  7. sites.add("Taobao");
  8. sites.add("Weibo");
  9. System.out.println(sites);
  10. }
  11. }
  12. 结果为
  13. [Google, Runoob, Taobao, Weibo]

访问元素

访问ArrayList中的元素可以使用get()方法

  1. import java.util.ArrayList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. ArrayList<String> sites = new ArrayList<String>();
  5. sites.add("Google");
  6. sites.add("Runoob");
  7. sites.add("Taobao");
  8. sites.add("Weibo");
  9. System.out.println(sites.get(1)); // 访问第二个元素
  10. }
  11. }
  12. 结果为
  13. Runoob

修改元素

如果要修改ArrayList中的元素可以使用set()方法:

  1. import java.util.ArrayList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. ArrayList<String> sites = new ArrayList<String>();
  5. sites.add("Google");
  6. sites.add("Runoob");
  7. sites.add("Taobao");
  8. sites.add("Weibo");
  9. sites.set(2, "Wiki"); // 第一个参数为索引位置,第二个为要修改的值
  10. System.out.println(sites);
  11. }
  12. }
  13. 结果为:
  14. [Google, Runoob, Wiki, Weibo]

删除元素

如果要删除ArrayList中的元素可以使用remove()方法:

  1. import java.util.ArrayList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. ArrayList<String> sites = new ArrayList<String>();
  5. sites.add("Google");
  6. sites.add("Runoob");
  7. sites.add("Taobao");
  8. sites.add("Weibo");
  9. sites.remove(3); // 删除第四个元素
  10. System.out.println(sites);
  11. }
  12. }
  13. 结果为
  14. [Google, Runoob, Taobao]

计算大小

如果要计算ArrayList中的元素数量可以是使用size()方法

  1. import java.util.ArrayList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. ArrayList<String> sites = new ArrayList<String>();
  5. sites.add("Google");
  6. sites.add("Runoob");
  7. sites.add("Taobao");
  8. sites.add("Weibo");
  9. System.out.println(sites.size());
  10. }
  11. }
  12. 结果为:
  13. 4

迭代数组列表

我们可以使用for来迭代数组列表中的元素:

  1. import java.util.ArrayList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. ArrayList<String> sites = new ArrayList<String>();
  5. sites.add("Google");
  6. sites.add("Runoob");
  7. sites.add("Taobao");
  8. sites.add("Weibo");
  9. for (int i = 0; i < sites.size(); i++) {
  10. System.out.println(sites.get(i));
  11. }
  12. }
  13. }
  14. 结果为:
  15. Google
  16. Runoob
  17. Taobao
  18. Weibo

也可以使用for-each来迭代元素:

  1. import java.util.ArrayList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. ArrayList<String> sites = new ArrayList<String>();
  5. sites.add("Google");
  6. sites.add("Runoob");
  7. sites.add("Taobao");
  8. sites.add("Weibo");
  9. for (String i : sites) {
  10. System.out.println(i);
  11. }
  12. }
  13. }
  14. 结果为:
  15. Google
  16. Runoob
  17. Taobao
  18. Weibo

其他的引用类型

ArrayList中的元素实际上是对象,在以上实例中,数组列表元素都是字符串String类型。
如果我们要存储其他类型,而只能为引用数据类型,这时我们就需要使用到基本类型的包装类
基本类型对应的包装类表如下:
image.png
此外,bigInteger、BigDecimal用于高精度的运算,BigInteger支持任意精度的整数,也是引用类型,但它们没有相对应的基本类型

  1. ArrayList<Integer> li=new Arraylist<>(); // 存放整数元素
  2. ArrayList<Character> li=new Arraylist<>(); // 存放字符元素

以下实例使用ArrayList存储数字(使用Integer类型·)

  1. import java.util.ArrayList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. ArrayList<Integer> myNumbers = new ArrayList<Integer>();
  5. myNumbers.add(10);
  6. myNumbers.add(15);
  7. myNumbers.add(20);
  8. myNumbers.add(25);
  9. for (int i : myNumbers) {
  10. System.out.println(i);
  11. }
  12. }
  13. }
  14. 结果为:
  15. 10
  16. 15
  17. 20
  18. 25

ArrayList排序

Collecations类也是一个非常有用的类,位于java.util包中,提供的sort()方法可以对字符或数组列表进行排序
以下实例对字母进行排序

  1. import java.util.ArrayList;
  2. import java.util.Collections; // 引入 Collections 类
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. ArrayList<String> sites = new ArrayList<String>();
  6. sites.add("Taobao");
  7. sites.add("Wiki");
  8. sites.add("Runoob");
  9. sites.add("Weibo");
  10. sites.add("Google");
  11. Collections.sort(sites); // 字母排序
  12. for (String i : sites) {
  13. System.out.println(i);
  14. }
  15. }
  16. }
  17. 结果为:
  18. Google
  19. Runoob
  20. Taobao
  21. Weibo
  22. Wiki

以下实例对数字进行排序:

  1. import java.util.ArrayList;
  2. import java.util.Collections; // 引入 Collections 类
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. ArrayList<Integer> myNumbers = new ArrayList<Integer>();
  6. myNumbers.add(33);
  7. myNumbers.add(15);
  8. myNumbers.add(20);
  9. myNumbers.add(34);
  10. myNumbers.add(8);
  11. myNumbers.add(12);
  12. Collections.sort(myNumbers); // 数字排序
  13. for (int i : myNumbers) {
  14. System.out.println(i);
  15. }
  16. }
  17. }
  18. 结果为:
  19. 8
  20. 12
  21. 15
  22. 20
  23. 33
  24. 34

Java ArrayList方法

Java ArrayList常用方法列表如下
image.png
image.png

Java LinkedList

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址
链表可分为单向链和双向链表
一个单向链表包含两个值,当前节点的值和一个指向下一个节点的链接
image.png
一个·双向链表有三个整数值:数值、向后的节点链接、向前的节点链接
image.png
Java LinkedList(链表)类似于ArrayList,是一种常用的数据容器
于ArrayList相比,LinkedList的增加和删除对操作效率更高,而查找和修改的操作效率较低
以下情况使用ArrayList:

  • 频繁访问列表种的某一个元素
  • 只需要在列表末尾进行添加和删除元素操作

以下情况使用LinkedList:

  • 你需要通过循环迭代来访问列表中的某些元素
  • 需要频繁的在列表的开头、中间、末尾等位置进行添加和删除元素操作

LinkedList继承了AbstractSequentialList类
LinkedList实现了Queue接口,可作为队列使用
LinkedList实现了List接口,可进行列表的相关操作
LinkedList实现了Deque接口,可作为队列使用
LinkedList实现了Cloneable接口,可实现克隆
LinkedList实现了java.io.Serialzable接口,即可支持序列化,能通过序列化去传输
image.png
LinkedList类位于java.util包中,使用钱需要引入它,语法格式如下:

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. LinkedList<E> list = new LinkedList<E>(); // 普通创建方法
  4. 或者
  5. LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合创建链表

创建一个简单的链表实例:

  1. import java.util.LinkedList;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. LinkedList<String> sites = new LinkedList<String>();
  5. sites.add("Google");
  6. sites.add("Runoob");
  7. sites.add("Taobao");
  8. sites.add("Weibo");
  9. System.out.println(sites);
  10. }
  11. }
  12. 结果为:
  13. [Google, Runoob, Taobao, Weibo]

更多的情况下使用ArrayList访问列表中的随机元素更加高效,但以下几种情况LinkedList提供了更高效的方法:
在列表开头添加元素:

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. LinkedList<String> sites = new LinkedList<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. // 使用 addFirst() 在头部添加元素
  10. sites.addFirst("Wiki");
  11. System.out.println(sites);
  12. }
  13. }
  14. 结果为
  15. [Wiki, Google, Runoob, Taobao]

在列表结尾添加元素:

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. LinkedList<String> sites = new LinkedList<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. // 使用 addLast() 在尾部添加元素
  10. sites.addLast("Wiki");
  11. System.out.println(sites);
  12. }
  13. }
  14. 结果为:
  15. [Google, Runoob, Taobao, Wiki]

在列表开头移除元素:

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. LinkedList<String> sites = new LinkedList<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Weibo");
  10. // 使用 removeFirst() 移除头部元素
  11. sites.removeFirst();
  12. System.out.println(sites);
  13. }
  14. }
  15. 结果为:
  16. [Runoob, Taobao, Weibo]

在列表结尾移除元素:

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. LinkedList<String> sites = new LinkedList<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Weibo");
  10. // 使用 removeLast() 移除尾部元素
  11. sites.removeLast();
  12. System.out.println(sites);
  13. }
  14. }
  15. 结果为:
  16. [Google, Runoob, Taobao]

获取列表开头的元素:

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. LinkedList<String> sites = new LinkedList<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Weibo");
  10. // 使用 getFirst() 获取头部元素
  11. System.out.println(sites.getFirst());
  12. }
  13. }
  14. 结果为:
  15. Google

获取列表结尾的元素:

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. LinkedList<String> sites = new LinkedList<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Weibo");
  10. // 使用 getLast() 获取尾部元素
  11. System.out.println(sites.getLast());
  12. }
  13. }
  14. 结果为:
  15. Weibo

迭代元素

我们可以使用for配合size()方法来迭代列表中的元素

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. LinkedList<String> sites = new LinkedList<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Weibo");
  10. for (int size = sites.size(), i = 0; i < size; i++) {
  11. System.out.println(sites.get(i));
  12. }
  13. }
  14. }
  15. 结果为:
  16. Google
  17. Runoob
  18. Taobao
  19. Weibo

也可以使用for-each来迭代元素

  1. // 引入 LinkedList 类
  2. import java.util.LinkedList;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. LinkedList<String> sites = new LinkedList<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Weibo");
  10. for (String i : sites) {
  11. System.out.println(i);
  12. }
  13. }
  14. }
  15. 结果为:
  16. Google
  17. Runoob
  18. Taobao
  19. Weibo

常用方法

image.png
image.png

Java HashSet

HashSet基于HashMap来实现的,是一个不允许有重复元素的集合
HashSet允许有null值
HashSet是无序的,即不会记录插入的顺序
HashSet不是线程安全的,如果多个线程尝试同时修改HashSet,则最终结果是不确定的,您必须在多线程访问时显式同步对HashSet的并发访问
HashSet实现了Set接口
image.png
HashSet中的元素实际上是对象,,一些常见的基本类型可以使用它的包装类
基本类型对应的包装类表如下:
image.png
HashSet类位于java.util包中,使用前需要引入它,语法格式如下:

  1. import java.util.HashSet; // 引入 HashSet 类

以下实例我们创建一个HashSet对象sites,用于保存字符串元素

  1. HashSet<String> sites = new HashSet<String>();

添加元素

HashSet类提供类很多有用的方法,添加元素可以使用add()方法

  1. // 引入 HashSet 类
  2. import java.util.HashSet;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. HashSet<String> sites = new HashSet<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Zhihu");
  10. sites.add("Runoob"); // 重复的元素不会被添加
  11. System.out.println(sites);
  12. }
  13. }
  14. 结果为:
  15. [Google, Runoob, Zhihu, Taobao]

在上面的实例中,Runoob被添加了两次,它在集合中也只会出现一次,因为集合中的每个元素都必须是唯一的

判断元素是否存在

我们可以使用 contains() 方法来判断元素是否存在于集合当中

  1. // 引入 HashSet 类
  2. import java.util.HashSet;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. HashSet<String> sites = new HashSet<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Zhihu");
  10. sites.add("Runoob"); // 重复的元素不会被添加
  11. System.out.println(sites.contains("Taobao"));
  12. }
  13. }
  14. 结果为:
  15. true

删除元素

  1. // 引入 HashSet 类
  2. import java.util.HashSet;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. HashSet<String> sites = new HashSet<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Zhihu");
  10. sites.add("Runoob"); // 重复的元素不会被添加
  11. sites.remove("Taobao"); // 删除元素,删除成功返回 true,否则为 false
  12. System.out.println(sites);
  13. }
  14. }
  15. 结果为:
  16. [Google, Runoob, Zhihu]

删除集合中所以元素可以使用 clear 方法:

  1. // 引入 HashSet 类
  2. import java.util.HashSet;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. HashSet<String> sites = new HashSet<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Zhihu");
  10. sites.add("Runoob"); // 重复的元素不会被添加
  11. sites.clear();
  12. System.out.println(sites);
  13. }
  14. }
  15. 结果为:
  16. []

计算大小

如果要计算HashSet中的元素数量可以使用size()方法

  1. // 引入 HashSet 类
  2. import java.util.HashSet;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. HashSet<String> sites = new HashSet<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Zhihu");
  10. sites.add("Runoob"); // 重复的元素不会被添加
  11. System.out.println(sites.size());
  12. }
  13. }
  14. 结果为:
  15. 4

迭代HashSet

可以使用 for-each来迭代 HashSet中的元素

  1. // 引入 HashSet 类
  2. import java.util.HashSet;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. HashSet<String> sites = new HashSet<String>();
  6. sites.add("Google");
  7. sites.add("Runoob");
  8. sites.add("Taobao");
  9. sites.add("Zhihu");
  10. sites.add("Runoob"); // 重复的元素不会被添加
  11. for (String i : sites) {
  12. System.out.println(i);
  13. }
  14. }
  15. }
  16. 结果为:
  17. Google
  18. Runoob
  19. Zhihu
  20. Taobao

Java HashMap

HashMap是散列表,它存储的内容是键值对(key-value)映射
HashMap实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步
HashMap是无序的,即不会记录插入的顺序
HashMap继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口
image.png
HashMap的key与value类型可以相同也可以不同,可以是字符串(String)类型的key和value,也可以是整型(Integer)的key与字符串(String)类型的value
image.png
HashMap中的元素实际上是对象,一些常见的基本类型可以使用它的包装类
基本类型对应的包装类表如下:
image.png
HashMap类位于java.util包中,使用前需要引入它,语法格式如下:

  1. import java.util.HashMap; // 引入 HashMap 类

以下实例我们创建一个HashMap对象Sites,整型(Integer)的key和字符串(String)类型的value:

  1. HashMap<Integer, String> Sites = new HashMap<Integer, String>();

添加元素

HashMap类提供类很多有用的方法,添加键值对(key-value)可以使用put()方法:

  1. // 引入 HashMap 类
  2. import java.util.HashMap;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. // 创建 HashMap 对象 Sites
  6. HashMap<Integer, String> Sites = new HashMap<Integer, String>();
  7. // 添加键值对
  8. Sites.put(1, "Google");
  9. Sites.put(2, "Runoob");
  10. Sites.put(3, "Taobao");
  11. Sites.put(4, "Zhihu");
  12. System.out.println(Sites);
  13. }
  14. }
  15. 结果为:
  16. {1=Google, 2=Runoob, 3=Taobao, 4=Zhihu}

以下实例创建一个字符串(String)类型的key和字符串(String)类型的value:

  1. import java.util.HashMap;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. // 创建 HashMap 对象 Sites
  5. HashMap<String, String> Sites = new HashMap<String, String>();
  6. // 添加键值对
  7. Sites.put("one", "Google");
  8. Sites.put("two", "Runoob");
  9. Sites.put("three", "Taobao");
  10. Sites.put("four", "Zhihu");
  11. System.out.println(Sites);
  12. }
  13. }
  14. 结果为:
  15. {four=Zhihu, one=Google, two=Runoob, three=Taobao}

访问元素

我们可以使用get(key)方法来获取key对应的value:

  1. import java.util.HashMap;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. // 创建 HashMap 对象 Sites
  5. HashMap<Integer, String> Sites = new HashMap<Integer, String>();
  6. // 添加键值对
  7. Sites.put(1, "Google");
  8. Sites.put(2, "Runoob");
  9. Sites.put(3, "Taobao");
  10. Sites.put(4, "Zhihu");
  11. System.out.println(Sites.get(3));
  12. }
  13. }
  14. 结果为:
  15. Taobao

删除元素

我们可以使用remove(key)方法来删除key对应的键值对(key-value):

  1. import java.util.HashMap;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. // 创建 HashMap 对象 Sites
  5. HashMap<Integer, String> Sites = new HashMap<Integer, String>();
  6. // 添加键值对
  7. Sites.put(1, "Google");
  8. Sites.put(2, "Runoob");
  9. Sites.put(3, "Taobao");
  10. Sites.put(4, "Zhihu");
  11. Sites.remove(4);
  12. System.out.println(Sites);
  13. }
  14. }
  15. 结果为:
  16. {1=Google, 2=Runoob, 3=Taobao}

删除所有键值对(key-value)可以使用clear方法:

  1. // 引入 HashMap 类
  2. import java.util.HashMap;
  3. public class RunoobTest {
  4. public static void main(String[] args) {
  5. // 创建 HashMap 对象 Sites
  6. HashMap<Integer, String> Sites = new HashMap<Integer, String>();
  7. // 添加键值对
  8. Sites.put(1, "Google");
  9. Sites.put(2, "Runoob");
  10. Sites.put(3, "Taobao");
  11. Sites.put(4, "Zhihu");
  12. Sites.clear();
  13. System.out.println(Sites);
  14. }
  15. }
  16. 结果为:
  17. {}

计算大小

如果要计算HashMap中的元素数量可以使用size()方法:

  1. import java.util.HashMap;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. // 创建 HashMap 对象 Sites
  5. HashMap<Integer, String> Sites = new HashMap<Integer, String>();
  6. // 添加键值对
  7. Sites.put(1, "Google");
  8. Sites.put(2, "Runoob");
  9. Sites.put(3, "Taobao");
  10. Sites.put(4, "Zhihu");
  11. System.out.println(Sites.size());
  12. }
  13. }
  14. 结果为:
  15. 4

迭代HashMap

可以使用for-each来迭代HashMap中的元素
如果你只想获取key,可以使用keySet()方法,然后可以通过get(key)获取对应的value,如果你只想获取value,可以使用values()方法

  1. import java.util.HashMap;
  2. public class RunoobTest {
  3. public static void main(String[] args) {
  4. // 创建 HashMap 对象 Sites
  5. HashMap<Integer, String> Sites = new HashMap<Integer, String>();
  6. // 添加键值对
  7. Sites.put(1, "Google");
  8. Sites.put(2, "Runoob");
  9. Sites.put(3, "Taobao");
  10. Sites.put(4, "Zhihu");
  11. // 输出 key 和 value
  12. for (Integer i : Sites.keySet()) {
  13. System.out.println("key: " + i + " value: " + Sites.get(i));
  14. }
  15. // 返回所有 value 值
  16. for(String value: Sites.values()) {
  17. // 输出每一个value
  18. System.out.print(value + ", ");
  19. }
  20. }
  21. }
  22. 结果为:
  23. key: 1 value: Google
  24. key: 2 value: Runoob
  25. key: 3 value: Taobao
  26. key: 4 value: Zhihu
  27. Google, Runoob, Taobao, Zhihu,

Java HashMap方法

常用方法列表如下:
image.png
image.png