1. 程式人生 > >Java基礎--集合類

Java基礎--集合類

最近在找工作,目前還沒有定下來,拿到了一個公司的offer,不過被當白菜了,正在商量薪資方面的事情。隨著百度面試的失敗,夢想再次破滅。想想這一年來的奮鬥,別是一番滋味在心頭。突然想起一句話:踏歌長行,夢想永在!

說程式設計師是幸福的,因為我們每天都會和大腦過意不去,故意去挑戰,因為我們總是在與IDE經歷了一系列的戰鬥後,露出欣喜的表情,也因為我們總是以自己從事複雜的、高智商的工作而驕傲、自豪!

本章是Java之美[從菜鳥到高手演變]系列集合類。集合類是Java語言中非常重要的一類知識,Java很多的應用都離不開它。我們有必要認真研究一下。

本部落格永久更新,如有轉載,

請說明出處:http://blog.csdn.net/zhangerqing

如有問題,請聯絡本人: egg

郵箱:[email protected]

微博:http://weibo.com/xtfggef

一、集合類簡介

陣列是很常用的一種的資料結構,我們用它可以滿足很多的功能,但是,有時我們會遇到如下這樣的問題:

1、我們需要該容器的長度是不確定的。

2、我們需要它能自動排序。

3、我們需要儲存以鍵值對方式存在的資料。

如果遇到上述的情況,陣列是很難滿足需求的,接下來本章將介紹另一種與陣列類似的資料結構——集合類,集合類在Java中有很重要的意義,儲存臨時資料,管理物件,泛型,Web框架等,很多都大量用到了集合類。

常見的集合類有這些種:

實現Collection介面的:Set、List以及他們的實現類。

實現Map介面的:HashMap及其實現類,我們常用的有Map及其實現類HashMap,HashTable,List、Set及其實現類ArrayList、HashSet,因為集合類是很大的一塊內容,我們不方便把它的全部內容寫出來,只能慢慢的增加,希望各位讀者有自己想法的,踴躍向我提出,我們共同打造精美的部落格,供廣大程式設計愛好者學習,下面我我們通過一個圖來整體描述一下:


這個圖片沒法顯示的很清楚,所以我將原始圖片上傳到了我的資源裡:http://download.csdn.net/detail/zhangerqing/4711389。願意看清楚的就去下吧。

下面的表格也許可以更直接的表現出他們之間的區別和聯絡:

介面

簡述

實現

操作特性

成員要求

Set

成員不能重複

HashSet

外部無序地遍歷成員

成員可為任意Object子類的物件,但如果覆蓋了equals方法,同時注意修改hashCode方法。

TreeSet

外部有序地遍歷成員;附加實現了SortedSet, 支援子集等要求順序的操作

成員要求實現caparable介面,或者使用 Comparator構造TreeSet。成員一般為同一型別。

LinkedHashSet

外部按成員的插入順序遍歷成員

成員與HashSet成員類似

List

提供基於索引的對成員的隨機訪問

ArrayList

提供快速的基於索引的成員訪問,對尾部成員的增加和刪除支援較好

成員可為任意Object子類的物件

LinkedList

對列表中任何位置的成員的增加和刪除支援較好,但對基於索引的成員訪問支援效能較差

成員可為任意Object子類的物件

Map

儲存鍵值對成員,基於鍵找值操作,compareTo或compare方法對鍵排序

HashMap

能滿足使用者對Map的通用需求

鍵成員可為任意Object子類的物件,但如果覆蓋了equals方法,同時注意修改hashCode方法。

TreeMap

支援對鍵有序地遍歷,使用時建議先用HashMap增加和刪除成員,最後從HashMap生成TreeMap;附加實現了SortedMap介面,支援子Map等要求順序的操作

鍵成員要求實現caparable介面,或者使用Comparator構造TreeMap。鍵成員一般為同一型別。

LinkedHashMap

保留鍵的插入順序,用equals 方法檢查鍵和值的相等性

成員可為任意Object子類的物件,但如果覆蓋了equals方法,同時注意修改hashCode方法。

IdentityHashMap

使用== 來檢查鍵和值的相等性。

