Java程序設計基礎教程(慕課版)(第2版) 課件 第6單元 集合和數(shù)組_第1頁
Java程序設計基礎教程(慕課版)(第2版) 課件 第6單元 集合和數(shù)組_第2頁
Java程序設計基礎教程(慕課版)(第2版) 課件 第6單元 集合和數(shù)組_第3頁
Java程序設計基礎教程(慕課版)(第2版) 課件 第6單元 集合和數(shù)組_第4頁
Java程序設計基礎教程(慕課版)(第2版) 課件 第6單元 集合和數(shù)組_第5頁
已閱讀5頁,還剩40頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

第6單元集合和數(shù)組Java程序設計基礎教程((慕課版)(第2版))目錄導航6.1集合初探6.3數(shù)組6.5單元小結(jié)6.2集合的遍歷6.4項目實戰(zhàn)6.1集合初探通常情況下,將具有相同性質(zhì)的一類事物匯聚成一個整體,即集合;集合框架則是為了表示和操作集合而規(guī)定的統(tǒng)一的、標準的體系結(jié)構(gòu)。集合框架包含三大部分:對外接口:表示集合的抽象數(shù)據(jù)類型,使對集合中所表示的內(nèi)容進行單獨操作成為可能。接口實現(xiàn):集合框架中接口的具體實現(xiàn),也就是可復用的數(shù)據(jù)結(jié)構(gòu)。對集合運算的算法:在一個實現(xiàn)了集合框架接口的對象上完成某種有用操作的方法。Java提供了Collection集合,在其中定義了很多抽象的數(shù)據(jù)類型,包括集(Set)、鏈表(List)和哈希表(HashTable)等,另外還有比較特殊的映射(Map)。6.1.1CollectionCollection框架中有豐富的抽象數(shù)據(jù)類型,這些數(shù)據(jù)類型封裝了對應的算法,以實現(xiàn)數(shù)據(jù)的低耗、高效。Collection的繼承結(jié)構(gòu)如圖所示。6.1.1CollectionJava中集合操作類的基本接口是Collection,該接口用于表示任何元素或?qū)ο蠼M,支持添加、刪除和迭代等功能。Collection的通用方法如表所示。方法功能描述booleanadd(Objectelement)添加一個元素到集合中booleanaddAll(Collectionfrom)將from集合中的所有元素添加到集合中voidclear()清空集合booleancontains(Objectobj)判斷集合中是否含有某元素booleancontainsAll(Collectionc)判斷集合中是否包含集合c中所有的元素booleanequals(Objectobj)判斷集合是否相等bolleanisEmpty()判斷集合是否為空Iteratoriterator()返回一個實現(xiàn)了Iterator接口的對象booleanremove(Objectelement)刪除集合中的某元素booleanremoveAll(Collectionc)刪除集合中所有與c集合中相同的元素booleanretainAll(Collectionc)刪除集合中不在c集合中的元素intsize()返回集合中元素的數(shù)目6.1.2Map集合Map并非繼承自Collection接口。Map維護著鍵值對的映射關系,其中鍵是不可重復的。每組不可重復的鍵值對映射可以執(zhí)行修改、查詢和提供可選視圖等操作。

