Java:集合

来源:https://www.cnblogs.com/progor/archive/2018/05/17/9052951.html
-Advertisement-
Play Games

本文內容: 什麼是集合 Collection Iterator List set Map Collections工具類 首發日期:2018-05-17 什麼是集合: 集合是一種新容器,集合可以存儲數量不固定的元素(數組的空間是固定的,你申請多少空間以後都不能改變),而集合可以動態的增加空間(有些是空... ...



本文內容:

 

  • 什麼是集合
  • Collection
  • Iterator
  • List
  • set
  • Map
  • Collections工具類

 

首發日期:2018-05-17


什麼是集合:

 

  • 集合是一種新容器,集合可以存儲數量不固定的元素(數組的空間是固定的,你申請多少空間以後都不能改變),而集合可以動態的增加空間(有些是空間不夠時新建一個足夠大的數組再把原來的元素移到新的數組中)。
  • 集合的出現解決的幾個問題:
    • 存儲數量不等的元素。
    • 定義了數據結構,所以集合的元素可以依據數據結構來讀取,比如LinkList(可以理解成鏈表結構的數組),HashSet(哈希表結構)
    • 可以存儲具有映射關係的元素(Map)
  • 集合中存儲的元素都是對象(預設取出的也是一個Object對象),即使存入的是一個數字,也會轉換成 Integer 類。
  • 集合存放的只是對象的引用
  • java中集合類體系主要分為兩類:主要用於存儲普通元素的Collection、用於存儲具有映射關係的元素的Map

 

 

PS:

  • jdk1.5和jdk1.8新增的內容有點多,現在有點新特性沒添上,以後有空再加上去吧。
  • Queue主要為了實現隊列功能,這裡不講述,有興趣自行查找。

 


Collection:

 

介紹:

  • collection是一個抽象介面,是List、Set和Queue介面的父介面

 

方法(父介面定義的方法,實現類中都會有)【具體使用看下麵的具體實現類】:

  • 添加元素:
    • 添加一個元素X:add(X)
    • 添加集合X中全部元素到集合中:addAll(X)
  • 刪除元素:
    • clear():移除此 collection 中的所有元素
    • remove(x):移除指定元素x
    • removeAll(x):移除集合中另一個集合x的元素
  • 檢查:
    • size():檢測集合的元素個數
    • isEmpty():檢測集合是否為空,空返回true
    • contains(x):是否包含某元素x
    • containsAll(x):是否包含另一個集合x中的所有元素。
  • 其他:
    • toArray():將集合轉成數組
    • iterator():返回可以在此集合上進行元素迭代的迭代器
    • equals(x):比較集合是否與x一致。

集合的獲取依賴於迭代器Iterator。

 

 

 

補充:

  • 下麵的各種具體實現類的構造方法都支持傳入一個比較器,用於執行非自然排序(比如String的比較是字元,而我們可以定義成按字元長度排序。)【例子在TreeSet中。】

 


Iterator:

介紹:

  • Iterator是一個介面,它可以對Collection進行元素迭代(如果Collection返回了一個迭代器的話)
  • 基本每一個具體實現類中都實現了Iterator(內部實現),從而使得Iterator可以迭代所有的Collection的具體實現類的元素。

 

迭代方法:

  • hasNext():如果仍有元素可以迭代,則返回 true
  • next():迭代出下一個元素
  • remove():刪除迭代器剛越過的元素(就是剛剛next到的元素)

 

示例:

package 集合;


import java.util.ArrayList;
import java.util.Iterator;
public class IteratorDemo {
    public static void main(String[] args) {
        ArrayList q=new ArrayList();
        //
        q.add("a");
        q.add("b");
        q.add("c");
        q.add("d");
        //使用迭代器迭代
        for(Iterator it=q.iterator();it.hasNext();) {
            Object obj=it.next();
            System.out.println(obj);//a b c d
            if(obj=="a")
                it.remove();
        }
        //刪除後查看一下
        System.out.println(q);
    }
}

 

 

 

補充:

  • 對於List,有一個特別的迭代器介面:ListIterator,這個迭代器專用於List,它比普通的介面多出了增加元素、修改元素、正反向迭代功能。
  • Iterator經常與foreach語句來搭配使用。
    • 但在1.5之後,Collection實現了Iterable介面,使得集合可以直接迭代了。image

 


List:

介紹:

  • List是一個介面,定義的是存儲的元素是有序的集合,
  • 實現List的集合可以使用下標來取出
  • 實現List的集合中元素可以是重覆的。

image

 

特有方法(除了Collection中有的方法):

    • add(index,x):在集合的指定位置index插入指定元素x
    • addAll(index,x):從指定的位置開始,將集合x中的所有元素插入到此列表中。
    • remove(index):移除集合中指定位置index上的元素。
    • get(index):返回列表中指定位置的元素。 【因為List是有下標的,所以支持使用get來獲取元素】
    • set(index, x)用指定元素x替換列表中指定位置index的元素
    • indexOf(X):返回集合中元素x的下標
    • subList(fromIndex,toIndex):根據下標,從集合中取出元素,返回的是一個List
    • listIterator():返回此列表中的元素的列表迭代器。

 

 

常用實現類:

ArrayList:

  • 是一種數組結構的集合,便於查找,增刪麻煩
  • 也有一些新增的方法,但貌似不太重要,有興趣的查文檔吧。
import java.util.ArrayList;
import java.util.Iterator;
public class ListDemo {
    public static void main(String[] args) {
        ArrayList q=new ArrayList();
        //
        q.add("a");
        q.add("b");
        ArrayList a=new ArrayList();
        a.addAll(q);
        a.add("c");
        a.add("d");
        System.out.println(a);//[a, b, c, d],實現了toString,所以可以直接列印出來。
        ////        a.remove("a");
        a.remove(0);
        //
        System.out.println(a.size());//3
        System.out.println(a.contains("b"));//true
        System.out.println(a.isEmpty());//false
        System.out.println(a);//[b, c, d]
        //
        a.set(0, "bag");
        System.out.println(a);
        //使用迭代器迭代
        for(Iterator it=a.iterator();it.hasNext();) {
            System.out.println(it.next());//c d
        }

    }

}

 

LinkedList:

  • 是一種鏈表結構的集合,便於增刪,查找不快。
  • 它的元素插入法是頭插法,所以後面的元素會排在前面。
  • LinkedList還實現了Deque介面,可以用LinkedList來實現堆棧、隊列、雙端隊列。
  • 因為使用了頭插法,所以有幾個方法需要註意一下:
    • addFirst(x):將指定元素插入此列表的開頭
    • addLast(x):將指定元素添加到此列表的結尾。
    • getFirst():返回此列表的第一個元素。
    • getLast():返回此列表的最後一個元素。
    • removeFirst():移除並返回此列表的第一個元素。
    • removeLast():移除並返回此列表的最後一個元素。
    • descendingIterator():返回逆序的迭代器

 

 

 

 

補充:

  • 以前還能見到Vector和Stack,但Vector太過古老,被ArrayList取代,所以這裡不講;而Stack已經被ArrayDeque取代。
  • 這裡不講述線程同步中集合的處理。
  • 對於想在迭代器迭代過程中針對集合進行增刪改的,可以通過返回ListIterator來操作。

 


set

 

介紹:

  • Set是一個介面,定義的是存儲的元素是無序的集合,  
  • 實現Set的集合中元素不可以重覆。
  • 獲取Set集合中的元素只能依靠迭代器。

image

 

新增方法:無新增方法,基本都是Collection中聲明的方法。

 

 

常用實現類:

HashSet:

  • 哈希表結構的集合
  • 利用哈希表結果構成的集合查找速度會很快。

image

 

TreeSet:

  • 二叉樹結構的集合
  • 二叉樹插入元素是有順序的,TreeSet的元素是有序的。
  • 由於二叉樹需要對結點排序(插入的結點位置),預設情況下沒有排序方法,所以元素需要繼承Comparator並重寫compareTo方法來實現元素之間比較大小的功能。
  • 對於TreeSet,compareTo方法來保證元素的唯一性。【這時候可以不重寫equals】

 

 

LinkHashSet:

  • 是HashSet的子類,是鏈表跟哈希表的數據結構的結合,上一個元素會存儲下一個元素的位置,所以可以按順序來取出。

image

 

 

解決集合的元素的重覆:

  • Set集合是不允許重覆元素的,但是集合是不知道我們對象的重覆的判斷依據的,預設情況下判斷依據是判斷兩者是否為同一元素(euqals方法,依據是元素==元素?),如果要依據我們自己的判斷來判斷元素是否重覆,需要重寫元素的equals方法(元素比較相等時調用)【在hastSet中還需要多一步:hashCode方法(元素生成hash碼的規則,生成的哈希碼如果相同則會影響存儲規則--》首先判斷哈希碼是否相同,再判斷元素是否相同,如果元素相同則不存儲,如果不相同則依據哈希規則向後取一個位置存儲(數據結構的知識,這裡不講述))】
  • hashCode()的返回值是元素的哈希碼,如果兩個元素的哈希碼相同,那麼需要進行equals判斷。【所以可以自定義返回值作為哈希碼】
  • equals()返回true代表兩元素相同,返回false代表不同。
import java.util.HashSet;
import java.util.Set;
class Student{
    String name;
    int age;
    Student(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String toString() {//重寫方法,以便sysout能輸出
        return "Student [name=" + name + ", age=" + age + "]";
    }
    public int hashCode() {//這裡使用的是自動生成的代碼,也可以使用自己的規則
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    public boolean equals(Object obj) {//這裡使用的是自動生成的代碼,也可以使用自己的規則
        if (this == obj)//如果兩個地址相同,返回true
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))//這裡根據姓名和年齡來判斷元素是否相同
            return false;
        return true;
    }
    
}

public class HashSetDemo {

    public static void main(String[] args) {
        Set s=new HashSet();
//        s.add("abc");
//        s.add("abc");
//        System.out.println(s);//這裡因為可以使用自帶的判斷方法,所以不會發生重覆
        
//        s.add(new Student("lilei",18));
//        s.add(new Student("lilei",18));
//        System.out.println(s);//這裡因為判斷兩個地址是不同的,所以會重覆。
        
//        在重寫equals之後:
        s.add(new Student("lilei",18));
        s.add(new Student("lilei",18));
        System.out.println(s);//不發生重覆。

    }

}

 

 

解決TreeSet的排序問題:

  • 二叉樹需要結點排序,所以元素之間比較能夠比較,所以對於自定義元素對象,需要繼承Comparator並重寫的compareTo方法。
  • 兩個元素相等時,compareTo返回0;左大於右時,返回正整數(一般返回1);小於時返回負整數(一般返回-1)
  • 在TreeSet中,compareTo負責檢測元素重覆,所以要對compareTo的重寫留心。
import java.util.TreeSet;
class Student2 implements Comparable{
    String name;
    int age;
    Student2(String name,int age){
        this.name=name;
        this.age=age;
    }
    public int compareTo(Object o) {
         Student2 stu=(Student2)o;
        
        return this.name.equals(stu.name)?this.age-stu.age:this.name.compareTo(stu.name);
         //預設按姓名排序,如果有重覆的姓名,按年齡排序。認為同名同年齡為同一元素
    }
    @Override
    public String toString() {
        return "Student2 [name=" + name + ", age=" + age + "]";
    }


}
public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet t=new TreeSet();
//        t.add("a");
//        t.add("c");
//        t.add("d");
//        t.add("b");
//        System.out.println(t);//對於非自定義對象,可以排序[a, b, c, d]
        t.add(new Student2("lilei",18));
        t.add(new Student2("lilei",17));
        t.add(new Student2("hanmeimei",18));
        t.add(new Student2("john",17));
        t.add(new Student2("mike",27));
        t.add(new Student2("alice",21));
        System.out.println(t);
    }
}
  • 還支持創建集合時傳入一個比較器Comparator來進行排序,這時候重寫的是compare方法:
