1. 程式人生 > >Java 進階——集合體系詳解之Map體系鍵值對集合

Java 進階——集合體系詳解之Map體系鍵值對集合

引言

一Map體系的訪問方式

Map的訪問也和HashSet的特點一樣是無需的,Map體系與Set體系不同並不實現Iterator介面,當然也不會具有迭代器,那麼Map集合怎麼訪問呢?間接通過Set的迭代器,Map集合訪問方式主要有兩種:keySetentrySet

  1. keySet:將Map中所有的鍵存入到Set集合,再借助Set的迭代器Iterator取出所有的鍵,最後再根據get方法獲取到鍵對應的值。
Map<T,T> map=new HasMap<T,T>()
Set<T> set=map.keySet();//得到Set集合
Iterator<
T> it=set.iterator();//得到Set集合的迭代器 while(it.hasNext()){ String key=it.next();//通過迭代器獲取鍵 String value=map.get(key);//map根據鍵獲取對應的值 }
  1. entrySet:將Map集合的對映關係Map.Entry存入到Set集合中,對映關係的資料型別就是Map.Entry。
/*
Map.Entry:其實Entry是Map介面中的一個內部介面(因為能加static修飾符只能是成員變數,所以只能是成員介面),因為只能先有Map集合才有對映關係,而對映關係是直接處理成員資料的,所以設計為內部介面。
interface Map{
    public static interface Entry{
        public abstract Object getKey();
        ...
} } //巢狀介面的實現 class HashMaps implements Map{ class Maps implements Map.Entry{ public Object getKey(); ... } }*/ Set<Map.Entry<T,T>> entrySet=map.entrySet();//得到Set集合 Iterator<Map.Entry<T,T>> it=entrySet.iterator();//得到Set集合的迭代器 while(it.hasNext()){ Map.Entry<T
,T> m=it.next();//通過迭代器獲取對映關係 String key=m.getKey();//通過對映關係獲取key String value=map.getValue(key); }

二Map體系集合之HashTable(已基本被HasMap替代)

雜湊表HashTable實現了Map介面,該雜湊表將鍵對映到對應的值,該集合是執行緒同步的。任何非null物件都可以作為鍵Key或者值Value,換言之不允許存入null鍵null值。為了能成功在雜湊表中儲存和獲取物件,用作鍵的物件必須實現hashCodeequals方法。

三Map體系集合之HashMap

HashMap底層資料結構也是雜湊表,除了非同步和允許使用null鍵和null值、效率比較高以外,其他功能和HashTable類相同。
要儲存到Map集合的物件完成三步工作:實現Comparable<物件>、覆寫compareTohashCodeequals方法,至於原因嗎,因為雜湊體系。

class  Person implements Comparable<Person>{
    private String name;
    private int age;

    Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public int compareTo(Person s){
        int num=new Integer(this.age).compareTo(new Integer(s.age));
        if(num==0){
            return this.name.compareTo(s.name);
        }
        else{
            return num;
        }
    }
    //為了去除重複必須重新構造hashCOde
    public int hashCode()
    {
        return name.hasCode()+age*37;
    }

    //當雜湊值相同的時候才會執行
    public boolean equals(Object obj){
        if(!(obj instanceof Person)){
            throw new ClassCastException("型別不匹配");
        }
        Person p=(Person)obj;
        return this.name.equals(p.name) && this.age==p.age;
    }
    public String toString(){
        return "姓名:"+name+"年齡:"+age;
    }
}
//把Person物件儲存到HasMap中,以Person物件為鍵,對應的籍貫為值,姓名和年齡相同就認為是相同的人,需要保持唯一性
public static void main(String[] args){
    Map<Person,String> map=new HashMap<Person,String>();
    map.put(new Person("zhang3",18),"beijing");
    map.put(new Person("zhang4",19),"didu");
    map.put(new Person("zhang5",21),"modu");
    //map.put(new Person("zhang5",21),"將要替換掉modu");若已經儲存了(new Person("zhang5",21),"modu");再put(new Person("zhang5",21),"將要替換掉modu"),由於已經儲存了(new Person("zhang5",21))再put時會替換原來的值變成新的值
//第一種keySet方式遍歷
Set<Person> set=map.keySet();
Iterator<Person> it=set.iterator();//得到Set集合的迭代器
while(it.hasNext()){
    Person key=it.next();//通過迭代器獲取鍵
    String value=map.get(key);//map根據鍵獲取對應的值
    System.out.println(key.toString()+":"+value);
    }
//第二種方式entrySet
Set<Map.Entry<Person,String>> entrySet=map.entrySet();
Iterator<Map.Entry<Person,String>> iter=entrySet.iterator();//得到Set集合的迭代器
while(iter.hasNext()){
    Map.Entry<Person,String> pa=iter.next();//通過迭代器獲取鍵
    Person key=pa.getKey();//獲取鍵
    String value=pa.getValue();
    System.out.println(key.toString()+":"+value);
}
}

