【正文】
ntainers for different needs: a vector (called an ArrayList in Java) for consistent access to all elements, and a linked list for consistent insertion at all elements, for example, so you can choose the particular type that fits your needs. Container libraries may also include sets, queues, hash tables, trees, stacks, etc. All containers have some way to put things in and get things out。為獲得最快的運(yùn)行速度,存儲(chǔ)以及存在時(shí)間可在編寫(xiě)程序時(shí)決定,只需將對(duì)象放置在堆棧(有時(shí)也叫作自動(dòng)或定域變量)或者靜態(tài)存儲(chǔ)區(qū)域即可。程序員可用兩種方法來(lái)破壞一個(gè)對(duì)象:用程序化的方式?jīng)Q定何時(shí)破壞對(duì)象,或者利用由運(yùn)行環(huán)境提供的一種“垃圾收集器”特性,自動(dòng)尋找那些不再使用的對(duì)象,并將其清除。在C++中,它們是以“標(biāo)準(zhǔn)模板庫(kù)”(STL)的形式提供的。作為一個(gè)類,它也提供了一級(jí)抽象。它們都屬于簡(jiǎn)單的序列,擁有完全一致的接口和外部行為。在Java中(與其他幾乎所有OOP語(yǔ)言一樣),對(duì)這個(gè)問(wèn)題的答案都是肯定的,而且這個(gè)終級(jí)基礎(chǔ)類的名字很簡(jiǎn)單,就是一個(gè)“Object”。由于運(yùn)行期的類型信息肯定存在于所有對(duì)象中,所以永遠(yuǎn)不會(huì)遇到判斷不出一個(gè)對(duì)象的類型的情況。但我們不知道一個(gè)Object到底是Circle還是Shape,所以很難保證下溯造型的安全進(jìn)行,除非確切地知道自己要操作的是什么。Java采取的這種關(guān)鍵字保留機(jī)制其實(shí)經(jīng)常讓人摸不著頭腦,很難斷定以后會(huì)發(fā)生什么事情。但這一次不是在分級(jí)結(jié)構(gòu)中上溯造型成一種更“通用”的類型。一個(gè)單根結(jié)構(gòu),加上所有對(duì)象都在內(nèi)存堆中創(chuàng)建,可以極大簡(jiǎn)化參數(shù)的傳遞(這在C++里是一個(gè)復(fù)雜的概念)。如果在一個(gè)編程環(huán)境中工作,它由于其他因素(比如在Windows下運(yùn)行,或者由垃圾收集器帶來(lái)了開(kāi)銷)產(chǎn)生了內(nèi)在的開(kāi)銷,那么矢量和鏈接列表之間在系統(tǒng)開(kāi)銷上的差異就或許不是一個(gè)大問(wèn)題。堆棧的接口與行為與隊(duì)列的不同,而隊(duì)列的接口與行為又與一個(gè)集(Set)或列表的不同。如果是一個(gè)數(shù)組形式的實(shí)體,比如一個(gè)矢量(Vector),那么也許能用索引運(yùn)算符或函數(shù)。在需要的時(shí)候,集合會(huì)自動(dòng)擴(kuò)充自己,以便適應(yīng)我們?cè)谄渲兄萌氲娜魏螙|西。C++允許我們決定是在寫(xiě)程序時(shí)創(chuàng)建對(duì)象,還是在運(yùn)行期間創(chuàng)建,這種控制方法更加靈活。本節(jié)將就這些問(wèn)題進(jìn)行探討。最重要的問(wèn)題之一是對(duì)象的創(chuàng)建及破壞方式。大家或許認(rèn)為既然它如此靈活,那么無(wú)論如何都應(yīng)在內(nèi)存堆里創(chuàng)建對(duì)象,而不是在堆棧中創(chuàng)建。所以我們事先不必知道要在一個(gè)集合里容下多少東西。但在許多情況下,這樣做往往會(huì)無(wú)功而返。利用這個(gè)特征,我們解決問(wèn)題時(shí)便有更大的靈活性。我們可能只需要一種類型的序列。利用單根結(jié)構(gòu),我們可以更方便地實(shí)現(xiàn)一個(gè)垃圾收集器。而是下溯造型成一種更“特殊”的類型。舉個(gè)例子來(lái)說(shuō),我們知道在上溯造型的時(shí)候,Circle(圓)屬于Shape(幾何形狀)的一種類型,所以上溯造型是安全的。如果沒(méi)有這種單根結(jié)構(gòu),而且系統(tǒng)通過(guò)一個(gè)句柄來(lái)操縱對(duì)象,那么實(shí)現(xiàn)垃圾收集器的途徑會(huì)有很大的不同,而且會(huì)面臨許多障礙。2 單根結(jié)構(gòu)在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,由于C++的引入而顯得尤為突出的一個(gè)問(wèn)題是:所有類最終是否都應(yīng)從單獨(dú)一個(gè)基礎(chǔ)類繼承。最好的例子便是矢量(Vector)和列表(List)的區(qū)別。如果想對(duì)集合中的一系列元素進(jìn)行操縱或比較,而不是僅僅面向一個(gè),這時(shí)又該怎么辦呢?辦法就是使用一個(gè)“繼續(xù)器”(Iterator),它屬于一種對(duì)象,負(fù)責(zé)選擇集合內(nèi)的元素,并把它們提供給繼承器的用戶。幸運(yùn)的是,設(shè)計(jì)優(yōu)良的OOP語(yǔ)言都配套提供了一系列集合。若在堆棧或者靜態(tài)存儲(chǔ)空間里創(chuàng)建一個(gè)對(duì)象,編譯器會(huì)判斷對(duì)象的持續(xù)時(shí)間有多長(zhǎng),到時(shí)會(huì)自動(dòng)“破壞”或者“清除”它。C++認(rèn)為程序的執(zhí)行效率是最重要的一個(gè)問(wèn)題,所以它允許程序員作出選擇。 there are usually functions to add elements to a container, and others to fetch those elements back out. But fetching elements can be more problematic, because a singleselection function is restrictive. What if you want to manipulate or pare a set of elements in the container instead of just one? The solution is an iterator, which is an object whose job is to select the elements within a container and present them to the user of the iterator. As a class, it also provides a level of abstraction. This abstraction can be used to separate the details of the container from the code that’s accessing that container. The container, via the iterator, is abstracted to be simply a sequence. The iterator allows you to traverse that sequence without worrying about the underlying structure—that is, whether it’s an ArrayList, a LinkedList, a Stack, or something else. This gives you the flexibility to easily change the underlying data structure without disturbing the code in your program. Java began (in version and ) with a standard iterator, called Enumeration, for all of its container classes. Java 2 has added a much more plete container library that contains an iterator called Iterator that does more than the older Enumeration. From a design standpoint, all you really want is a sequence that can be manipulated to solve your problem. If a single type of sequence satisfied all of your needs, there’d be no reason to have different kinds. There are two reasons that you need a choice of containers. First, containers provide different types of interfaces and external behavior. A stack has a different interface and behavior than that of a queue, which is different from that of a set or a list. One of these might provide a more flexible solution to your problem than the other. Second, different containers have different efficiencies for certain operations. The best example is an ArrayList and a LinkedList. Both are simple sequences that can have identical interfaces and external behaviors. But certain operations can have radically different costs. Randomly accessing