由David发表在天码营

Java的容器

定义好Post类之后,现在需要对博客文章进行管理。我们可以定义一个PostRepository类,通过PostRepository可以做以下操作:

  • 创建博客
  • 删除博客
  • 获取一篇博客的内容
  • 获取博客列表

我们已经有面向对象编程的经验了,我们可以给Repository增加四个方法:

package com.tianmaying.repository;import com.tianmaying.domain.Post;public class PostRepository {public static void add(Post post) {}public static Post getPostById(long id) {return null;}public static void remove(long id) {}public static ArrayList<Post> getAll() {return null;}
}

上面我们定义了四个静态成员方法,我们刚刚讲过static修饰方法的含义,现在马上就用到了。你现在可能对getAll()方法返回的ArrayList<Post>还有点疑惑,没关系,我们马上就要讲到。

先来考虑一个问题,这个PostRepository里面应该包含什么变量呢? 我们很容易想到就是一组博客。在Java中,我们可以通过数组将一组对象组织在一起,因此我们马上可以想到定义一个Post的数组。

但是数组的尺寸是固定的,通常情况下程序总是在运行时根据条件来创建对象,我们可能无法预知将要创建对象的个数,甚至是具体的类型。比如PostRepository中保存多少Blog对象我们事先是不知道的。

这时我们就需要Java的集合(Collection)类了。我们通常也称集合为容器,因为它们可以帮我们方便地组织和管理一组对象。

所以我们可以给PostRepository类增加一个静态成员变量:

public class PostRepository {private static posts = new ArrayList<Post>();...
}

这里ArrayList就是Java提供给我们使用的一个集合类,用以保存一个元素序列,并且可以进行元素的访问、插入和删除等操作。

ArrayList<Post>是一种泛型的写法。泛型就是参数化类型,即ArrayList所操作的数据类型通过一个类型参数指定。ArrayList这个容器中可以保存任何类型的变量,而且这些对象访问、插入和删除的逻辑也是相同的。比如,如果我们希望ArrayList中存放一组整数的话,我们就可以声明List<Integer>类型的变量。

在Java 7和Java 8中,编译器能够根据变量声明时的泛型类型自动推断出实例化所用的泛型类型。

ArrayList<Post> post1 = new ArrayList<Post>();
ArrayList<Post> post2 = new ArrayList<>();

post2的初始化就没有指定ArrayList中的泛型类型,编译器可以推导出来。

List的使用

ArrayList提供了一系列操作元素序列的方法。下面我们使用ArrayList来实现PostRepository的四个方法。

package com.tianmaying.repository;import java.util.ArrayList;
import java.util.List;import com.tianmaying.domain.Post;public class PostRepository {private static ArrayList<Post> posts = new ArrayList<Post>();public static void add(Post post) {posts.add(post);}public static Post getPostById(long id) {for (Post post : posts) {if (post.getId() == id) {return post;}}return null;}public static void remove(long id) {for (Post post: posts) {if (post.getId() == id) {posts.remove(post); return;}}}public static ArrayList<Post> getAll() {return posts;}
}

我们看到ArrayList的用法很简单,可以通过add方法增加元素,通过remove方法删除元素。

遍历ArrayList的方法是一种特殊的for循环,遍历Java容器中的元素都可以使用这种方法。

我们也可以使用迭代器Iterator类来完成遍历。Iterator主要有两个方法,基于这两个方法就能进行遍历操作:

  • next()方法来获取序列的下一个元素
  • hasNext()检查序列中是否还有元素

使用Iterator实现的代码如下:

public static void remove(long id) {Iterator<Post> iterator = posts.iterator();while (iterator.hasNext()) {Post post = iterator.next();if (post.getId() == id) {posts.remove(post); return;}}
}

与ArrayList类似的一种容器是LinkedList,它们都是List接口的实现。接口的概念我们后面会讲,现在你只需要知道操作ArrayList和操作LinkedList的方式是完全一样的,只不过它们内部的实现机制不一样。

这两者的主要不同在于:

  • ArrayList:通过下标随机访问元素快,但是插入、删除元素较慢
  • LinkedList:插入、删除和移动元素快,但是通过下标随机访问元素性能较低

如果你学过数据结构,就是知道ArrayList是基于数组实现的,而LinkedList是基于链表实现的。这两种数据结构的特点决定了这两个容器的不同之处。

Map

Map故名思议,就是映射,可以将一个对象映射到另一个对象。每一组映射作为一个<键,值>对保存在Map容器中。Map和List一样是一种接口,它的实现HashMap类,是我们最常使用的一种容器。

我们回顾getPostById这个方法的实现:

public static Post getPostById(long id) {for (Post post : posts) {if (post.getId() == id) {return post;}}return null;
}

每次都要经过一次遍历,经过比较才能找到id对应的博客。如果能够把作为一个键值对,那么通过id取出一篇博客就更加快速和方便。现在基于Map来实现博客管理功能,我们新建另外一个类PostRepositoryByMap:

