創(chuàng)建一個Set集合,保存用戶輸入的數(shù)據(jù)
具體代碼實現(xiàn)如下面代碼中的testSet()方法。
知識點:
Set集合的基本特征是元素不允許重復。HashSet不保存元素順序,linkedHashSet用鏈表保持元素的插入順序,TreeSet可定制排序規(guī)則。
HashSet的底層是用HashMap實現(xiàn)的,即HashMap<key,value>中把所有value置為null,key就組成了一個Set
HashSet把元素的hashCode值作為地址索引來存儲元素,可以實現(xiàn)類似根據(jù)數(shù)組下標索引查找元素的效果,這是HashSet訪問速度快的原因
HashSet中如果兩個元素通過equals比較結(jié)果為true,但是兩個元素的hashCode不相等,即在兩個地方存放了值相等的兩個元素,HashSet將會出現(xiàn)各種奇怪問題,不能正常工作。
基于上面第4點,HashSet元素判斷兩個元素相等的標準是,不僅需要equals比較的結(jié)果為true,而且需要元素hashCode值相等,即不允許equals比較為true但是hashCode不想等的兩個元素存放在HashSet中。
HashSet中允許equals比較為false但是hashCode相等的兩個元素同時存在,這兩個元素將會被存放在同一個位置,并用鏈表維持兩個元素順序,但是這將嚴重影響HashSet的性能。
基于上面4.5.6點,如果需要重寫一個HashSet的equals方法,一定也要重寫hashCode方法,原則是如果equals方法和equals方法使用共同的變量(成員變量)做計算,使得如果equals為true,hashCode結(jié)果值要相等。
linkedHashSet底層多了一個鏈表結(jié)構(gòu)用來保存元素的插入順序(插入位置還是由hashCode決定的),遍歷linkedHashSet時會自動根據(jù)鏈表來遍歷
TreeSet的元素是有序的,有兩種排序規(guī)則,默認是按自然排序(在元素中寫排序規(guī)則,元素必須實現(xiàn)了Comparable接口,且元素類型必須一樣),另一種是定制排序(由集合實現(xiàn)排序規(guī)則,需要集合關聯(lián)一個Comparator對象實現(xiàn))
JAVA中接收鍵盤輸入用System.in.read(),這個方法接收的是byte[]字節(jié),當輸入結(jié)束(回車)時返回-1,但是這個方法會同時將r和n也接收。BufferedReader的readLine()方法可以讀取一行,適應各種平臺的斷行規(guī)則(自動去除換行符r,n等),但是BufferedReader只能讀取stream類型,System.in只能返回byte類型,因此需要用InputStreamReader做轉(zhuǎn)換。
創(chuàng)建一個List集合,隨意添加10個元素,然后通過索引為5處的元素,再取其中某個元素的索引,再刪除索引為3的元素
實現(xiàn)代碼如下面的testList()
知識點,
List集合的基本特征是元素有序,可重復,每個元素都有順序索引。因此List集合可以像數(shù)組一樣使用。
List集合有一個專用迭代器ListIterator,可以實現(xiàn)反向迭代。
ArrayList和Vector底層使用一個智能數(shù)組實現(xiàn),可動態(tài)擴展(ensureCapacity(int i)重新分類空間),
在java.util.Arrays的內(nèi)部也定義了一個ArrayList(通過asList()方法返回),但這是一個不可變定長數(shù)組,不能增加,刪除數(shù)組元素,否則會拋出異常。
Vector是一個古老的集合實現(xiàn)類,Vector所擁有的功能ArrayList基本都有。但是Vector是一個線程安全類,性能上會比ArrayList稍低。另外Vector還有一個子類Stack,實現(xiàn)了棧結(jié)構(gòu)。
linkedList是List的實現(xiàn)類,同時又是Deque的實現(xiàn)類,因此linkedList同時具有ArrayList(隨機存?。┖虯rrayDeque(雙端隊列,棧)的功能。但是linkedList的內(nèi)部實現(xiàn)完全不同,linkedList內(nèi)部使用鏈表實現(xiàn),雖然也linkedList表面上使用的是index索引數(shù)組方式的隨機訪問,但是內(nèi)部實現(xiàn)的時候使用index關聯(lián)了鏈表的順序,依然使用的是迭代訪問,所以性能上比ArrayList差。不過插入和刪除性能更好。
給定["a","b","a","b","c","a","b","c"]數(shù)組,使用Map的key保存字符串的元素,用value保存元素出現(xiàn)的次數(shù)
實現(xiàn)代碼如下面的testMap()
知識點
Map的基本特征是key不重復。key和set存在單向一對一關系。
Map接口中有兩個重要的數(shù)據(jù)結(jié)構(gòu),一個是keySetp,用Set集合保存了所有key;一個是內(nèi)部類Entry,用來封裝key-value對,每個元素對應一個Entry對象,保存在Map的全局數(shù)組transient Entry table[];中。
Map的entrySet()方法可以返回一個Entry對象組成的的Set集合的視圖。注意entrySet中并沒有使用一個Set對象來保存所有Entry集合,而是定義一個EntrySet內(nèi)部類,其中有個iterator()方法可以迭代訪問map的所有Entry對象,調(diào)用EntrySet的iterator()方法就相當于得到了Entry集合的視圖。
HashMap中,每次put進一個新元素時,都會在底層new一個Entry類來關聯(lián)key-value,并將Entry對象保存在Map的全局數(shù)組transient Entry table[];中
由上面可知遍歷HashMap至少有四種方法。1)集合通用方法value=iterator.next。2)map常規(guī)方法value=map.get(key).3)遍歷entrySet集合。value=map.entrySet.getValue().4)遍歷values集合value=map.values...
HashMap和Hashtable的關系,可以類比HashSet跟Vector.Hashtable是一個古老的,線程安全的集合。
HashMap跟HashSet判斷元素是否相等的標準一樣,都是需要同時滿足equals為true,且元素hashCode值相等才認為是相同元素。equals為true但hashCode不相等的兩個元素可以存入map中,但是不能正常工作;equals為false但hashCode相等會認為是不同元素,存放在同一個地方,用鏈表關聯(lián)value,性能低。
linkedHashMap跟linkedHashSet一樣,也用(雙向)鏈表維護元素的插入順序(key順序)。
以上三個練習題實現(xiàn)代碼如下
package?test;import?java.io.BufferedReader;import?java.io.IOException;import?java.io.InputStreamReader;import?java.util.ArrayList;import?java.util.HashMap;import?java.util.HashSet;import?java.util.Iterator;import?java.util.linkedHashSet;import?java.util.linkedList;import?java.util.List;import?java.util.Map;import?java.util.Set;import?java.util.TreeSet;class?A?{????public?int?count;????public?A(int?count)?{????????this.count?=?count;????}????public?boolean?equals(Object?obj){????????if?(this?==?obj)?{????????????return?true;????????}????????if?(obj?!=?null?&&?obj.getClass()?==?A.class)?{????????????A?r?=?(A)obj;????????????return?r.count?==?this.count;????????}????????return?false;????}????public?int?hashCode()?{????????return?this.count;????}????public?String?toString()?{????????return?this.count+"";????}}public?class?TestCollection?{????//練習一:創(chuàng)建一個Set集合,保存用戶輸入的數(shù)據(jù)????public?static?void?testSet()?throws?Exception?{????????????????????????//HashSet無序,不重復????????Set?set?=?new?HashSet();????????int?keyIn;????????int?num?=?0;????????while?(?num++?<?2)?{????????????????????????????????????BufferedReader?br?=?new?BufferedReader(new?InputStreamReader(System.in));????????????keyIn?=?Integer.parseInt(br.readLine());????????????set.add(new?A(keyIn));????????}????????System.out.println(set);????}????//練習二????public?static?void?testList()?{????????List?list?=?new?linkedList();????????//List?list?=?new?ArrayList();????????for?(int?i=0;?i<10;?i++)?{????????????list.add(new?A(i));????????}????????list.add(new?A(5));????????System.out.println(list);????????System.out.println(list.get(5));????????//這里雖然用的是new?A(6),但是在list中仍然可以找到這個元素,原因是在上面的class?A中重寫了equal和hashCode方法????????System.out.println(list.indexOf(new?A(6)));????????System.out.println(list.remove(3));????????System.out.println(list);????}????//練習三????public?static?void?testMap()?{????????String[]?str?=?new?String[]?{"a","b","a","b","c","a","b","c"};????????Map?map?=?new?HashMap();????????Set?set?=?new?linkedHashSet();????????for?(int?i?=?0;?i?<?str.length;?i++)?{????????????set.add(str[i]);????????}????????String?key;????????Iterator?it?=?set.iterator();????????while?(it.hasNext())?{????????????int?val?=?0;????????????key?=?(String)it.next();????????????for?(int?i?=?0;?i?<?str.length;?i++)?{????????????????if?(str[i]?==?key)?val++;????????????}????????????map.put(key,?val);????????}????????System.out.println(map);????}????public?static?void?main(String[]?args)?throws?Exception?{????????//TestCollection.testSet();????????TestCollection.testList();????????//TestCollection.testMap();????}}
以上就是長沙牛耳教育java培訓機構(gòu)的小編針對“經(jīng)典Java基礎知識練習題”的內(nèi)容進行的回答,希望對大家有所幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為你服務。