Reading 1: Static Checking > Arrays and Collections
原文地址:https://courses.edx.org/courses/course-v1:MITx+6.005.1x+3T2016/courseware/Readings_Videos/01-Static-Checking/
数组和集合
让我改变之前的冰雹计算让其将序列储存在数据结构中而不是打印出来.Java有两种类列表类型供我们使用:数组和集合.
数组是另一种类型T的固定长度的序列.例如,这里是如何定义一个数组变量和构造一个数组值给他:int[] a =new int[100];
这个int[]数组类型包含了所有可能的数组值,但是一个特定的数组值一定确定,将不能改变其长度了.数组类型的操作包括:
- 索引 a[2]
- 赋值 a[2] = 0
- 长度 a.length(注意其和String.length()的区别,这不是一个方法调用,因此你不需要在后面加上括号)
这是冰雹代码用数组后的变化.我们开始构造数组,用一个索引值i去走完数组,在我们生成值的同时去储存他们.
这个做法中的一些事情应该立刻感觉到不对.什么是魔术数字100?我们尝试一个数字n产生的序列长度大于100怎么办?这不适用于一个长度大于100的数组.我们产生了一个bug.Java将静态地扑捉到这个bug,还是动态地,又或者根本发觉不了?顺便一提,这类的bug--固定数组长度溢出,曾经在不安全的语言中普遍地采用,比如c和c++这种不进行数据进入runtime检测的语言.他们必须为大量的网络安全分支和网络爬虫负责.
让我们用列表类型来替代固定长度的数组.列表是另一种变量T的可变长度序列.这是我们如何定义一个列表类型和声明一个列表变量:List list=new ArrayList();
这里是其的一些操作:
- 索引 list.get(2)
- 赋值 list.set(2, 0)
- 长度 list.size()
注意列表是一个接口,一个不能直接用new来构造的类型,而是定义了一个列表必须有的操作.我们将在未来课程中关于抽象类型的内容中再谈到这一点.ArrayList是一个类,一个提供了这些操作实现的实体类型.ArrayList不是唯一的列表类型的实现,尽管它是最常用的一个.LinkedList是另外一个.在Java的API文档中可以查到更多,你可以搜索"java API".必须知道API文档,它们是你的朋友.("API"的意思是应用程序接口,也是库的近义词).
注意到我们也写成了List<Integer>而不是List<int>.很不幸,我们不能用List<int>直接模拟int[].列表只知道和对象类型打交道,合不是基本类型.在Java中每个基本类型(写成小写的和被缩短了,比如int)都有一个相对应的对象类型(写成大写,全称,比如Integer).Java要求我们用这些对象类型和给一个类型用角标参数化.据我所知,这个要求的唯一原因是提醒程序员这点列表包含了对象,因此比基本类型用了更多的内存.但是在其他环境,Java自动在int和Integer中进行转换,因此我们可以写Integer i = 5,而不会报错.
这是用列表类型写的冰雹序列:
不仅仅更简单了,也更安全了,因为列表可以自我增大到你加入到的数量大小(当然,直到你耗尽内存).
迭代
一个for循环一步步走完了一个数组或者列表的每一个元素,类似于Python中那样,通过稍微有些区别的语法.例如:
你可以迭代完整个数组或者列表,你把列表换成数组同样的代码也能使用.
Math.max()是Java API中一个很方便的方程.整个Math类都是这类很有用的方法--在网上搜索"java 8 Math",找到Java第八版的Math类文档.