package com.tianmaying.repository;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import com.tianmaying.domain.Post;public class PostRepositoryByMap {private static Map<Long, Post> postsMap = new HashMap<Long, Post>();public static void add(Post post) {postsMap.put(post.getId(), post);}public static Post getPostById(long id) {    return postsMap.get(id);}public static void remove(long id) {postsMap.remove(id);}public static List<Post> `addAll`方法() {List<Post> posts = new ArrayList<>();      posts.addAll(postsMap.values());return posts;}}
`

Map具有两个泛型参数,第一个是键的类型,第二个是值的类型。类型不能是原生类型,必须是引用类型,因此这里第一个类型是long的包装类Long。

使用Map之后,查找和删除博客的实现就非常简单了:

  • put方法可以增加一个键值对
  • get方法就能根据键获取到值
  • remove方法可以删除键对应的元素

Java编译器会在需要时自动帮我们进行原生数据类型和包装类之间进行转换,比如我们postMap.remove(id);这条语句传入的是long原生数据类型,Java编译器知道此时应该传入的是Long,会自动帮我们做这个转换。

我们可以获取键、值或键值对的集合,分别使用keySet, values以及entrySet。getAll方法就通过postsMap.values()获取所有的值,这里就是所有的Blog对象。

注意这里调用了一个addAll方法,这个方法是所有容器都有的一个方法,可以把另外一个容器中的元素加入其中。

我们可以这样遍历一个Map:

for (Map.Entry<Long, Post> postEntry : postMap.entrySet()) {Long id = postEntry.getKey();Post post = postEntry.getValue();// 在遍历中操作每一个post...
}

如果PostRepositoryByMap的getAll()方法不使用addAll方法,而通过遍历的方式逐个将博客对象加入到一个List中,如何实现呢? 你可以尝试一下。

作者:David
链接:https://zhuanlan.zhihu.com/p/20676879
来源:知乎

Java集合的使用:List与Map相关推荐

  1. java集合map_JAVA中的集合类Map、Set、List

    *精炼的总结: Collection 是对象集合, Collection 有两个子接口 List 和 Set List 可以通过下标 (1,2..) 来取得值,值可以重复 而 Set 只能通过游标来取 ...

  2. Java集合List,Set,Map,Queue,Deque

    集合是Java基础中非常重要的一部分,Java提供了非常丰富的集合API,了解各个集合的特点,怎么样在各种各样的场景中使用正确的集合,非常重要,也是一个Java程序员最基本的素养. 整体了解 Java ...

  3. 史上最全的集合框架讲解 ----- Java 集合框架(3)---- Map 相关类最全解析

    引言 好了,步入正题,上篇文章Java 集合框架(2)---- List 相关类解析中我们一起看了一下 List 接口的相关具体类(ArrayList.LinkedList-.),这篇开始我们开始探索 ...

  4. Java 集合框架(5)---- Map 相关类解析(中)

    本文标题大纲: 文章目录 前言 HashMap TreeMap 指定 TreeMap 的元素排序方式 前言 还是先上那张图吧,我又偷懒了,还是只关注 Map 接口下的类就行了: 在上上篇文章中我们一起 ...

  5. Java集合List、Set、Map

    集合是 java 基础中非常重要的一部分,同样也是 Java 面试中很重要的一个知识点.所以,给王小整理了这篇关于集合的文章. 1.接口继承关系以及实现 集合类存放于 Java.util 包中,主要有 ...

  6. Java集合详解--什么是Map

    引言 在很久很久以前,讲过Set的实现原理,讲到Set就是Map的马甲,那么今天我们就来看看Map是如何实现的(本文都基于JDK1.8的版本) 什么是Map Map和Collection有关的几个ma ...

  7. Java 集合List、Set、Map知识结构大全详解

    目录 概述 一.Collection 接口 (1)List列表 -- 有序.值可重复 (2)Set 集  -- 值不可重复 二.Map 接口 (1)HashMap --  无序 1.取模法 2.Has ...

  8. java 集合 接口_Java集合之Collection接口

    1 - Java集合介绍 /* 1. 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象 的操作,就要对对象进行存储. 2. 另一方面,使用Array存储对象方面具有一些弊 端,而 ...

  9. Java基础篇:Java集合

    文章目录 1.概述 2.Collection接口 2.1 Collection接口方法 2.2 Iterator迭代器接口 2.3 Collection子接口之:List接口 2.4 Collecti ...

  10. java集合代码_Java-集合(示例代码)

    一.Java集合框架概述 ●一方面,面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储.另一方面,使用Array存储对象方面具有一些弊端,而Java集合就像一种容器 ...

最新文章

  1. 66篇论文入选CVPR 2021,商汤的秘籍竟是“大力出奇迹”
  2. spring集成mq_使用Spring Integration Java DSL与Rabbit MQ集成
  3. C# Socket简单例子(服务器与客户端通信)
  4. 互联网如何“武装”农民?
  5. flops什么意思中文_不知道什么是FLOPs?进来瞧瞧~
  6. C++为什么空格无法输出_那些C/C++程序员该具备的32个编程修养习惯!
  7. YOLOv4/v5的创新点汇总!
  8. Verilog常用语法
  9. 怎么大量转换图片格式为tiff
  10. 皮影机器人ppt_机器人皮影戏装置的制作方法
  11. 远程访问内网服务器使用FRP实现内网穿透
  12. 航空产业已成境外情报机构重点网络攻击目标
  13. 激荡的2020过后,物流江湖下个十年谁主沉浮?
  14. PyQt模拟微信聊天页面开发
  15. 用Paddle自动生成二次元人物头像
  16. RGB565 RGB888
  17. # 工欲善其事必先利其器-C语言拓展--嵌入式C语言(九)
  18. Win10运行程序提示不受信任的解决方法【系统天地】
  19. 乐学偶得python视频_乐学偶得 - 课程
  20. 婚恋网站能遇见幸福吗?2019互联网婚恋交友行业洞察

热门文章

  1. Activity中UI框架基本概念
  2. Python基础知识(第四天)
  3. python查询数据库,打印查询结果过程中出现'NoneType' object is unsubscriptable
  4. 智能风控平台核心之风控决策引擎(二)
  5. 编程语言与思维:科技公司如何自我重构?
  6. php删除session中的值,PHP中session变量的销毁
  7. 面试离职理由_面试一个月都没有成功,是种什么样的神奇体验?
  8. C语言之动态内存管理与动态内存函数
  9. python 从尾到头打印链表
  10. Java版的防抖(debounce)和节流(throttle)