<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## [集合的打印](https://lingcoder.gitee.io/onjava8/#/book/12-Collections?id=%e9%9b%86%e5%90%88%e7%9a%84%e6%89%93%e5%8d%b0) 必須使用`Arrays.toString()`來生成數組的可打印形式。但是打印集合無需任何幫助。下面是一個例子,這個例子中也介紹了基本的Java集合: ~~~ // collections/PrintingCollections.java // Collections print themselves automatically import java.util.*; public class PrintingCollections { static Collection fill(Collection<String> collection) { collection.add("rat"); collection.add("cat"); collection.add("dog"); collection.add("dog"); return collection; } static Map fill(Map<String, String> map) { map.put("rat", "Fuzzy"); map.put("cat", "Rags"); map.put("dog", "Bosco"); map.put("dog", "Spot"); return map; } public static void main(String[] args) { System.out.println(fill(new ArrayList<>())); System.out.println(fill(new LinkedList<>())); System.out.println(fill(new HashSet<>())); System.out.println(fill(new TreeSet<>())); System.out.println(fill(new LinkedHashSet<>())); System.out.println(fill(new HashMap<>())); System.out.println(fill(new TreeMap<>())); System.out.println(fill(new LinkedHashMap<>())); } } /* Output: [rat, cat, dog, dog] [rat, cat, dog, dog] [rat, cat, dog] [cat, dog, rat] [rat, cat, dog] {rat=Fuzzy, cat=Rags, dog=Spot} {cat=Rags, dog=Spot, rat=Fuzzy} {rat=Fuzzy, cat=Rags, dog=Spot} */ ~~~ 這顯示了Java集合庫中的兩個主要類型。它們的區別在于集合中的每個“槽”(slot)保存的元素個數。**Collection**類型在每個槽中只能保存一個元素。此類集合包括:**List**,它以特定的順序保存一組元素;**Set**,其中元素不允許重復;**Queue**,只能在集合一端插入對象,并從另一端移除對象(就本例而言,這只是查看序列的另一種方式,因此并沒有顯示它)。**Map**在每個槽中存放了兩個元素,即*鍵*和與之關聯的*值*。 默認的打印行為,使用集合提供的`toString()`方法即可生成可讀性很好的結果。**Collection**打印出的內容用方括號括住,每個元素由逗號分隔。**Map**則由大括號括住,每個鍵和值用等號連接(鍵在左側,值在右側)。 第一個`fill()`方法適用于所有類型的**Collection**,這些類型都實現了`add()`方法以添加新元素。 **ArrayList**和**LinkedList**都是**List**的類型,從輸出中可以看出,它們都按插入順序保存元素。兩者之間的區別不僅在于執行某些類型的操作時的性能,而且**LinkedList**包含的操作多于**ArrayList**。本章后面將對這些內容進行更全面的探討。 **HashSet**,**TreeSet**和**LinkedHashSet**是**Set**的類型。從輸出中可以看到,**Set**僅保存每個相同項中的一個,并且不同的**Set**實現存儲元素的方式也不同。**HashSet**使用相當復雜的方法存儲元素,這在[附錄:集合主題](https://lingcoder.gitee.io/onjava8/#/)中進行了探討。現在只需要知道,這種技術是檢索元素的最快方法,因此,存儲順序看上去沒有什么意義(通常只關心某事物是否是**Set**的成員,而存儲順序并不重要)。如果存儲順序很重要,則可以使用**TreeSet**,它將按比較結果的升序保存對象)或**LinkedHashSet**,它按照被添加的先后順序保存對象。 **Map**(也稱為*關聯數組*)使用*鍵*來查找對象,就像一個簡單的數據庫。所關聯的對象稱為*值*。 假設有一個**Map**將美國州名與它們的首府聯系在一起,如果想要俄亥俄州(Ohio)的首府,可以用“Ohio”作為鍵來查找,幾乎就像使用數組下標一樣。正是由于這種行為,對于每個鍵,**Map**只存儲一次。 `Map.put(key, value)`添加一個所想要添加的值并將它與一個鍵(用來查找值)相關聯。`Map.get(key)`生成與該鍵相關聯的值。上面的示例僅添加鍵值對,并沒有執行查找。這將在稍后展示。 請注意,這里沒有指定(或考慮)**Map**的大小,因為它會自動調整大小。 此外,**Map**還知道如何打印自己,它會顯示相關聯的鍵和值。 本例使用了**Map**的三種基本風格:**HashMap**,**TreeMap**和**LinkedHashMap**。 鍵和值保存在**HashMap**中的順序不是插入順序,因為**HashMap**實現使用了非常快速的算法來控制順序。**TreeMap**通過比較結果的升序來保存鍵,**LinkedHashMap**在保持**HashMap**查找速度的同時按鍵的插入順序保存鍵。 ## [列表List](https://lingcoder.gitee.io/onjava8/#/book/12-Collections?id=%e5%88%97%e8%a1%a8list) **List**承諾將元素保存在特定的序列中。**List**接口在**Collection**的基礎上添加了許多方法,允許在**List**的中間插入和刪除元素。 有兩種類型的**List**: * 基本的**ArrayList**,擅長隨機訪問元素,但在**List**中間插入和刪除元素時速度較慢。 * **LinkedList**,它通過代價較低的在**List**中間進行的插入和刪除操作,提供了優化的順序訪問。**LinkedList**對于隨機訪問來說相對較慢,但它具有比**ArrayList**更大的特征集。 下面的示例導入**typeinfo.pets**,超前使用了[類型信息](https://lingcoder.gitee.io/onjava8/#/)一章中的類庫。這個類庫包含了**Pet**類層次結構,以及用于隨機生成**Pet**對象的一些工具類。此時不需要了解完整的詳細信息,只需要知道兩點: 1. 有一個**Pet**類,以及**Pet**的各種子類型。 2. 靜態的`Pets.arrayList()`方法返回一個填充了隨機選取的**Pet**對象的**ArrayList**: ~~~ // collections/ListFeatures.java import typeinfo.pets.*; import java.util.*; public class ListFeatures { public static void main(String[] args) { Random rand = new Random(47); List<Pet> pets = Pets.list(7); System.out.println("1: " + pets); Hamster h = new Hamster(); pets.add(h); // Automatically resizes System.out.println("2: " + pets); System.out.println("3: " + pets.contains(h)); pets.remove(h); // Remove by object Pet p = pets.get(2); System.out.println( "4: " + p + " " + pets.indexOf(p)); Pet cymric = new Cymric(); System.out.println("5: " + pets.indexOf(cymric)); System.out.println("6: " + pets.remove(cymric)); // Must be the exact object: System.out.println("7: " + pets.remove(p)); System.out.println("8: " + pets); pets.add(3, new Mouse()); // Insert at an index System.out.println("9: " + pets); List<Pet> sub = pets.subList(1, 4); System.out.println("subList: " + sub); System.out.println("10: " + pets.containsAll(sub)); Collections.sort(sub); // In-place sort System.out.println("sorted subList: " + sub); // Order is not important in containsAll(): System.out.println("11: " + pets.containsAll(sub)); Collections.shuffle(sub, rand); // Mix it up System.out.println("shuffled subList: " + sub); System.out.println("12: " + pets.containsAll(sub)); List<Pet> copy = new ArrayList<>(pets); sub = Arrays.asList(pets.get(1), pets.get(4)); System.out.println("sub: " + sub); copy.retainAll(sub); System.out.println("13: " + copy); copy = new ArrayList<>(pets); // Get a fresh copy copy.remove(2); // Remove by index System.out.println("14: " + copy); copy.removeAll(sub); // Only removes exact objects System.out.println("15: " + copy); copy.set(1, new Mouse()); // Replace an element System.out.println("16: " + copy); copy.addAll(2, sub); // Insert a list in the middle System.out.println("17: " + copy); System.out.println("18: " + pets.isEmpty()); pets.clear(); // Remove all elements System.out.println("19: " + pets); System.out.println("20: " + pets.isEmpty()); pets.addAll(Pets.list(4)); System.out.println("21: " + pets); Object[] o = pets.toArray(); System.out.println("22: " + o[3]); Pet[] pa = pets.toArray(new Pet[0]); System.out.println("23: " + pa[3].id()); } } /* Output: 1: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug] 2: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Hamster] 3: true 4: Cymric 2 5: -1 6: false 7: true 8: [Rat, Manx, Mutt, Pug, Cymric, Pug] 9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug] subList: [Manx, Mutt, Mouse] 10: true sorted subList: [Manx, Mouse, Mutt] 11: true shuffled subList: [Mouse, Manx, Mutt] 12: true sub: [Mouse, Pug] 13: [Mouse, Pug] 14: [Rat, Mouse, Mutt, Pug, Cymric, Pug] 15: [Rat, Mutt, Cymric, Pug] 16: [Rat, Mouse, Cymric, Pug] 17: [Rat, Mouse, Mouse, Pug, Cymric, Pug] 18: false 19: [] 20: true 21: [Manx, Cymric, Rat, EgyptianMau] 22: EgyptianMau 23: 14 */ ~~~ 打印行都編了號,因此可從輸出追溯到源代碼。 第 1 行輸出展示了原始的由**Pet**組成的**List**。 與數組不同,**List**可以在創建后添加或刪除元素,并自行調整大小。這正是它的重要價值:一種可修改的序列。在第 2 行輸出中可以看到添加一個**Hamster**的結果,該對象將被追加到列表的末尾。 可以使用`contains()`方法確定對象是否在列表中。如果要刪除一個對象,可以將該對象的引用傳遞給`remove()`方法。同樣,如果有一個對象的引用,可以使用`indexOf()`在**List**中找到該對象所在位置的下標號,如第 4 行輸出所示中所示。 當確定元素是否是屬于某個**List**,尋找某個元素的索引,以及通過引用從**List**中刪除元素時,都會用到`equals()`方法(根類**Object**的一個方法)。每個**Pet**被定義為一個唯一的對象,所以即使列表中已經有兩個**Cymrics**,如果再創建一個新的**Cymric**對象并將其傳遞給`indexOf()`方法,結果仍為**\-1**(表示未找到),并且嘗試調用`remove()`方法來刪除這個對象將返回**false**。對于其他類,`equals()`的定義可能有所不同。例如,如果兩個**String**的內容相同,則這兩個**String**相等。因此,為了防止出現意外,請務必注意**List**行為會根據`equals()`行為而發生變化。 第 7、8 行輸出展示了刪除與**List**中的對象完全匹配的對象是成功的。 可以在**List**的中間插入一個元素,就像在第 9 行輸出和它之前的代碼那樣。但這會帶來一個問題:對于**LinkedList**,在列表中間插入和刪除都是廉價操作(在本例中,除了對列表中間進行的真正的隨機訪問),但對于**ArrayList**,這可是代價高昂的操作。這是否意味著永遠不應該在**ArrayList**的中間插入元素,并最好是轉換為**LinkedList**?不,它只是意味著你應該意識到這個問題,如果你開始在某個**ArrayList**中間執行很多插入操作,并且程序開始變慢,那么你應該看看你的**List**實現有可能就是罪魁禍首(發現此類瓶頸的最佳方式是使用分析器 profiler)。優化是一個很棘手的問題,最好的策略就是置之不顧,直到發現必須要去擔心它了(盡管去理解這些問題總是一個很好的主意)。 `subList()`方法可以輕松地從更大的列表中創建切片,當將切片結果傳遞給原來這個較大的列表的`containsAll()`方法時,很自然地會得到**true**。請注意,順序并不重要,在第 11、12 行輸出中可以看到,在**sub**上調用直觀命名的`Collections.sort()`和`Collections.shuffle()`方法,不會影響`containsAll()`的結果。`subList()`所產生的列表的幕后支持就是原始列表。因此,對所返回列表的更改都將會反映在原始列表中,反之亦然。 `retainAll()`方法實際上是一個“集合交集”操作,在本例中,它保留了同時在**copy**和**sub**中的所有元素。請再次注意,所產生的結果行為依賴于`equals()`方法。 第 14 行輸出展示了使用索引號來刪除元素的結果,與通過對象引用來刪除元素相比,它顯得更加直觀,因為在使用索引時,不必擔心`equals()`的行為。 `removeAll()`方法也是基于`equals()`方法運行的。 顧名思義,它會從**List**中刪除在參數**List**中的所有元素。 `set()`方法的命名顯得很不合時宜,因為它與**Set**類存在潛在的沖突。在這里使用“replace”可能更適合,因為它的功能是用第二個參數替換索引處的元素(第一個參數)。 第 17 行輸出表明,對于**List**,有一個重載的`addAll()`方法可以將新列表插入到原始列表的中間位置,而不是僅能用**Collection**的`addAll()`方法將其追加到列表的末尾。 第 18 - 20 行輸出展示了`isEmpty()`和`clear()`方法的效果。 第 22、23 行輸出展示了如何使用`toArray()`方法將任意的**Collection**轉換為數組。這是一個重載方法,其無參版本返回一個**Object**數組,但是如果將目標類型的數組傳遞給這個重載版本,那么它會生成一個指定類型的數組(假設它通過了類型檢查)。如果參數數組太小而無法容納**List**中的所有元素(就像本例一樣),則`toArray()`會創建一個具有合適尺寸的新數組。**Pet**對象有一個`id()`方法,可以在所產生的數組中的對象上調用這個方法。
                  <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>

                              哎呀哎呀视频在线观看