<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## Java編程那些事兒80——集合框架簡述 陳躍峰 出自:[http://blog.csdn.net/mailbomb](http://blog.csdn.net/mailbomb) ### 9.6.3 集合框架簡述 在JDK API中專門設計了一組類,這組類的功能就是實現各種各樣方式的數據存儲,這樣一組專門用來存儲其它對象的類,一般被稱為對象容器類,簡稱容器類,這組類和接口的設計結構也被統稱為集合框架(Collection Framework)。 這組類和接口都包含在java.util包中。 為了使整個集合框架中的類便于使用,在設計集合框架時大量的使用接口,實際實現的功能類實現對應的接口,這樣可以保證各個集合類的使用方式保持統一。 在集合框架中,提供的存儲方式共有兩種: 1、按照索引值操作數據 在這種存儲方式中,為每個存儲的數據設定一個索引值,存儲在容器中的第一個元素索引值是0,第二個索引值是1,依次類推。在操作數據時按照索引值操作對應的數據,實現這種方式的集合類都實現java.util.Collection接口。 2、按照名稱操作數據 在這種存儲方式中,為每個存儲的數據設定一個名稱(任意非null的對象都可以作為名稱),以后按照該名稱操作該數據,要求名稱不能重復,每個名稱對應唯一的一個值。這種存儲數據的方式也稱作名稱-數值對,也就是名值對存儲。實現這種方式的幾個類都實現java.util.Map接口。 這里“按照索引值操作數據”的存儲方式,又按照容器內部是否能夠存儲重復的元素,劃分成兩類: 1、允許存儲重復元素。 這種存儲方式中,所有的類都實現了java.util.List接口。 2、不允許存儲重復元素。 這種存儲方式中,所有的類都實現了java.util.Set接口。 這樣,集合框架中的類就分成了三大類: 1、List系列 該系列中的類按照索引值來操作數據,允許存放重復的元素。 2、Set系列 該系列中的類按照索引值來操作數據,不允許存放重復的元素。 3、Map系列 該系列中的類按照名稱來操作數據,名稱不允許重復,值可以重復,一個名稱對應一個唯一的值。 而在數據結構中,實現數據的存儲又可以使用不同的數據結構類型進行存儲,例如數組、鏈表、棧、隊列和樹等,則以上三類集合框架可以使用不同的數據結構類進行實現,使用每種數據結構則具備該中數據結構的特點。例如使用數組則訪問速度快,使用鏈表則便于動態插入和刪除等,這樣就造成了集合框架的復雜性。 另外,在將對象存儲到集合類中,為了加快存儲的速度,要求被存儲對象的類中必須覆蓋equals方法和hashCode方法。 對于這些集合類,下面按照以上三個系列的順序一一進行說明。 #### 9.6.3.1 List系列 List系列的類均實現List接口,大部分的類都以List作為類名的后綴,也有部分該體系中的類命名比較特殊。 該系列中的類,比較常見的有ArrayList和LinkedList兩個。其中ArrayList是以數組為基礎實現的List,而LinkedList則是以鏈表為基礎實現的List,ArrayList擁有數組的優點,而LinkedList擁有鏈表的優點。 由于該體系中的類均實現List接口,所以在這些類的內部,相同的功能方法聲明是保持一致的,下面進行一一介紹: a、add方法 boolean add(Object o) 該方法的作用是追加對象o到已有容器的末尾。 另外一個add方法: void add(int index, Object element) 該方法的作用是將對象element插入到容器中索引值為index的位置,原來位于該位置的對象以及后續的內容將依次向后移動。 b、addAll方法 boolean addAll(Collection c) 該方法的作用是將容器對象c中的每個元素依次添加到當前容器的末尾。 另外一個addAll方法: boolean addAll(int index, Collection c) 該方法的作用是將容器對象c中的第一個元素插入到當前容器中索引值為index的位置,第二個元素插入到當前容器中索引值為index+1的位置,依次類推。而當前容器中原來位于index以及index索引值以后的元素則依次向后移動。 c、get方法 Object get(int index) 該方法的作用是返回當前容器對象中索引值為index的元素的內容。 d、indexOf方法 int indexOf(Object o) 該方法的作用是查找當前容器中是否存在對象o,如果存在則返回該對象第一次出現位置的索引值,如果不存在則返回-1。 另外一個方法lastIndexOf則是從末尾向前查找,返回從末尾向前第一次出現位置的索引值,如果不存在則返回-1。 e、remove方法 Object remove(int index) 該方法的作用是刪除索引值為index的對象的內容,如果刪除成功則返回被刪除對象的內容。 另外一個remove方法: boolean remove(Object o) 該方法的作用是刪除對象內容為o的元素,如果相同的對象有多個,則只刪除索引值小的對象。如果刪除成功則返回true,否則返回false。 無論使用哪一個remove方法,類內部都自動移動將被刪除位置后續的所有元素向前移動,保證索引值的連續性。 f、set方法 Object set(int index, Object element) 該方法的作用是修改索引值為index的內容,將原來的內容修改成對象element的內容。 g、size方法 int size() 該方法的作用是返回當前容器中已經存儲的有效元素的個數。 h、toArray方法 Object[] toArray() 該方法的作用是將當前容器中的元素按照順序轉換成一個Object數組。 下面是一個簡單的以ArrayList類為基礎實現的List系列中類基本使用的示例,代碼如下: ~~~ ?????????????????? import java.util.*; /** ?* 以ArrayList類為基礎演示List系列類的基本使用 ?*/ public class ArrayListUse { ???????? public static void main(String[] args) { ?????????????????? //容器對象的初始化 ?????????????????? List list = new ArrayList();????????????????? ?????????????????? //添加數據 ?????????????????? list.add("1"); ?????????????????? list.add("2"); ?????????????????? list.add("3"); ?????????????????? list.add("1"); ?????????????????? list.add("1");???????????? ?????????????????? //插入數據 ?????????????????? list.add(1,"12");??????????????? ?????????????????? //修改數據 ?????????????????? list.set(2, "a");?????????????????? ?????????????????? //刪除數據 ?????????????????? list.remove("1");?????????????? ?????????????????? //遍歷 ?????????????????? int size = list.size();? //獲得有效個數 ?????????????????? //循環有效索引值 ?????????????????? for(int i = 0;i < size;i++){ ??????????????????????????? System.out.println((String)list.get(i)); ?????????????????? } ???????? } } ~~~ 該程序的運行結果為: 12 a 3 1 1 在List系列中,還包含了Stack(棧)類和Vector(向量)類,Stack類除了實現List系列的功能以外,還實現了棧的結構,主要實現了出棧的pop方法和入棧的push方法。 而Vector類由于需要兼容老版本JDK中緣故,所以在實現的方法中需要提供老版本Vector類中對應的方法,這樣導致Vector類中相同或類似的功能方法一般是成對出現的。 #### 9.6.3.2 Set系列 Set系列中的類都實現了Set接口,該系列中的類均以Set作為類名的后綴。該系列中的容器類,不允許存儲重復的元素。也就是當容器中已經存儲一個相同的元素時,無法實現添加一個完全相同的元素,也無法將已有的元素修改成和其它元素相同。 Set系列中類的這些特點,使得在某些特殊場合的使用比較適合。 該系列中常見的類有: 1、CopyOnWriteArraySet 以數組為基礎實現的Set類。 2、HashSet 以哈希表為基礎實現的Set類。 3、LinkedHashSet 以鏈表為基礎實現的Set類。 4、TreeSet 以樹為基礎實現的Set類。 以不同的數據結構類型實現的Set類,擁有不同數據結構帶來的特性,在實際使用時,根據邏輯的需要選擇合適的Set類進行使用。 Set系列中的類的方法和List系列中的類的方法要比List系列中少很多,例如不支持插入和修改,而且對于Set系列中元素的遍歷也需要轉換為專門的Iterator(迭代器)對象才可以進行遍歷,遍歷時順序和Set中存儲的順序會有所不同。 下面是以HashSet類為基礎實現的示例代碼,代碼如下: ~~~ import java.util.*; /** ?* 以HashSet為基礎演示Set系列類的基本使用 ?*/ public class HashSetUse { ???????? public static void main(String[] args) { ?????????????????? //容器對象的初始化 ?????????????????? Set set = new HashSet();????????? ?????????????????? //添加元素 ?????????????????? set.add("1"); ?????????????????? set.add("2"); ?????????????????? set.add("3"); ?????????????????? set.add("1"); ?????????????????? set.add("1");?????????????????????????????? ?????????????????? //刪除數據 ?????????????????? //set.remove("1");?????????? ?????????????????? //遍歷 ?????????????????? Iterator iterator = set.iterator(); ?????????????????? while(iterator.hasNext()){ ??????????????????????????? System.out.println((String)iterator.next()); ?????????????????? } ???????? } } ~~~ 該程序的運行結果為: 3 2 1 #### 9.6.3.3 Map系列 Map系列中的類都實現了Map接口,該系列中的部分類以Map作為類名的后綴。該系列容器類存儲元素的方式和以上兩種完全不同。 Map提供了一種使用“名稱:值”這樣的名稱和數值對存儲數據的方法,在該存儲方式中,名稱不可以重復,而不同的名稱中可以存儲相同的數值。具體這種存儲的格式將在示例代碼中進行實現。 在這種存儲結構中,任何不為null的對象都可以作為一個名稱(key)來作為存儲的值(value)的標識,使用這種形式更利于存儲比較零散的數據,也方便數據的查找和獲得。Map類中存儲的數據沒有索引值,系統會以一定的形式索引存儲的名稱,從而提高讀取數據時的速度。 該系列中常見的類有: 1、HashMap 以Hash(哈希表)為基礎實現的Map類。 2、LinkedHashMap 以鏈表和Hash(哈希表)為基礎實現的Map類。 3、TreeMap 以樹為基礎實現的Map類。 和上面的結構類似,以不同的數據結構實現的Map類,擁有不同數據結構的特點,在實際的項目中使用時,根據需要選擇合適的即可。 該系列的類中常見的方法如下: a、get方法 Object get(Object key) 該方法的作用是獲得當前容器中名稱為key的結構對應的值。 b、keySet方法 Set keySet() 該方法的作用是返回當前容器中所有的名稱,將所有的名稱以Set的形式返回。使用這個方法可以實現對于Map中所有元素的遍歷。 c、put方法 Object put(Object key, Object value) 該方法的作用是將值value以名稱key的形式存儲到容器中。 d、putAll方法 void putAll(Map t) 該方法的作用是將Map對象t中的所有數據按照原來的格式存儲到當前容器類中,相當于合并兩個Map容器對象。 e、remove方法 Object remove(Object key) 該方法的作用是刪除容器中名稱為key的值。 f、size方法 int size() 該方法的作用是返回當前日期中存儲的名稱:值數據的組數。 g、values方法 Collection values() 該方法的作用是返回當前容器所有的值組成的集合,以Collection對象的形式返回。 下面是一個簡單的示例,在該示例中演示Map系列類的基本使用,代碼如下: ~~~ import java.util.*; /** ?* 以HashMap為基礎演示Map系列中類的使用 ?*/ public class HashMapUse { ???????? public static void main(String[] args) { ?????????????????? //容器對象的初始化 ?????????????????? Map map = new HashMap();??????????? ?????????????????? //存儲數據 ?????????????????? map.put("蘋果", "2.5"); ?????????????????? map.put("桔子", "2.5"); ?????????????????? map.put("香蕉", "3"); ?????????????????? map.put("菠蘿", "2");????????????? ?????????????????? //刪除元素 ?????????????????? map.remove("桔子");?????????????? ?????????????????? //修改元素的值 ?????????????????? map.put("菠蘿", "5");????????????? ?????????????????? //獲得元素個數 ?????????????????? int size = map.size(); ?????????????????? System.out.println("個數是:" + size);?????????? ?????????????????? //遍歷Map ?????????????????? Set set = map.keySet(); ?????????????????? Iterator iterator = set.iterator(); ?????????????????? while(iterator.hasNext()){ ??????????????????????????? //獲得名稱 ??????????????????????????? String name = (String)iterator.next(); ??????????????????????????? //獲得數值 ??????????????????????????? String value = (String)map.get(name); ??????????????????????????? //顯示到控制臺 ??????????????????????????? System.out.println(name + ":" + value); ?????????????????? } ???????? } } ~~~ 該程序的運行結果為: 個數是:3 香蕉:3 菠蘿:5 蘋果:2.5 #### 9.6.3.4 使用示例 如前所述,集合框架中的類只是提供了一種數據存儲的方式,在實際使用時,可以根據邏輯的需要選擇合適的集合類進行使用。 下面以一個字符串計算的示例演示集合類的實際使用。 該程序的功能為計算一個數字字符串,例如”1+2*31-5”、”12*30/34-450”等,的計算結果,在該示例中支持四則運算,但是不支持括號。本示例中計算的字符串要求合法。 該程序實現的原理是:首先按照運算符作為間隔,將字符串差分為數字字符串和運算符字符串的序列,由于分拆出的字符串數量不固定,所以存儲到List系列的Vector容器中,然后按照運算符的優先級進行計算。 該程序的代碼如下: ~~~ import java.util.*; /** ?* 計算字符串的值 ?*/ public class CalcStr { ???????? public static void main(String[] args) { ?????????????????? String s = "1+20*3/5"; ?????????????????? double d = calc(s); ?????????????????? System.out.println(d); ???????? }??????? ???????? /** ???????? ?* 計算字符串的值 ???????? ?* @param s 需要計算的字符串 ???????? ?* @return 計算結果 ???????? ?*/ ???????? public static double calc(String s){ ?????????????????? //拆分字符串 ?????????????????? Vector v = split(s); ?????????????????? //print(v); //測試代碼 ?????????????????? //計算字符串 ?????????????????? double d = calcVector(v); ?????????????????? return d; ???????? } ???????? ???????? /** ???????? ?* 將字符串拆分為數字和運算符。 ???????? ?* 例如:"1+23*4"則拆分為:"1"、"+"、"23"、"*"和"4" ???????? ?* @param s 需要拆分的字符串 ???????? ?* @return 拆分以后的結果 ???????? ?*/ ???????? private static Vector split(String s){ ?????????????????? Vector v = new Vector(); ?????????????????? String content = ""; ?????????????????? int len = s.length(); //字符串長度 ?????????????????? char c; ?????????????????? for(int i = 0;i < len;i++){ ??????????????????????????? c = s.charAt(i); ??????????????????????????? //判斷是否為運算符 ??????????????????????????? if(c == '+' || ???????????????????????????????????? c == '-' || ???????????????????????????????????? ?c == '*' || ???????????????????????????????????? ? c == '/'){ ???????????????????????????????????? //存儲數字 ???????????????????????????????????? v.add(content); ???????????????????????????????????? //存儲運算符 ???????????????????????????????????? v.add("" + c); ???????????????????????????????????? //清除已有字符串 ???????????????????????????????????? content = ""; ??????????????????????????? }else{ ???????????????????????????????????? content += c; //連接字符串 ??????????????????????????? } ?????????????????? } ?????????????????? v.add(content); //添加最后一個數字 ?????????????????? return v; ???????? } ???????? ???????? /** ???????? ?* 測試代碼,輸出拆分以后的結果 ???????? ?* @param v 需要打印的Vector對象 ???????? ?*/ ???????? private static void print(Vector v){ ?????????????????? int size = v.size(); ?????????????????? for(int i = 0;i < size;i++){ ??????????????????????????? System.out.println((String)v.get(i)); ?????????????????? } ???????? } ???????? ???????? /** ???????? ?* 計算Vector中的數據 ???????? ?* @param v 存儲拆分后字符串的Vector ???????? ?* @return 計算結果 ???????? ?*/ ???????? private static double calcVector(Vector v){ ?????????????????? int index1; ?????????????????? int index2; ?????????????????? //計算乘除 ?????????????????? while(true){ ??????????????????????????? index1 = v.indexOf("*"); //乘號索引值 ??????????????????????????? index2 = v.indexOf("/"); //除號索引值 ??????????????????????????? //無乘除符號 ??????????????????????????? if(index1 == - 1 && index2 == -1){ ???????????????????????????????????? break;? //結束循環 ??????????????????????????? }?????????????????????????? ??????????????????????????? //如果有乘號 ??????????????????????????? if(index1 != -1){ ???????????????????????????????????? //沒有除號或乘號在前 ???????????????????????????????????? if(index2 == -1 || index1 < index2){ ?????????????????????????????????????????????? String s1 = (String)v.get(index1 - 1); //第一個數字 ?????????????????????????????????????????????? String opr = (String)v.get(index1); //運算符 ?????????????????????????????????????????????? String s2 = (String)v.get(index1 + 1); //第二個數字 ?????????????????????????????????????????????? //計算 ?????????????????????????????????????????????? String answer = calc(s1,s2,opr); ?????????????????????????????????????????????? //計算以后的處理 ?????????????????????????????????????????????? handle(answer,index1 - 1,v); ???????????????????????????????????? } ??????????????????????????? } ??????????????????????????? //有除號 ??????????????????????????? if(index2 != -1){ ???????????????????????????????????? //沒有乘號或除號在前 ???????????????????????????????????? if(index1 == -1 || index2 < index1){ ?????????????????????????????????????????????? String s1 = (String)v.get(index2 - 1); //第一個數字 ?????????????????????????????????????????????? String opr = (String)v.get(index2); //運算符 ?????????????????????????????????????????????? String s2 = (String)v.get(index2 + 1); //第二個數字 ?????????????????????????????????????????????? //計算 ?????????????????????????????????????????????? String answer = calc(s1,s2,opr); ?????????????????????????????????????????????? //計算以后的處理 ?????????????????????????????????????????????? handle(answer,index2 - 1,v); ???????????????????????????????????? } ??????????????????????????? } ?????????????????? } ?????????????????? //計算加 ?????????????????? int index3 = v.indexOf("+"); ?????????????????? while(index3 != -1){ //有加號 ??????????????????????????? String s1 = (String)v.get(index3 - 1); //第一個數字 ??????????????????????????? String opr = (String)v.get(index3); //運算符 ??????????????????????????? String s2 = (String)v.get(index3 + 1); //第二個數字 ??????????????????????????? //計算 ??????????????????????????? String answer = calc(s1,s2,opr); ??????????????????????????? //計算以后的處理 ??????????????????????????? handle(answer,index3 - 1,v); ??????????????????????????? //獲得下一個加號的位置 ??????????????????????????? index3 = v.indexOf("+"); ?????????????????? } ?????????????????? ?????????????????? //計算減 ?????????????????? index3 = v.indexOf("-"); ?????????????????? while(index3 != -1){ //有加號 ??????????????????????????? String s1 = (String)v.get(index3 - 1); //第一個數字 ??????????????????????????? String opr = (String)v.get(index3); //運算符 ??????????????????????????? String s2 = (String)v.get(index3 + 1); //第二個數字 ??????????????????????????? //計算 ??????????????????????????? String answer = calc(s1,s2,opr); ??????????????????????????? //計算以后的處理 ??????????????????????????? handle(answer,index3 - 1,v); ??????????????????????????? //獲得下一個減號的位置 ??????????????????????????? index3 = v.indexOf("-"); ?????????????????? } ?????????????????? //反饋結果 ?????????????????? String data = (String)v.get(0); ?????????????????? return Double.parseDouble(data); ???????? } ???????? ???????? /** ???????? ?* 計算兩個字符串類型的值運算結果 ???????? ?* @param number1 數字1 ???????? ?* @param number2 數字2 ???????? ?* @param opr 運算符 ???????? ?* @return 運算結果 ???????? ?*/ ???????? private static String calc(String number1,String number2,String opr){ ?????????????????? //將字符串轉換為數字 ?????????????????? double d1 = Double.parseDouble(number1); ?????????????????? double d2 = Double.parseDouble(number2); ?????????????????? //判斷運算符 ?????????????????? if(opr.equals("+")){ ??????????????????????????? return "" + (d1 + d2); ?????????????????? } ?????????????????? if(opr.equals("-")){ ??????????????????????????? return "" + (d1 - d2); ?????????????????? } ?????????????????? if(opr.equals("*")){ ??????????????????????????? return "" + (d1 * d2); ?????????????????? } ?????????????????? if(opr.equals("/")){ ??????????????????????????? return "" + (d1 / d2); ?????????????????? } ?????????????????? return "0";? //運算符錯誤時返回0 ???????? } ???????? ???????? /** ???????? ?* 計算以后的處理 ???????? ?* @param answer 計算結果 ???????? ?* @param index 參與計算的三個字符串中第一個字符串的起始位置 ???????? ?* @param v 存儲字符串的容器 ???????? ?*/ ???????? private static void handle(String answer,int index,Vector v){ ?????????????????? //刪除計算過的字符串 ?????????????????? for(int i = 0;i < 3;i++){ ??????????????????????????? v.remove(index); ?????????????????? } ?????????????????? //將計算結果插入到index位置 ?????????????????? v.insertElementAt(answer, index); ???????? } } ~~~ 該程序的運行結果為: 13.0 ### 9.7 總結 在本章中,主要介紹了java.lang包和java.util包中比較常見的類的使用,熟悉了JDK API的基本使用,掌握了文檔的查閱以及方法調用等一些基本的技能,為后續章節的學習打下堅實的基礎。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看