Map有自己的接口,其方法與Collection中定義的方法稍有不同。Map的常用方法如表所示。方法功能描述Objectput(Objectkey,Objectvalue)添加一個鍵值對到Map中Objectremove(Objectkey)刪除鍵是key的映射并返回該鍵映射的值voidputAll(Mapmapping)將另一個Map添加到指定Map中voidclear()清除Map中的數(shù)據(jù)Objectget(Objectkey)獲取指定key映射的valuebooleancontainsKey(Objectkey)判斷映射表是否含有指定key的映射booleancontainsValue(Objectvalue)判斷映射表是否含有指定value的映射intsize()返回指定映射表的鍵值對個數(shù)booleanisEmpty()判斷映射表是否為空SetkeySet()返回映射表中所有鍵組成Set集合SetentrySet()返回一個實現(xiàn)了Map.Entry接口的對象集合Collectionvalues()返回Map所有值組成的Collection集合任務6-1Map的使用publicclassMapDemo{publicstaticvoidmain(String[]args){Map<String,String>map=getMap(); //獲取一個mapSystem.out.println(map); //輸出map的數(shù)據(jù)System.out.println("輸出key=null的value:"+map.get(null)); //根據(jù)key獲取其valueSet<String>keySet=map.keySet(); //獲取map對象key的Set集合System.out.println("key的集合:"+keySet); //輸出map的key集合Collection<String>valueCollection=map.values(); //獲取map的value集合System.out.println("value集合:"+valueCollection); //輸出map的value集合Set<Entry<String,String>>entrySet=map.entrySet(); //獲取map.Entry對象System.out.println("******************開始以Entry對象的方式輸出Map中的映射鍵值對");System.out.print("[");for(Entry<String,String>entry:entrySet){System.out.print("key="+entry.getKey()+":value="+entry.getValue()+";");}System.out.println("]\n******************結(jié)束以Entry對象的方式輸出Map中的映射鍵值對");Map<String,String>hashMap=newHashMap<>();hashMap.put("hashMap","hashMap");hashMap.put("treeMap","treeMap");hashMap.put("gender","M");文件MapDemo.java任務6-1Map的使用map.putAll(hashMap);//將hashMap中的數(shù)據(jù)添加到map對象中System.out.println(map);//是否包含的判斷System.out.println("是否包含key=gender的對象:"+map.containsKey("gender"));System.out.println("是否包含key=Java的對象:"+map.containsKey("Java"));System.out.println("是否包含value=M的對象:"+map.containsValue("M"));System.out.println("是否包含value=F的對象:"+map.containsValue("F"));System.out.println("map集合是否為空:"+map.isEmpty());System.out.println("map集合的大小是:"+map.size());map.clear();//清空map對象System.out.println("map集合是否為空:"+map.isEmpty());System.out.println("map集合的大小是:"+map.size());}//返回一個含有鍵值對的map對象publicstaticMap<String,String>getMap(){Map<String,String>map=newHashMap<>();//初始化一個HashMap對象map.put(null,"keynull");//添加一個鍵值對到map中(key和value均可以為null)map.put("null",null);map.put("name","map");map.put("gender","F");map.put("home","house");returnmap;}}任務6-1Map的使用運行結(jié)果如圖6-2所示。任務6-2HashMap及TreeMap的使用publicclassTreeMap2HashMapDemo{publicstaticvoidmain(String[]args){//創(chuàng)建HashMap對象Map<String,String>hashMap=newHashMap<>();//添加元素hashMap.put("Java","JavaUser");hashMap.put("C","Cuser");hashMap.put("C++","C++user");hashMap.put("Go","Gouser");

System.out.println("hashMap="+hashMap);//根據(jù)hashMap構(gòu)建一個TreeMapTreeMap<String,String>treeMap=newTreeMap<>(hashMap);

System.out.println("treeMap="+treeMap);

HashMap<String,String>hMap=newHashMap<>(treeMap);System.out.println("hMap="+hMap);}}文件TreeMap2HashMapDemo.java運行結(jié)果如圖6-3所示。從運行結(jié)果中可以明顯看出,TreeMap是有一定排序規(guī)則的。當然,讀者可以自定義排序規(guī)則,也可以使用默認的規(guī)則。相比于無序的HashMap,TreeMap在遍歷時無疑會快很多,但因為它是根據(jù)二叉樹進行存儲的,所以其隨機訪問和插入性能勢必弱于HashMap。不過兩者的相互轉(zhuǎn)換可彌補這個不足,對于不同的數(shù)據(jù)類型,僅需將其轉(zhuǎn)換成合適的類型即可。

WeakHashMap是Map的一個特殊實現(xiàn),僅用于存儲鍵的弱引用。當映射的某個鍵在WeakHashMap的外部不再被引用時,垃圾收集器會收集映射中對應的鍵值對。這種數(shù)據(jù)類型在維護注冊表的數(shù)據(jù)結(jié)構(gòu)時效果明顯。當某個條目的鍵不再被任何線程訪問時,該條目就可以被回收。6.1.3List集合鏈表分為兩個部分:一個是數(shù)據(jù)部分,用于存儲數(shù)據(jù);另一個是連動部分,用于指向前一個元素的位置和后一個元素的位置。鏈表繼承自Collection接口,用于定義可以重復的有序集合。Collection接口允許對鏈表進行按位置操作,查詢則從鏈表的頭部或尾部開始。