成員使用的是嚴格相等

WeakHashMap

其行為依賴於垃圾回收執行緒,沒有絕對理由則少用

(上圖來源於網友的總結,已不知是哪位的原創,恕不貼出地址,如原作者看到請聯絡我,必將貼出連結!)

實現Collection介面的類,如Set和List,他們都是單值元素(其實Set內部也是採用的是Map來實現的,只是鍵值一樣,從表面理解,就是單值),不像實現Map介面的類一樣,裡面存放的是key-value(鍵值對)形式的資料。這方面就造成他們很多的不同點,如遍歷方式,前者只能採用迭代或者迴圈來取出值,但是後者可以使用鍵來獲得值得值。

二、基本方法及使用

---------------------------

實現Map介面的

HashMap

Set的實現類HashSet,底層還是呼叫Map介面來處理,所以,此處,我將說下Map介面及其實現類的一些方法。Map介面中的原始方法有:

public abstract int size();
public abstract boolean isEmpty();
public abstract boolean containsKey(Object paramObject);
public abstract boolean containsValue(Object paramObject);
public abstract V get(Object paramObject);
public abstract V put(K paramK, V paramV);
public abstract V remove(Object paramObject);
public abstract void putAll(Map<? extends K, ? extends V> paramMap);
public abstract void clear();
public abstract Set<K> keySet();
public abstract Collection<V> values();
public abstract Set<Entry<K, V>> entrySet();
public abstract boolean equals(Object paramObject);
public abstract int hashCode();

此處細心的讀者會看到,每個方法前都有abstract關鍵字來修飾,其實就是說,介面中的每個方法都是抽象的,有的時候我們寫的時候不加abstract關鍵字,但是在編譯的過程中,JVM會給加上的,所以這點要注意。抽象的方法意味著它沒有方法實現體,同時必須在實現類中重寫,接下來我們依次分析一下他們的實現類HashMap中是怎麼做的。

HashMap的設計複雜而又巧妙,用處廣泛,值得我們深究一下,因為HashMap是一塊很大很重要的知識點,而在這兒我們重點介紹集合類,所以請看這篇文章,關於的文章。

重點方法介紹:

首先是構造方法,大多數情況下,我們採取無參的建構函式來構造雜湊表,

  1. public HashMap()  
  2. {  
  3.   this.entrySet = null;  
  4.   this.loadFactor = 0.75F;  
  5.   this.threshold = 12;  
  6.   this.table = new Entry[16];  
  7.   init();  
  8. }  
此處先介紹三個重要的變數:loadFactor、threshold、table,loadFactor是一個載入因子,threshold是臨界值,table說明雜湊表的底層,其實是個陣列。可以看看他們的宣告方式:

 transient Entry[] table;;
 int threshold;
 final float loadFactor;

細心的讀者似乎又發現一個新問題,為什麼table前面採用的是transient關鍵字呢,那我們得閒來研究下宣告為transient關鍵字的含義:變數如果被宣告為transient型別的話,那麼在序列化的時候,忽略其的值,就是說此處的table,如果將要進行持久化的話,是不會對table的值進行處理的,直接忽略,為什麼此處table會這樣處理呢?因為HashMap的儲存結構,其實就是一個數組+多個連結串列,數組裡存放物件的地址,連結串列存放資料,所以對地址進行持久化是沒有任何意義的。關於這塊知識,我會在另一篇文章中重點介紹。