import java.util.Comparator;
import java.util.TreeSet;
class CompareByLength implements Comparator{

    public int compare(Object o1, Object o2) {
        
        Student3 stu1=(Student3)o1;
        Student3 stu2=(Student3)o2;
        return stu1.name.length()-stu2.name.length();
//        註意,這裡也與compareTo類似,定義的規則必須要考慮到重覆性,不然會導致屬性值相同的元素
//        認為是同一元素
    }
    
}

class Student3 {
    String name;
    int age;
    Student3(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String toString() {
        return "Student2 [name=" + name + ", age=" + age + "]";
    }
}
public class TreeSetDemo2 {
    public static void main(String[] args) {
        
        TreeSet t=new TreeSet(new CompareByLength());
        t.add(new Student3("aaa",18));
        t.add(new Student3("a",18));
//        t.add(new Student3("d",18));//這裡是元素重覆性的檢測,原因在compare
        t.add(new Student3("aa",17));
        t.add(new Student3("cccccccccc",17));
        System.out.println(t);
    }
}

 

 

 

 


Map:

 

介紹:

  • Map主要用於存儲帶有映射關係的數據(比如學號與學生信息的映射關係)
  • Map的存儲形式是鍵值對,一個鍵對應一個值。
  • 鍵是不可重覆的,值是可以重覆的。

 

常見方法:

  • 獲取:
    • keySet():獲取所有鍵,返回一個Set集合
    • get(x):返回指定鍵x所映射的值;如果此映射不包含該鍵的映射關係,則返回 null
    • size():返回鍵值對的數量。
    • values():獲取所有值,返回一個Set集合 。
    • entrySet():返回一個集合,集合中的對象都是包含鍵值對關係的entry類對象。
  • 設置:
    • put(key,value):將指定的值與此映射中的指定鍵關聯【已有則覆蓋舊值】
    • putAll(X):從指定映射X中將所有映射關係複製到此映射中。
  • 刪除:
    • clear():刪除所有鍵值對
    • remove(key):如果存在一個鍵key的映射關係,則將其從此映射中移除
  • 其他:
    • containsKey(x):檢測是否存儲指定鍵x
    • containsValue(x):檢測是否存儲指定值x
    • isEmpty():檢測是否為空,空則返回 true

 

 

重要實現類:

HashMap:

  • 哈希表結構的。
  • HashMap的方法基本都是Map中聲明的方法

 

TreeMap:

  • 二叉樹結構的。
  • 有序的,可以根據鍵值來排序,需要實現可以進行比較的方法(compareTo或compare)

 

 

Properties:

  • 一種經常用來存儲配置的集合,很適合存儲一些比如"backgroundColor=red"的數據。
  • 常用方法:
    • getProperty(String key):用指定的鍵在此屬性列表中搜索屬性。
    • load(InputStream inStream):從輸入流中讀取屬性列表(鍵和元素對)。
    • list(PrintStream out):將屬性列表輸出到指定的輸出流。

 

 

 

嵌套類:

Map.Entry<K,V>