四Map體系集合之TreeMap

TreeMap是可以排序的Map集合,TreeMap底層資料結構是二叉樹,執行緒不同步,可以用於給Map中的鍵Key排序,可以通過compareTo方法來排序,也可以通過傳入比較器構造Map集合來覆蓋掉comareTo方法來實現排序

1例:把Person物件儲存到TreeMap,並按照姓名、年齡排序

class  Person implements Comparable<Person>{
    private String name;
    private int age;

    Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    //預設的是先根據年齡排序的,年齡相同再按照姓名排序
    public int compareTo(Person s){
        int num=new Integer(this.age).compareTo(new Integer(s.age));
        if(num==0){
            return this.name.compareTo(s.name);
        }
        else{
            return num;
        }
    }
    //為了去除重複必須重新構造hashCOde
    public int hashCode()
    {
        return name.hasCode()+age*37;
    }

    //當雜湊值相同的時候才會執行
    public boolean equals(Object obj){
        if(!(obj instanceof Person)){
            throw new ClassCastException("型別不匹配");
        }
        Person p=(Person)obj;
        return this.name.equals(p.name) && this.age==p.age;
    }
    public String toString(){
        return "姓名:"+name+"年齡:"+age;
    }
}

如果不更改Person物件的原始碼,就是按照預設的排序規則(先按照年齡再根據姓名),好在TreeMap

class PersonNameComparator implements Comparator<Person>{
    public int compare(Person s,Person s2){
        int re=s.getName().compareTo(s2.getName());
        if(re==0){
            return new Integer(s.getAge()).compareTo(new Integer(s2.getAge()));
        }
        return re;
    }
}

測試類

public static void main(String[] args){
    TreeMap<Person,String> tm=new TreeMap<Person,String>(new PersonNameComparator());
    tm.put(new Person("azhang3",18),"beijing");
    tm.put(new Person("dzhang4",19),"didu");
    tm.put(new Person("bzhang5",21),"modu");

    Set<Map.Entry<Person,String>> entrySet=map.entrySet();
    Iterator<Map.Entry<Person,String>> iter=entrySet.iterator();//得到Set集合的迭代器
    while(iter.hasNext()){
        Map.Entry<Person,String> pa=iter.next();//通過迭代器獲取鍵
        Person key=pa.getKey();//獲取鍵
        String value=pa.getValue();
        System.out.println(key.toString()+":"+value);
    }
}

2 獲取指定字串中的字母次數,如“asdfsafddwewdwss”,列印結果a(1)d(4)……

public String charCount(String str){
    chars[] chs=str.toCharArray();
    TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>();//錯誤的,泛型不允許使用基本型別必須使用引用型別TreeMap<char,int> tm=new TreeMap<char,int>();
    int count=0;
    for(int x=0;x<chs.length;x++){
        if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='Z')){
            continue;
        }
        Integer value=tm.get(chs[x]);
        if(value!=null){
            count=value;
        }
        count++;
        tm.put(chs[x],count);
        count=0;
    }
    StringBuilder sb=new StringBuilder();
    Set<Map.Entry<Character,Integer>> enteySet=tm.entrySet();
    Iterator<Map.Entry<Character,Integer>> it=enteySet.iterator();
    while(it.hasNext()){
        Map.Entry<Character,Integer> me=it.next();
        Character ch=me.getKey();
        Integer value=me.getValue();
        sb.append(ch+"("+value+")");
    }
    return sb.toString();
}