HashMap的初始容量為0,每增加一對值,容量曾1,這點好理解,我們通過一個小的例子,來看看HashMap的基本使用方法。

  1. package com.xtfggef.map.test;  
  2. import java.util.HashMap;  
  3. import java.util.Map;  
  4. import java.util.Set;  
  5. /** 
  6.  * HashMap的使用 
  7.  * @author erqing 
  8.  *  
  9.  */
  10. publicclass MapTest {  
  11.     publicstaticvoid main(String[] args) {  
  12.         /* 初始化map */
  13.         Map<String, Integer> map = new HashMap<String, Integer>();  
  14.         System.out.println("HashMap的初始值:" + map.size());  
  15.         System.out.println("HashMap是否為空:" + (map.isEmpty() ? "是" : "否"));  
  16.         /* 想map中新增元素 */
  17.         map.put("erqing"1);  
  18.         map.put("niuniu"2);  
  19.         map.put("egg"3);  
  20.         System.out.println(map.size());  
  21.         ;  
  22.         System.out.println("HashMap是否為空:" + (map.isEmpty() ? "是" : "否"));  
  23.         /* 遍歷HashMap中的元素 */
  24.         Set<String> set = map.keySet();  
  25.         for (String s : set) {  
  26.             System.out.println(s + " " + map.get(s) + " " + "hashcode:"
  27.                     + s.hashCode());  
  28.         }  
  29.         /*檢測是否含有某個Key*/
  30.         System.out.println(map.containsKey("egg"));  
  31.         /*檢測是否含有某個Value*/
  32.         System.out.println(map.containsValue(2));  
  33.         /*列印hashCode*/
  34.         System.out.println(map.hashCode());  
  35.     }  
  36. }  
輸出:

HashMap的初始值:0
HashMap是否為空:是
3
HashMap是否為空:否
niuniu 2 hashcode:-1045196352
egg 3 hashcode:100357
erqing 1 hashcode:-1294670850
true
true
1955200455