  • Map.entrySet 方法配合,Map.entrySet返回的結果是一個集合,集合中的每一個元素都是這個類的對象。
  • 存在意義是返回結果包含了鍵和值,使得能夠同時操作鍵和值。
  • 此類對象的常用方法:
    • getKey():返回與此項對應的鍵。
    • getValue():返回與此項對應的值。
    • setValue(value):用指定的值替換與此項對應的值
public class MapDemo {
    public static void main(String[] args) {
        Map m=new HashMap();
        m.put("hanmeimei", "lilei");
        m.put("wodeta", "wo");
        m.put("apple", "google");
        Set s=m.entrySet();
        for(Iterator it=s.iterator();it.hasNext();) {
            Map.Entry me=(Entry) it.next();
            System.out.println(me.getKey()+"...."+me.getValue());
        }
    }
}

 

 


Collections工具類:

 

介紹:

  • Collections是jdk提供的一個專門用來操作集合的類
  • 此類完全由在 collection 上進行操作或返回 collection 的靜態方法組成。

 

常用方法:

  • 排序:
    • sort(L):根據元素的自然順序 對指定列表按升序進行排序。
    • sort(L,C):根據指定比較器C產生的順序對指定列表進行排序。

 

  • 查找:
    • max(L):根據元素的自然順序,返回給定 collection 的最大元素
    • max(L,C):根據指定比較器C產生的順序,返回給定 collection 的最大元素
    • min(L):根據元素的自然順序,返回給定 collection 的最小元素
    • min(L,C):根據指定比較器C產生的順序,返回給定 collection 的最小元素

 