相關推薦

Java ——集合體系Map體系集合

引言 一Map體系的訪問方式 Map的訪問也和HashSet的特點一樣是無需的,Map體系與Set體系不同並不實現Iterator介面,當然也不會具有迭代器,那麼Map集合怎麼訪問呢?間接通過Set的迭代器,Map集合訪問方式主要有兩種:keySet和e

Java—— 集合體系List體系有序集合

引言 面嚮物件語言對事物的體現必然是以物件的形式,Java工程師為了方便多多個物件的操作,就對物件進行儲存,集合就是儲存物件的一種方式,他們的底層都是基於不同的資料結構。當然集合和陣列一樣都是容器,陣列也是可以儲存物件的,但是陣列長度一經初始化長度就是固定的,

Java ——多執行緒優化執行緒池 ThreadPoolExecutor的核心容器阻塞佇列(一)

#引言 多執行緒我想無論是後端開發,還是對於App開發者來說都不會陌生,何況Android強制要求不能在主執行緒中做網路請求,於是乎,在很多初學者或者App的原始碼中會出現會多的new Thread…的方式,這樣的程式碼是不優雅而且存在很多的隱患,假如說在使用者

Java集合框架繼承map介面

趁著最近比較閒,靜下心來準備把關於集合框架的東西好好整理一下,邊學邊整理。近階段先是整理整體的知識點,一些介面,一些繼承類以及它們的特性,用法,後續還會有一些常用的,比較重要的類的jdk原始碼剖析。 map介面: Map 提供 Key 到 Value

Linux:DNS

del 藍汛 網名 反垃圾郵件 區域傳送 author load man google DNS服務和BIND 本章內容 名字解析 DNS服務 實現主從服務器 實現子域 實現view 編譯安裝 壓力測試 DNS排錯 DNS服務 DNS:Domain Name Servi

集合map