此處附一個利用HashMap來簡單處理問題的例子,需求在註釋中已經給出,希望讀者好好看看,程式碼不難,但是很多的面試及面試題都用到這個思路,筆者曾經面試的時候,經常會被問題這題的思想,但是就是沒有去親自實現一下,以致在hashmap的操作上被難住了。

  1. package com.xtfggef.hashmap;  
  2. import java.util.HashMap;  
  3. import java.util.Map;  
  4. import java.util.Set;  
  5. /** 
  6.  * 列印在陣列中出現n/2以上的元素 
  7.  * 利用一個HashMap來存放陣列元素及出現的次數 
  8.  * @author erqing 
  9.  * 
  10.  */
  11. publicclass HashMapTest {  
  12.     publicstaticvoid main(String[] args) {  
  13.         int [] a = {2,3,2,2,1,4,2,2,2,7,9,6,2,2,3,1,0};  
  14.         Map<Integer, Integer> map = new HashMap<Integer,Integer>();  
  15.         for(int i=0; i<a.length; i++){  
  16.             if

    相關推薦

    Java基礎--集合

    最近在找工作,目前還沒有定下來,拿到了一個公司的offer,不過被當白菜了,正在商量薪資方面的事情。隨著百度面試的失敗,夢想再次破滅。想想這一年來的奮鬥,別是一番滋味在心頭。突然想起一句話:踏歌長行,夢想永在! 說程式設計師是幸福的,因為我們每天都會和大腦過意不

    黑馬程式設計師——java基礎——集合

    ------- android培訓、java培訓、期待與您交流! ---------- 面嚮物件語言對事物的體現都是以物件的形式,所以為了方便對多個物件的操作,Java就提供了集合類。 集合的繼承

    java基礎集合——ArrayList 源碼略讀

    lec rst extend except ini cts 數據量 bound cif ArrayList是java的動態數組,底層是基於數組實現。 1. 成員變量 public class ArrayList<E> extends AbstractList&l

    java基礎集合——LinkedList 源碼略讀

    serializa 鏈表 ngs 功能 ray 方法 == memory () 1.概覽 LinkedList是java的動態數組另一種實現方式,底層是基於雙向鏈表,而不是數組。 public class LinkedList<E> extends Ab

    面試題-Java基礎-集合和數組

    eset ria design iter 什麽 code zab 索引 鍵值對存儲 1.Java集合類框架的基本接口有哪些? 集合類接口指定了一組叫做元素的對象。集合類接口的每一種具體的實現類都可以選擇以它自己的方式對元素進行保存和排序。有的集合類允許重復的鍵,有些不允

    Java集合容器初步了解

    equals treemap 輸入 strong 字符串數組 通過 system 結構 shm   容器(Collection)     數組是一種容器,集合也是一種容器     java編程中, 裝其他各種各樣的對象(引用類型)的一種東西, 叫容器     (圖書

    Java基礎加強——加載機制

    操作 擴展類 代碼 java類 sys 讓我 接口 加載 使用   什麽叫類加載     JVM把 .class 字節碼文件加載到內存,並進行相關的校驗、解析、初始化,最終轉換為虛擬機可用的JAVA類型的過程,稱為JVM類加載機制。   (當然,JVM並不關心class文件

    黑馬程序猿——JAVA基礎——集合

    安全性 優先 java集合框架 gif map對象 排序 1.2 是否 trac ----------android培訓、java培訓、java學習型技術博客、期待與您交流。------------ 一、關於java中的集合類 首先看一下,大致的

    Java集合

    rowspan 根據 strong 無序 下使用 排序 eem 是否 關系 一、集合與數組 數組(可以存儲基本數據類型)是用來存現對象的一種容器,但是數組的長度固定,不適合在對象數量未知的情況下使用。 集合(只能存儲對象,對象類型可以不一樣)的長度可變,可在多數情況下使用。

    java集合面試題

    構造 是否 自定義 完成 init 隊列 創建 equal 具體類 轉自:https://yq.aliyun.com/articles/78788?spm=5176.8252056.759076.3.uFYrmt java.util包中包含了一系

    JAVA基礎_加載器

    內部類 ror 遇到 大致 otf win class pla nal 什麽是類加載器類加載器是Java語言在1.0版本就引入的。最初是為了滿足JavaApplet需要。現在類加載器在Web容器和OSGI中得到了廣泛的應用,一般來說,Java應用的開發人員不需要直接同類加載

    java集合有哪些他們之間的關系有什麽區別

    jhJava API中所用的集合類,都是實現了Collection接口,他的一個類繼承結構如下:Collection<--List<--Vector 數組實現 查詢快、增刪慢Collection<--List<--ArrayList 數組實現 查詢快、增刪慢Collection

    Java基礎-Random(05)

    tint sca mar ext random類 color ner margin logs 隨機數(Random) 作用:用於產生一個隨機數 使用步驟(和Scanner類似) 導包import java.util.Random; 創建對象Random r = ne

    java基礎--集合框架(強弱)

    字符 收集 erro sts 軟引用 每一個 框架 bject 缺陷 (1) 隊列:單向和雙向 一、單向:一端操作 1、一般:FIFO 2、優先和堆棧: LIFO 二、雙向:兩端操作,頭或尾操作 package com.zwj.que; import

    java基礎 抽象與接口

    重要 自身 接口 多繼承 bst 文件 其他 ron 不同 抽象類:   在面向對象的領域一切都是對象,所有的對象都是通過類來描述的。如果我們要定義的一個類沒有足夠的信息來描述一個具體的對象,還需要其他的具體類來支持,這個時候我們可以考慮使用抽象類。在類定義的前面增加abs

    Java 基礎 集合框架

    con tar java集合 ava 復雜 www div 哈希表 clas   Java中的集合從類的繼承和接口的實現結構來說,可以分為兩大類:   1 繼承自Collection接口,包含List、Set和Queue等接口和實現類。   2 繼承自Map接口,主要包含哈

    java基礎-集合

    navig 其他 prior 體系結構 roc atlas ges 需要 -o 2018-1-23 by Atlas 體系結構 Navigable:可導航的,理解成有秩序的。Priority:優先的。其他個人覺得都常用不解釋。拋開算法,Map和Collection

    JAVA基礎——集合淺析

    div 判斷 要求 ron .info val rowspan adding 雙向鏈表 Java 集合 什麽時候數組會顯得力不從心,沒法滿足需求,需要集合類呢? 不知道具體數據長度 需要自動排序 存儲鍵值對 當然,上面的情況不是絕對的,只是數組比較難滿

    Java基礎12 型轉換與多態

    nds access 一個 轉換 jpg pan out type ret 作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝! 我們之前使用類創造新的類型(type),並使用繼承來便利我們創建類的過

    Java基礎09 數據與方法

    綜合 基本 基礎 gis value stat col 聲明 private 作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝! 我們一直是為了產生對象而定義類(class)的。對象是具有功能的實體