  • 修改:
    • fill(L,x):使用指定元素替換指定列表中的所有元素。
    • swap(L,indexX,indexY):將指定集合中indexX與indexY的元素交換
    • reverse(L):反轉指定列表中元素的順序。
    • reverseOrder():返回一個比較器,它強行逆轉實現了 Comparable 介面的對象 collection 的自然順序
import java.util.ArrayList;
import java.util.Collections;
public class ListDemo2 {
    public static void main(String[] args) {
        ArrayList q=new ArrayList();
        q.add("a");
        q.add("z");
        q.add("b");
        q.add("c");
        System.out.println(Collections.max(q));
        System.out.println(q);
        Collections.sort(q);
        System.out.println(q);

    }
}

 

想瞭解更多,可以自行查看jdk文檔。

 



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 穿越:從0開始,構建前後端分離應用 攔截器的作用 攔截器是web項目不可或缺的組成部分,一般使用攔截器實現以下功能 1、登錄session驗證 防止瀏覽器端繞過登錄,直接進入到應用 或者session超時後,返回到登錄頁面 2、記錄系統日誌 一個完善的應用系統,應該具備監控功能,通過完善的系統日誌記 ...
  • #include<bits/stdc++.h>using namespace std;main(){double a=2.9939; cout<<fixed<<setprecision(2)<<a;printf("%.3f", a);return 0;} ...
  • JavaSE基礎點一 Java概述 什麼是Java? Java是一門程式設計語言,在說Java語言前先談一下什麼是電腦語言。電腦語言是人與電腦之間通信的語言,它主要由一些指令組成,這些指令包括數字、符號和語法等內容,人可以通過這些指令來指揮電腦進行各種工作。 電腦語言的分類有很多,大體分為 ...
  • 目標 使用 PHP 創建 COS 介面所需要的請求簽名,按照官方示例,請求簽名應用在需要身份校驗的場景,即非公有讀許可權時。否則在請求API介面時,就必須攜帶簽名作為請求頭的一部分傳遞。 步驟 準備好用戶信息 1. 將會使用到的用戶信息包括: SecretId:騰訊雲賬號內分配 SecretKey:騰 ...
  • Java開源生鮮電商平臺-賬單模塊的設計與架構(源碼可下載) 補充說明:Java開源生鮮電商平臺-賬單模塊的設計與架構,即用戶的賬單形成過程。 由於系統存在一個押賬功能的需求,(何為押賬,就是形成公司的資金池,類似摩拜單車,ofo單車等等)。目前B2B平臺也是採用押賬的這種功能策略。 這裡有個特別說 ...
  • 今天主要和大家分享的是本人總結的分頁執行方法,也可以說就是分批執行;該篇採用java8新增的表達式來操作,希望能給各位帶來好的幫助和在日常工作中提供便利;同樣的操作流程和邏輯之前用C#代碼寫過一次,有需要的朋友可以看以前的博文; 分頁方式拆分List為多個子集List方法 執行統一方法-無返回值,關 ...
  • Description 補足程式,使得下麵程式輸出的結果是: 100 ~~~~ include include using namespace std; // Your Code Here string Print1() { return " "; } int Print2() { return 1 ...
  • 所有人物的相似圖連接。 關係同上。展示形式為多中心結構 以張無忌的不同身份為中心的網路關係圖。 一、分析結果 實體的不同屬性(張無忌的總多馬甲) 張無忌,無忌,張教主,無忌哥哥,張公子。同一個張無忌有多個身份,不同身份又和不同的人聯繫,有不一樣的相似度。 先來看看圖: 無忌哥哥是過於親密的名字,一般 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...