List接口有兩個實現(xiàn)類:ArrayList和LinkedList。ArrayList類是用數(shù)組實現(xiàn)的List,能進行快速的隨機訪問,但是隨機插入和刪除操作的速度比較慢。LinkedList類對順序訪問進行了優(yōu)化,在插入和刪除元素的操作上代價不高,但是隨機訪問的速度相對較慢。在實際應用中,LinkedList類可以當成棧、隊列(Queue)或雙向隊列(Deque)來使用。List是常用且簡單的數(shù)據(jù)結(jié)構(gòu),又稱為線性表(非空且有限)。在線性表中,有且僅有一個元素被稱為第一個元素和最后一個元素。同時,除第一個元素外,每個元素都有一個前驅(qū)元素;除最后一個元素外,每個元素都有一個后繼元素。在線性表中,所有相鄰的數(shù)據(jù)元素之間存在先后順序。圖6-4所示是一個長度為n的線性表。6.1.3List集合順序表的特點是用元素在計算機內(nèi)物理位置的相鄰關系來表示線性表中元素之間的邏輯關系,這使得順序表的隨機讀取速度非???。順序表元素的插入和刪除操作如圖6-5所示。因順序表是順序存儲的,所以每當一個元素插入或者刪除時,其后所有元素的位置都要做相應的變動,導致順序表的插入、刪除操作平均需要移動n/2個元素(如果是自末尾刪除和插入則無須移動元素),這相當耗時。順序表01OPTION任務6-3順序表publicclassArrayListDemo{publicstaticvoidmain(String[]args){List<String>arrList=newArrayList<>();//創(chuàng)建一個順序表對象//添加元素(在順序表末尾添加)arrList.add("one");arrList.add("two");arrList.add("three");arrList.add("four");arrList.add("five");arrList.add("six");System.out.println("arrList="+arrList);//輸出順序表的內(nèi)容System.out.println("設置索引位置2上的值為3,原值是:"+arrList.set(2,"3"));//在索引位置4上添加一個元素,值為5(在指定位置添加)arrList.add(4,"5");System.out.println("arrList="+arrList);//輸出順序表的內(nèi)容//獲取索引對應的值System.out.println("索引位置1上的值是:"+arrList.get(1));System.out.println("刪除索引位置為4的值,該值是:"+arrList.remove(4));System.out.println("arrList="+arrList);//輸出順序表的內(nèi)容文件ArrayListDemo.java//順序表的clear()和isEmpty()方法分別用于清除順序表數(shù)據(jù)和判斷順序表是否為空System.out.println("順序表是否為空:"+arrList.isEmpty());System.out.println("順序表的數(shù)據(jù)量是:"+arrList.size());System.out.println("查詢two元素對應的索引:"+arrList.indexOf("two"));System.out.println("查詢Seven元素對應的索引:"+arrList.indexOf("seven"));System.out.println("順序表中是否含有元素Seven:"+arrList.contains("Seven"));任務6-3順序表//獲取順序表的子表List<String>subList=arrList.subList(0,3);System.out.println("subList="+subList); //輸出子表數(shù)據(jù)//修改子表數(shù)據(jù),然后查看子表數(shù)據(jù)和原順序表數(shù)據(jù)subList.set(1,"Seven");System.out.println("subList="+subList); //輸出子表數(shù)據(jù)System.out.println("arrList="+arrList); //輸出順序表的內(nèi)容arrList.set(0,"serven");System.out.println("subList="+subList); //輸出子表數(shù)據(jù)System.out.println("arrList="+arrList); //輸出順序表的內(nèi)容arrList.clear();System.out.println("subList="+subList); //輸出子表數(shù)據(jù)}}運行結(jié)果如圖6-6所示。6.1.3List集合鏈表分為單向鏈表和雙向鏈表,單向鏈表只能從鏈表的第一個元素依次向后查找,雙向鏈表則可以從任意位置向前或者向后查找。鏈表的數(shù)據(jù)結(jié)構(gòu)如圖所示。順序表02OPTIONLinkedList類實現(xiàn)的就是雙向鏈表。

與順序表不同,在鏈表中只需要修改對應的前驅(qū)元素存儲的后繼元素信息和后繼元素存儲的前驅(qū)元素信息即可實現(xiàn)插入、刪除操作。具體的插入與刪除操作如圖所示。6.1.3List集合方法功能描述voidaddFirst(Ee)將給定的元素放到鏈表的最前面voidaddLast(Ee)將給定的元素放到鏈表的最后面Eelement()獲取鏈表的第一個元素Eget(intindex)獲取指定位置的元素EgetFirst()獲取第一個元素,在鏈表為空時可能會拋出異常EgetLast()獲取最后一個元素intindexOf(Objectobj)獲取指定元素在鏈表中第一次出現(xiàn)的位置,-1表示未找到intlastIndexOf(Objectobj)獲取指定元素在鏈表中最后一次出現(xiàn)的位置,-1表示未找到ListIterator<E>listIterator(intindex)獲取從指定位置開始的迭代器booleanoffer(Ee)將指定元素插入鏈表的尾部Epeek()獲取第一個元素。即使鏈表為空,也不會拋出異常Epoll()獲取并刪除第一個元素。如果鏈表為空,則返回nullEremove()通過底層調(diào)用removeFirst()來獲取并刪除第一個元素Eremove(intindex)獲取并刪除指定位置的元素EremoveFirst()獲取并刪除第一個元素。如果鏈表為空,則拋出異常EremoveLast()獲取并刪除最后一個元素Eset(intindex,Elemente)將指定位置的值用指定元素代替Object[]toArray()將所有元素組織成一個數(shù)組表6-3鏈表的常用方法任務6-4鏈表操作publicclassLinkedListDemo{publicstaticvoidmain(String[]args){LinkedList<Integer>numList=getList(100);//約瑟夫環(huán),將數(shù)字19從中移除josephRing();System.out.println("刪除下標是19的元素,其值是:"+numList.remove(19));ListIterator<Integer>it=numList.listIterator(94);//獲取下標從94開始的迭代器System.out.print("輸出結(jié)果是:[");while(it.hasNext()){System.out.print(it.next()+"");}System.out.print("]\n");//獲取下標為55~63的元素的子鏈表List<Integer>subList=getList(10);numList.retainAll(subList);//除去不在subList中的元素System.out.println("subList="+subList);System.out.println("去除不在subList中的元素后,numList中剩余的元素為:"+numList);System.out.println("獲取第一個元素(不刪除):"+numList.peek());System.out.println("numList="+numList);System.out.println("獲取第一個元素(刪除):"+numList.poll());System.out.println("numList="+numList);System.out.println("獲取第一個元素(不刪除):"+numList.getFirst());System.out.println("numList="+numList);System.out.println("獲取最后一個元素(不刪除):"+numList.getLast());System.out.println("numList="+numList);}文件LinkedListDemo.java任務6-4鏈表操作//約瑟夫環(huán),每當數(shù)到13時,該元素會被從環(huán)中移除publicstaticvoidjosephRing(){LinkedList<Integer>list=getList(100); //獲取下標為1~100的鏈表intcount=100; //從100開始計數(shù),count=1的時候停止計數(shù)intnumber=0; //用于標記是否已經(jīng)到達14Iterator<Integer>it=list.iterator(); //獲取list的迭代器對象while(count>1){if(it.hasNext()){it.next(); //跳過該數(shù)字number++; //計數(shù)器自增}else{it=list.iterator(); //訪問到鏈表末尾時,需要手動重置或重新創(chuàng)建迭代器}if(number==13){number=0; //重置計數(shù)器it.remove(); //出列--count; //總數(shù)自減}}System.out.println("最后的幸存者是:"+list.element()+"號。");}//1~100的數(shù)字鏈表publicstaticLinkedList<Integer>getList(intnumber){LinkedList<Integer>list=newLinkedList<>();for(inti=1;i<number+1;i++){list.add(i);}returnlist;}}文件LinkedListDemo.java任務6-4鏈表操作運行結(jié)果如圖6-9所示。鏈表繼承了Collection的所有方法,但是它本身有l(wèi)istIterator(intindex)方法,該方法可以從指定的下標開始迭代。如果知道了開始迭代的下標,鏈表的遍歷速度會有很大的提升,同時可省去將鏈表轉(zhuǎn)換成順序表的步驟。讀者在此處一定要注意,List接口沒有該方法,想要使用該方法一定要用鏈表的實現(xiàn)類LinkedList去定義該鏈表對象。6.1.4Set集合publicclassCountCharRepeatTimes{publicstaticvoidmain(String[]args){StringcharSeq=getCharSequence(20);System.out.println("隨機生成的字符序列是:"+charSeq);//創(chuàng)建用于存放字符的Set集合和用于存放字符串及其出現(xiàn)次數(shù)的map對象Map<Character,Integer>map=newHashMap<>();Set<Character>charSet=newHashSet<>();for(inti=0;i<charSeq.length();i++){Characterch=charSeq.charAt(i);if(charSet.add(ch)){ //成功插入,說明當前字符是第一次出現(xiàn)map.put(ch,1); //將當前字符插入map,將出現(xiàn)次數(shù)賦為1}else{ //插入失敗,說明當前字符已經(jīng)出現(xiàn)過map.put(ch,map.get(ch)+1); //將當前字符對應的出現(xiàn)次數(shù)加1}}System.out.println("charSeq中字符及其出現(xiàn)的次數(shù)是:"+map);}文件CountCharRepeatTimes.javaSet是集合中元素不可以重復的一種抽象數(shù)據(jù)類型。這與數(shù)學中的集合相似,集合中的元素不可以重復,Set中的元素也是如此。向Set集合中插入一個已經(jīng)存在的數(shù)據(jù)時,該方法會返回false,表示該元素未能被成功添加到集合中。任務6-5計算出現(xiàn)的次數(shù)6.1.4Set集合publicstaticStringgetCharSequence(intlen){StringbaseChar="adcdefghijklmnopqrstuvwxyz";StringBuildersb=newStringBuilder();Randomrm=newRandom();for(inti=0;i<len;i++){sb.append(baseChar.charAt(rm.nextInt(26)));//根據(jù)給定的長度,隨機從baseChar中獲取一個字符}returnsb.toString();}}運行結(jié)果如圖6-10所示。目錄導航6.1集合初探6.3數(shù)組6.5單元小結(jié)6.2集合的遍歷6.4項目實戰(zhàn)6.2.1Iterator接口

Iterator(迭代器)是一種設計模式,開發(fā)人員無須了解序列的底層結(jié)構(gòu)就可以遍歷序列。Iterator的創(chuàng)建代價很小,它是輕量級的對象。在Java中,Iterator的功能比較簡單,只能單向迭代。Iterator接口含有3個重要的方法:hasNext()、next()和remove()方法。首先使用hasNext()方法判斷迭代器是否有后續(xù)元素;如果有,則用next()方法獲取該元素;同時,還可以用remove()方法刪除最近通過next()方法返回的元素。任務6-6集合的迭代publicclassIteratorDemo{publicstaticvoidmain(String[]args){Map<String,String>map=MapDemo.getMap();//獲取map數(shù)據(jù)集List<Integer>list=LinkedListDemo.getList(20);//獲取list數(shù)據(jù)集Set<String>keySet=map.keySet();//獲取map中所有鍵的Set集合Collection<String>valuesCollection=map.values();//獲取map的values集合對象//輸出數(shù)據(jù)System.out.println("map="+map);System.out.println("list="+list);System.out.println("keySet="+keySet);System.out.println("valuesCollection="+valuesCollection);Iterator<Integer>listIt=list.iterator();//獲取List的迭代器System.out.println("******開始遍歷鏈表迭代器******");printInfo(listIt);//迭代System.out.println("******結(jié)束遍歷鏈表迭代器******");Iterator<String>setIt=keySet.iterator();//獲取Set的迭代器System.out.println("******開始遍歷Set集合迭代器******");printInfo(setIt);//迭代System.out.println("******結(jié)束遍歷Set集合迭代器******");Iterator<String>collectionIt=valuesCollection.iterator();文件IteratorDemo.java//獲取Collection的迭代器System.out.println("******開始遍歷Collection集合迭代器******");printInfo(collectionIt);//迭代System.out.println("******結(jié)束遍歷Collection集合迭代器******");}//遍歷迭代器@SuppressWarnings("rawtypes")publicstaticvoidprintInfo(Iteratorit){if(null==it){thrownewRuntimeException("迭代器中傳入的是空值!");}System.out.print("***開始迭代:[");while(it.hasNext()){//判斷迭代器是否有后續(xù)對象System.out.print(it.next()+"");}System.out.println("]迭代結(jié)束***");}}任務6-6集合的迭代運行結(jié)果如圖6-11所示。6.2.2增強型for循環(huán)

普通for循環(huán)的語法格式如下:for(nitValue;booleanexpresion;initValuestep){//TODO}對于一些特殊的數(shù)據(jù)結(jié)構(gòu),Java給出了增強型for循環(huán),用于簡化代碼,格式如下:for(typevalue:typeColleciton){//TODO}任務6-7增強型for循環(huán)publicclassEnhanceForDemo{publicstaticvoidmain(String[]args){Map<String,String>map=MapDemo.getMap();//獲取map數(shù)據(jù)System.out.println("map中的數(shù)據(jù):"+map);Set<Entry<String,String>>entrySet=map.entrySet();//獲取map映射的entrySet集合System.out.println("*********************");for(Entry<String,String>entry:entrySet){System.out.println("Entry對象的鍵值對是:key="+entry.getKey()+":value="+entry.getValue());}System.out.println("*********************");

Collection<String>valuesColl=map.values();//獲取map中所有值的Collection對象System.out.print("valuesColl中的數(shù)據(jù)是:[");for(Stringvalue:valuesColl){System.out.print(value+"");}System.out.print("]\n");

LinkedList<Integer>list=LinkedListDemo.getList(15);System.out.print("list中的數(shù)據(jù)是:[");for(Integervalue:list){System.out.print(value+"");}System.out.print("]");}}文件EnhanceForDemo.java運行結(jié)果如圖6-12所示。目錄導航6.1集合初探6.3數(shù)組6.5單元小結(jié)6.2集合的遍歷6.4項目實戰(zhàn)6.3.1數(shù)組的定義及初始化數(shù)組的存取是以數(shù)組中的元素為單位進行的,一個數(shù)組中擁有的元素個數(shù)是該數(shù)組的長度。在Java中,數(shù)組也是對象,需要動態(tài)地生成。數(shù)組一般分為一維數(shù)組、二維數(shù)組和多維數(shù)組。多維數(shù)組的復雜性導致其不如前兩者使用得那么頻繁,故本書只介紹一維數(shù)組和二維數(shù)組。一維數(shù)組的聲明方式如下:數(shù)據(jù)類型[]數(shù)組名;//盡量避免使用“數(shù)據(jù)類型

數(shù)組名[;”聲明方式數(shù)組的創(chuàng)建與初始化有以下方式:int[]arr={1,2,3};//以賦值的方式直接初始化,數(shù)組的長度是其元素的個數(shù)(這里數(shù)組長度是3)int[]arr=newint[3];//創(chuàng)建一個沒有賦值的、長度是3的數(shù)組數(shù)組一旦被定義,那么它的數(shù)據(jù)類型和數(shù)組名就不能更改,而且數(shù)組在使用前必須進行初始化。初始化時必須顯式或隱式地告訴JVM數(shù)組的長度,這個長度一旦確定,就不可以修改了。可直接使用clone()方法復制另一個數(shù)組的元素,或者直接引用其他數(shù)組元素,但條件是這些數(shù)組的數(shù)據(jù)類型要一致。二維數(shù)組和一維數(shù)組一樣,都可以直接使用值初始化和new關鍵字的方法創(chuàng)建。6.3.2數(shù)組的使用1.一維數(shù)組下面通過任務6-8來了解一維數(shù)組的使用。2.二維數(shù)組一個二維數(shù)組可以看作一張表,表里含有列和行,它們分別有對應的列號和行號。二維數(shù)組通過列號和行號來確定元素。值得注意的是,每一行的列數(shù)可以不同,并且在創(chuàng)建表的時候,只需要指定二維數(shù)組的行數(shù)就可以了,列數(shù)可以不指定。除了維數(shù)不同外,二維數(shù)組和一維數(shù)組沒有更多的區(qū)別。為了便于理解,可以將二維數(shù)組看作以一維數(shù)組為元素的一維數(shù)組。

下面通過任務6-9來了解二維數(shù)組的使用。任務6-8一維數(shù)組的使用publicclassArrayDemo{publicstaticvoidmain(String[]args){int[]arrInt={1,2,3,4,5};//聲明并初始化一個數(shù)組,該數(shù)組長度是5System.out.println("數(shù)組的長度是:"+arrInt.length);//輸出數(shù)組的長度System.out.println("arrInt="+forDemo(arrInt));//通過for循環(huán)遍歷數(shù)組int[]arrInt1=newint[4];System.out.println("arrInt1="+forDemo(arrInt1));//通過for循環(huán)遍歷數(shù)組String[]arrStr=newString[4];//創(chuàng)建一個String類型的數(shù)組,其長度是4System.out.println("數(shù)組的長度是:"+arrStr.length);arrStr[0]="zero";//根據(jù)下標對元素進行賦值arrStr[3]="three";System.out.println("arrStr="+enhanceForDemo(arrStr));//使用增強型for循環(huán)String[]arrString=arrStr.clone();//使用clone()方法創(chuàng)建對象System.out.println("arrString="+forDemo(arrString));//通過for循環(huán)遍歷數(shù)組arrString[0]="0";//重新賦值System.out.println("arrStr="+forDemo(arrStr));//通過for循環(huán)遍歷數(shù)組forDemo(arrString);//分別輸出兩者,查看區(qū)別arrString=arrStr;//直接賦值arrString[0]="零";//重新賦值System.out.println("arrString="+forDemo(arrString));//通過for循環(huán)遍歷數(shù)組System.out.println("arrStr="+forDemo(arrStr));//通過for循環(huán)遍歷數(shù)組}文件ArrayDemo.java任務6-8一維數(shù)組的使用//數(shù)組的遍歷publicstaticStringforDemo(int[]arr){StringBuildersbuilder=newStringBuilder("【");for(inti=0;i<arr.length;i++){sbuilder.append(arr[i]+",");}sbuilder.setCharAt(sbuilder.length()-2,'】');returnsbuilder.toString();}//數(shù)組的遍歷publicstaticStringforDemo(String[]arr){StringBuildersbuilder=newStringBuilder("【");for(inti=0;i<arr.length;i++){sbuilder.append(arr[i]+",");}sbuilder.setCharAt(sbuilder.length()-2,'】');returnsbuilder.toString();}//使用增強型for循環(huán)遍歷數(shù)組publicstaticStringenhanceForDemo(String[]arr){StringBuildersbuilder=newStringBuilder("【");for(Stringstr:arr){sbuilder.append(str+",");}sbuilder.setCharAt(sbuilder.length()-2,'】');returnsbuilder.toString();}}運行結(jié)果如圖6-13所示。任務6-9二維數(shù)組文件ArrayDemo1.javapublicclassArrayDemo1{publicstaticvoidmain(String[]args){int[][]arr=newint[4][];//創(chuàng)建二維數(shù)組時,只需要指定前一個維度的元素個數(shù)即可int[]arrSub=newint[5];//創(chuàng)建一個一維數(shù)組Arrays.fill(arrSub,5);System.out.println("arrSub="+ArrayDemo.forDemo(arrSub));//輸出/**可以將二維數(shù)組理解為以一維數(shù)組為元素的一維數(shù)組*/arr[0]=arrSub;int[][]arrInt={{1,2,3},{5,6,7,8},{1,2}};System.out.print("arrInt=【");for(inti=0;i<arrInt.length;i++){for(intj=0;j<arrInt[i].length;j++){if(!(i==arrInt.length-1&&j==arrInt[i].length-1)){System.out.print(arrInt[i][j]+",");}else{System.out.print(arrInt[i][j]);}}}System.out.println("】");}}運行結(jié)果如圖6-14所示。目錄導航6.1集合初探6.3數(shù)組6.5單元小結(jié)6.2集合的遍歷6.4項目實戰(zhàn)項目6-1實現(xiàn)Mapper和Reducer接口CustomMapper類學習集合之后,我們就可以實現(xiàn)第5單元項目實戰(zhàn)中的Mapper接口和Reducer接口了。步驟如下。step01

定義CustomMapper類,實現(xiàn)Mapper接口的map()方法,代碼如下:classCustomMapperimplementsMapper{@OverridepublicMap<String,String>map(Stringkey,Stringvalue){Map<String,Integer>counter=newHashMap<>();StringTokenizerstringTokenizer=newStringTokenizer(value);while(stringTokenizer.hasMoreTokens()){Stringtoken=stringTokenizer.nextToken();intcount=counter.getOrDefault(token,0);counter.put(token,count+1);}Map<String,String>result=newHashMap<>();for(Map.Entry<String,Integer>entry:counter.entrySet()){result.put(entry.getKey(),entry.getValue().toString());}returnresult;}}項目6-1實現(xiàn)Mapper和Reducer接口step02

定義CustomReducer類,實現(xiàn)Reducer接口的reduce()方法,代碼如下:CustomReducer類classCustomReducerimplementsReducer{@OverridepublicMap<String,String>reduce(Stringkey,List<String>values){Map<String,String>result=newHashMap<>();intsum=0;for(Stringvalue:values){sum+=Integer.parseInt(value);}result.put(key,String.valueOf(sum));returnresult;}}項目6-2三人斗地主——洗牌發(fā)牌程序本項目模擬三人斗地主的摸牌場景,編寫一個自動洗牌發(fā)牌程序。程序流程如下。①

實現(xiàn)洗牌操作,生成各種數(shù)值和花色的牌并放入一個亂序集合中。

隨機抽取3張牌作為底牌。

隨機選擇一張牌作為地主牌。

輪流給3個玩家分發(fā)剩余的牌。

將底牌發(fā)給抽到地主牌的玩家。程序的具體代碼如下所示。文件DealCardsDemo.javapublicclassDealCardsDemo{List<String>cardList=newArrayList<>(); //隨機牌數(shù)組的鏈表privateList<String>bottomCards=newArrayList<>(); //底牌數(shù)組privateStringlandLordCard=null; //地主牌privateRandomrm=newRandom(); //隨機數(shù)生成對象實例privateList<String>playerA=newArrayList<>(); //玩家AprivateList<String>playerB=newArrayList<>(); //玩家BprivateList<String>playerC=newArrayList<>(); //玩家C項目6-2三人斗地主——洗牌發(fā)牌程序publicstaticvoidmain(String[]args){DealCardsDemodealCards=newDealCardsDemo();//初始化對象dealCards.dealCards();//發(fā)牌System.out.println("玩家A的手牌是:");showCards(dealCards.getPlayerA());System.out.println("玩家B的手牌是:");showCards(dealCards.getPlayerB());System.out.println("玩家C的手牌是:");showCards(dealCards.getPlayerC());}//發(fā)牌程序publicvoiddealCards(){cardList=newArrayList<>(getCardSet());//獲取3張底牌while(bottomCards.size()<3){//從隨機牌數(shù)組中抽出一張牌(刪除),并將該牌放入底牌數(shù)組中bottomCards.add(cardList.remove(rm.nextInt(cardList.size())));}landLordCard=cardList.get(rm.nextInt(cardList.size()));//從剩余牌中抽一張牌作為地主牌System.out.println("地主牌是:"+landLordCard);

//循環(huán)發(fā)牌給玩家A、玩家B和玩家C(假設玩家A先摸牌)intcardNumber=cardList.size();System.out.println("發(fā)牌開始!");System.out.println("...");for(inti=1;i<=cardNumber;i++){if(i%3==0){//如果下標加1的值是3的倍數(shù),說明這張牌是玩家C的playerC.add(cardList.get(i-1));}elseif(i%2==0){//如果下標加1的值是2的倍數(shù),說明這張牌是玩家B的playerB.add(cardList.get(i-1));}else{//否則,這張牌就是玩家A的playerA.add(cardList.get(i-1));}}System.out.println("發(fā)牌結(jié)束!");System.out.println("底牌是:"+bottomCards);項目6-2三人斗地主——洗牌發(fā)牌程序if(playerA.contains(landLordCard)){System.out.println("地主是玩家A");while(!bottomCards.isEmpty()){playerA.add(bottomCards.remove(0));//刪除底牌數(shù)組并將其中的牌發(fā)給地主}}elseif(playerB.contains(landLordCard)){System.out.println("地主是玩家B");while(!bottomCards.isEmpty()){playerB.add(bottomCards.remove(0));//刪除底牌數(shù)組并將其中的牌發(fā)給地主}}else{System.out.println("地主是玩家C");while(!bottomCards.isEmpty()){playerC.add(bottomCards.remove(0));//刪除底牌數(shù)組并將其中的牌發(fā)給地主}}}//隨機牌數(shù)組生成程序publicSet<String>getCardSet(){Set<String>cardSet=newHashSet<>();//存儲隨機牌的Set數(shù)組Map<String,Integer>timesCounter=newHashMap<>();//牌面值出現(xiàn)的次數(shù)List<String>cardColors=getCardColor();//牌面顏色鏈表List<String>cardValues=getCardValue();//牌面值鏈表項目6-2三人斗地主——洗牌發(fā)牌程序//如果牌面值鏈表中還有值,說明牌組還沒有初始化while(!cardValues.isEmpty()){StringcardColor=cardColors.get(rm.nextInt(cardColors.size())); //獲取牌面顏色(隨機)StringcardValue=cardValues.get(rm.next

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論