Map介面集合類,具備的特點,儲存的資料結構都是以鍵值對的形式存在的,鍵不可重複,值可以重複。新增put() 如果之前沒有存在該鍵,那麼就返回的是null,如果之前就已經存在該鍵了,那麼就返回該鍵之前對應的值Putall() 把一個集合新增到另外一個集合中去刪除Remove(

【基礎】URL與URL編碼

// This function creates a new anchor element and uses location // properties (inherent) to get the desired URL data. Some String // operations are use

Java定時任務排程工具Timer篇(初級)

一.Timer簡介 定時任務的基本概念,Timer的函式,綜合運用和缺陷 基於給定的時間點,給定的時間間隔或者給定的執行次數自動執行的任務。 Timer 和Quartz Timer: 出身:由jdk提供,呼叫方式簡單粗暴; 能力:Timer能完成

python基礎-模塊

{0} 什麽 __init__ 過程 特殊 urn 三方 圖片 需要 在我們實際開發的過程中,每個項目都會或多或少的調用一些相同的代碼。如果每次都把代碼復制粘貼進項目的話,非常的繁瑣,且容易出錯,python模塊很好的為我們解決了這個問題。python的模塊是以 .py 結

Unity技巧 - RectTransform

前言 最近要做UI,有時候需要在程式碼中調整改變UI控制元件的屬性,比如位置、大小等,然而在NGUI裡面,控制UI控制元件的位置等屬性的是RectTransform這個元件,這個元件繼承自Transform元件,卻增加許多自己的特性,在不瞭解這些特性的情況下魯莽的去使用它,會導致出現很多匪夷所思的問題,而且

大型Java專題(四) 設計模式工廠模式

## 前言 ​ 今天開始我們專題的第三課了,開始對設計模式進行講解,本章節介紹:瞭解設計模式的由來,介紹設計模式能幫我們解決那些問題以及剖析工廠模式的歷史由來及應用場景。本章節參考資料書籍《Spring 5核心原理》中的第一篇 Spring 內功心法(Spring中常用的設計模式)(沒有電子檔,都是我取其精

JAVA架構師指南】二:JVM篇

## 前言   談到JAVA,就不得不提JVM---JAVA程式設計師繞不開的話題.也許有童鞋會說,我不懂JVM,但是我一樣可以寫出JAVA程式碼,我相信說這種話的童鞋,往往是隻有1-3年的初級開發人員,對JAVA理解還不深,不明白JVM的重要性,那接下來我們來說說,為什麼要學習JVM?   1.理解JV

大型Java專題(五) 設計模式單例模式與原型模式

## 前言 ​ 今天開始我們專題的第四課了,最近公司專案忙,沒時間寫,今天抽空繼續。上篇文章對工廠模式進行了詳細的講解,想必大家對設計模式合理運用的好處深有感觸。本章節將介紹:單例模式與原型模式。本章節參考資料書籍《Spring 5核心原理》中的第一篇 Spring 內功心法(Spring中常用的設計模式)

JAVA架構師指南】四:垃圾回收GC

前言   在【JAVA進階架構師指南】系列二和三中,我們瞭解了JVM的記憶體模型以及類載入機制,其中在記憶體模型中,我們說到,從執行緒角度來說,JVM分為執行緒私有的區域(虛擬機器棧/本地方法棧/程式計數器)和執行緒公有區域(方法區和java堆),其中執行緒私有區域記憶體隨著執行緒的結束而跟著被回收,GC主要

JAVA架構師指南】五:JVM效能調優

## 前言   首先給大家說聲對不起,最近屬實太忙了,白天上班,晚上加班,回家還要收拾家裡,基本每天做完所有事兒都是凌晨一兩點了,沒有精力再搞其他的了.   好了,進入正題,讓我們來聊聊JVM篇最後一個章節----JVM效能調優.童鞋們隨便開啟一個大廠的招聘崗位JD,應該都會有JVM調優相關的描述,其實招

大型Java專題(七) 設計模式委派模式與策略模式

## 前言 ​ 今天開始我們專題的第七課了。本章節將介紹:你寫的程式碼中是否覺得很臃腫,程式中有大量的if...else,想優化程式碼,精簡程式邏輯,提升程式碼的可讀性,這章節將介紹如何通過委派模式、策略模式讓你程式碼更優雅,消除程式大量冗餘的程式碼。本章節參考資料書籍《Spring 5核心原理》中的第一篇

大型Java專題(八) 設計模式介面卡模式、裝飾者模式、觀察者模式

## 前言 ​ 今天開始我們專題的第八課了。本章節將介紹:三個設計模式,介面卡模式、裝飾者模式和觀察者模式。通過學習介面卡模式,可以優雅的解決程式碼功能的相容問題。另外有重構需求的人群一定需要掌握裝飾者模式。本章節參考資料書籍《Spring 5核心原理》中的第一篇 Spring 內功心法(Spring中常用

大型Java專題(九) 設計模式總結

## 前言 ​ 關於設計模式的文章就到這裡了,學習這門多設計模式,你是不是有這樣的疑惑,發現很多設計模式很類似,經常會混淆某些設計模式。這章節我們將對設計模式做一個總結,看看各類設計模式有什麼區別。需要注意的是,設計模式在於理解,不在於形式。不要為了套用設計模式而使用設計模式,而是,在業務上遇到問題時,很自

QT五子棋專案四:AI人機戰max-min極大極小博弈演算法

不考慮博弈的演算法怎麼能算是AI呢?max-min極大極小值演算法就是考慮了博弈的演算法。來看一個簡單的例子在這個棋局中,電腦為白旗,白旗走哪一步更好呢,也許使用策略表會告訴你,應該衝4,但是衝4後,玩家就會連成4。這就是考慮了博弈之後,這一步棋就是敗局。這就是為什麼有max

Hashtable 集合

var ole ons nta nbsp console lin write reac // Hashtable 鍵值對集合 一個鍵對應一個值 Hashtable ht=new Hashtable();