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/
數(shù)組和集合
讓我改變之前的冰雹計(jì)算讓其將序列儲(chǔ)存在數(shù)據(jù)結(jié)構(gòu)中而不是打印出來(lái).Java有兩種類列表類型供我們使用:數(shù)組和集合.
數(shù)組是另一種類型T的固定長(zhǎng)度的序列.例如,這里是如何定義一個(gè)數(shù)組變量和構(gòu)造一個(gè)數(shù)組值給他:int[] a =new int[100];
這個(gè)int[]數(shù)組類型包含了所有可能的數(shù)組值,但是一個(gè)特定的數(shù)組值一定確定,將不能改變其長(zhǎng)度了.數(shù)組類型的操作包括:
- 索引 a[2]
- 賦值 a[2] = 0
- 長(zhǎng)度 a.length(注意其和String.length()的區(qū)別,這不是一個(gè)方法調(diào)用,因此你不需要在后面加上括號(hào))
這是冰雹代碼用數(shù)組后的變化.我們開(kāi)始構(gòu)造數(shù)組,用一個(gè)索引值i去走完數(shù)組,在我們生成值的同時(shí)去儲(chǔ)存他們.
這個(gè)做法中的一些事情應(yīng)該立刻感覺(jué)到不對(duì).什么是魔術(shù)數(shù)字100?我們嘗試一個(gè)數(shù)字n產(chǎn)生的序列長(zhǎng)度大于100怎么辦?這不適用于一個(gè)長(zhǎng)度大于100的數(shù)組.我們產(chǎn)生了一個(gè)bug.Java將靜態(tài)地?fù)渥降竭@個(gè)bug,還是動(dòng)態(tài)地,又或者根本發(fā)覺(jué)不了?順便一提,這類的bug--固定數(shù)組長(zhǎng)度溢出,曾經(jīng)在不安全的語(yǔ)言中普遍地采用,比如c和c++這種不進(jìn)行數(shù)據(jù)進(jìn)入runtime檢測(cè)的語(yǔ)言.他們必須為大量的網(wǎng)絡(luò)安全分支和網(wǎng)絡(luò)爬蟲(chóng)負(fù)責(zé).
讓我們用列表類型來(lái)替代固定長(zhǎng)度的數(shù)組.列表是另一種變量T的可變長(zhǎng)度序列.這是我們?nèi)绾味x一個(gè)列表類型和聲明一個(gè)列表變量:List?list=new ArrayList();
這里是其的一些操作:
- 索引 list.get(2)
- 賦值 list.set(2, 0)
- 長(zhǎng)度 list.size()
注意列表是一個(gè)接口,一個(gè)不能直接用new來(lái)構(gòu)造的類型,而是定義了一個(gè)列表必須有的操作.我們將在未來(lái)課程中關(guān)于抽象類型的內(nèi)容中再談到這一點(diǎn).ArrayList是一個(gè)類,一個(gè)提供了這些操作實(shí)現(xiàn)的實(shí)體類型.ArrayList不是唯一的列表類型的實(shí)現(xiàn),盡管它是最常用的一個(gè).LinkedList是另外一個(gè).在Java的API文檔中可以查到更多,你可以搜索"java API".必須知道API文檔,它們是你的朋友.("API"的意思是應(yīng)用程序接口,也是庫(kù)的近義詞).
注意到我們也寫(xiě)成了List<Integer>而不是List<int>.很不幸,我們不能用List<int>直接模擬int[].列表只知道和對(duì)象類型打交道,合不是基本類型.在Java中每個(gè)基本類型(寫(xiě)成小寫(xiě)的和被縮短了,比如int)都有一個(gè)相對(duì)應(yīng)的對(duì)象類型(寫(xiě)成大寫(xiě),全稱,比如Integer).Java要求我們用這些對(duì)象類型和給一個(gè)類型用角標(biāo)參數(shù)化.據(jù)我所知,這個(gè)要求的唯一原因是提醒程序員這點(diǎn)列表包含了對(duì)象,因此比基本類型用了更多的內(nèi)存.但是在其他環(huán)境,Java自動(dòng)在int和Integer中進(jìn)行轉(zhuǎn)換,因此我們可以寫(xiě)Integer i = 5,而不會(huì)報(bào)錯(cuò).
這是用列表類型寫(xiě)的冰雹序列:
不僅僅更簡(jiǎn)單了,也更安全了,因?yàn)榱斜砜梢宰晕以龃蟮侥慵尤氲降臄?shù)量大小(當(dāng)然,直到你耗盡內(nèi)存).
迭代
一個(gè)for循環(huán)一步步走完了一個(gè)數(shù)組或者列表的每一個(gè)元素,類似于Python中那樣,通過(guò)稍微有些區(qū)別的語(yǔ)法.例如:
你可以迭代完整個(gè)數(shù)組或者列表,你把列表?yè)Q成數(shù)組同樣的代碼也能使用.
Math.max()是Java API中一個(gè)很方便的方程.整個(gè)Math類都是這類很有用的方法--在網(wǎng)上搜索"java 8 Math",找到Java第八版的Math類文檔.