1.9容器

本贴最后更新于 3156 天前,其中的信息可能已经事过境迁

   通常来说,如果不知道在解决某个特定问题需要多少对象或者他们将存活多久时,那么就不可能知道如何存储这些对象。如何才能知道需要多少空间来创建这些对象呢?答案是你不可能知道(老外真会玩),因为这类信息只有在运行时才能获得。

    对于面向对象程序设计中的大多数问题而言,这个问题的解决方案似乎过于轻率:创建另一种对象类型。这种新的对象类型持有对其他对象的引用。当然,你可以用在大多数语言中都有的数组类型来实现相同的功能。但是这个通常被称为容器(Java中被称为“集合”)的新对象,在任何需要时都可以扩充自己以容纳你置于其中的所有东西。因此不需要知道将来会把多少个对象置于容器中,只需要创建一个容器对象,然后让它处理所有细节。

    幸运的是,好的OOP语言都有一组容器,它们作为开发包的一部分。在C++中,容器是标准C++类库的一部分,经常被称为标准模板类库(Standard emplate Library,STL)。Object Pascal在其可视化构件库(Visual Componet Library,VCL)中有容器;Smalltalk提供了一个非常完备的容器集;Java在其标准类库中也包含有大量的容器。在某些类库中,一两个通用容易足够满足所有需要;但是在其他类库(例如Java)中,具有满足不同需要的各种类型的容器,例如List(用于存储序列),Map(也被称为关联数组,用来建立对象之间的关联),Set(每种对象类型只持有一个),以及诸如队列、树、堆栈等更多的构件。

    从设计的观点来看,真正需要的只是一个可以被操作从而解决问题的序列。如果单一类型的容器可以满足所有需求,那么就没有必要设计不同类型的序列了。然而还是需要对容器有所选择,这有两个原因。第一,不同容器提供了不同类型的接口和外部行为。堆栈相比于队列就具备不同的接口和行为,也不同于集合和列表的接口和行为。它们之中的某些容器提供的解决方案可能比其他容器要灵活的多。第二,不同的容器对于某些操作具有不同的效率。最好的例子就是两种List的比较:ArrayList和LinkedList。他们都是具有相同接口和外部行为的简单的序列,但是它们对某些操作所花费的代价却有天壤之别。在ArrayList中,随机访问元素是一个话费固定时间的操作;但是,对LinkedList来说,随机选取元素需要在列表中移动,这种代价是高昂的,访问越靠近表尾的元素,花费的是爱你越长。而另一方面,如果想在序列中插入一个元素,LinkedList的开销却比ArrayList要小。上述操作以及其他操作的效率,依序列底层结构的不同而存在很大的差异。我们可以在一开始使用LinkedList构建程序,而在优化系统性能是改用ArrayList。接口List所带来的抽象,把容器之间进行转换时对代码产生的影响降到了最小限度。

1.9.1参数化类型

    在Java SE5出现之前,容器存储的对象都只具有Java中的通用类型:Object。单根继承结构意味着所有的东西都是Object类型,所以可以存储Object的容器可以存储任何东西。这使得容器很容易被复用。

    要使用这样的容器,只需在其中置入对象的引用,稍后还可以将它们取回。但是由于容器只存储Object,所以当将对象引用置入容器时,它必须向上转型为Object,因此他会丢失其身份。当把它取回时,就获取了一个对Object对象的引用,而不是对置入是的哪个类型的对象的引用。所以怎样才能将它变回先前置入容器中是的具有实用接口的对象呢?

    这里再度用到了转型,但是这一次不是向继承结构的上层转型为一个更泛化的类型,而是向下转型为一个更具体的类型。这种转型方式称为向下转型。我们知道,向上转型是安全的,例如Circle是一种Shape类型,但是不知道某个Object是Circle还是Shape,所以除非确切知道所要处理的对象的类型,否则向下转型几乎是不安全的。

    然而向下转型并非是彻底危险的,因为如果向下转型为错误的类型,就会得到被称为异常的运行时错误,稍后会介绍什么是异常。尽管如此,当从容器中去除对象引用时,还是必须要以某种方式记住这些对象究竟是什么类型,这样才能执行正确的向下转型。

    向下转型和运行时的检查需要额外的程序运行时间,也需要程序员付出更多的心血。那么创建正阳的容器,它知道自己所保存的对象的类型,从而不需要向下转型以及消除犯错误的可能,这样不是更有意义吗?这种解决方案被称为参数化类型机制。参数化类型就是一个编译器可以自动定制作用于特定类型上的类。例如,通过使用参数化类型,编译器可以定制一个只接纳和取出Shape对象的容器。

    Java SE5的重大变化之一就是增加了参数化类型,在Java中它被称为泛型。一对尖括号,中间包含类型的信息,通过这些特征就可以识别对泛型的使用。例如,可以用下面这样的语句来创建一个存储Shape的ArrayList:

ArrayList<Shape> shapes = new ArrayList<Shape>();

    为了利用泛型的优点,很多标准类库构件都进行了修改。泛型对程序设计中的很多代码都产生了重要的影响。

总结

  1. 对象应该存储什么位置,引入了“容器”(集合)
  2. 好多语言都有集合
  3. 根据需求设计不同类型的容器。一,不同容器提供了不同类型的接口和外部行为;二,不同的容器对于某些操作具有不同的效率
  4. ArrayList跟LinkedList的优缺点
  5. 因为往容器中存取对象需要转型的各种不便与不安全引入了“泛型”

----END----

  • 第1章对象导论
    9 引用 • 4 回帖
  • Java编程思想
    9 引用 • 4 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 319 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 21 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 561 关注
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    40 引用 • 24 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    492 引用 • 1383 回帖 • 374 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    314 引用 • 1667 回帖 • 2 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 3 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 687 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 1 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖 • 32 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    324 引用 • 1395 回帖
  • Log4j

    Log4j 是 Apache 开源的一款使用广泛的 Java 日志组件。

    20 引用 • 18 回帖 • 42 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 92 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 619 关注
  • sts
    2 引用 • 2 回帖 • 148 关注
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 565 关注
  • 智能合约

    智能合约(Smart contract)是一种旨在以信息化方式传播、验证或执行合同的计算机协议。智能合约允许在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转。智能合约概念于 1994 年由 Nick Szabo 首次提出。

    1 引用 • 11 回帖 • 7 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 598 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 521 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 595 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖 • 1 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 25 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 691 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 741 关注
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 48 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    333 引用 • 323 回帖 • 67 关注