總網頁瀏覽量

2012年5月22日 星期二

JAVA 集合(4) Map


Map集合
該集合存儲鍵值對,而且要保證鍵的唯一性
l   增加
n   put(K key, V value)
n   putAll(Map<? extneds K, ?extends V> m)
l   刪除
n   clear()
n   remove(Object key)
l   判斷
n   containsKey(Object key)
n   containsVaule(Object value)
n   isEmpty()
l   獲取
n   value get(Object key)
n   size()
n   values()
n   entrySet()
n   keySet()

Map子類
l   Hashtable: 底層是雜湊表數據結構,不可存入nullnull值,該集合是線程同步
l   HashMap: 底層是雜湊表數據結構,允許存入nullnull值,該集合是不同步
l   TreeMap: 底層是二元樹數據結構,線程不同步,可以用於map集合中的鍵進行排序

MapSet很像,Set底層就是使用Map集合


基本方法 HashMap
public class Main{
    public static void main(String[] args){
        Map<String, String> map = new HashMap<String, String>();
        //加入元素,加入時如果出現相同的鍵,則新的値會覆蓋原有的鍵對應值,並put方法會返回被覆蓋的値
        map.put("01""a");
        map.put("02""b");
        map.put("03""c");
        System.out.println("containKey: " + map.containsKey("02"));//true
        System.out.println("remove: " + map.remove("03"));//c
        System.out.println(map);//{01=a, 02=b}
        //可以通過get方法的返回值來判斷一個鏈是否存在,通過返回null來判斷
        System.out.println("get: " + map.get("01"));//get: a
        map.put("04"null);
       
        //獲取集合中所有的値
        Collection<String> col = map.values();
        System.out.println(col);// [null, a, b]
    }
}

map集合的兩種取出方式
l   Set<k> keySet(): map中所有的鍵存入到Set集合,因為set具備迭代器,可以用迭代方式取出所有的鍵,在根據get方法,獲取每一個鍵對應的値
l   entrySet(): Set<Map.Entry<k, v>> entrySet map集合中的映射關係存入到了set集合中,而這個關係的數據類型就是Map.Entry

Map集合的取出原理,將map集合轉成set集合,在通過迭代器取出

使用keySet()
public class Main{
    public static void main(String[] args){
        Map<String, String> map = new HashMap<String, String>();
        map.put("01""a");
        map.put("02""b");
        map.put("03""c");
        //獲取map集合中的所有鍵的Set集合, keySet()
        Set<String> keySet = map.keySet();
        //有了set集合就可以獲取迭代器
        Iterator<String> it = keySet.iterator();
        while(it.hasNext()){
            String key = it.next();
            //有了鍵就可以通過map集合的get方法獲取其對應的値
            String value = map.get(key);
            System.out.println("key: " + key + ", vaule: " + value);
        }//key: 01, vaule: a  //key: 02, vaule: b  //key: 03, vaule: c
    }
}

使用entrySet()
public class Main{
    public static void main(String[] args){
        Map<String, String> map = new HashMap<String, String>();
        map.put("01""a");
        map.put("02""b");
        map.put("03""c");
        //map集合中的映射關係取出,存入到Set集合中
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
       
        Iterator<Map.Entry<String, String>> it = entrySet.iterator();
        while(it.hasNext()){
            Map.Entry<String, String> me = it.next();
            String key = me.getKey();//
            String value = me.getValue();
            System.out.println("key: " + key + ", vaule: " + value);
        }
    }
}

Map.Entry: 其實Entry也是一個介面,他是Map介面中的一個內部介面
ex:
interface Map{
        public static interface Entry{
        public abstract Object getKey();
        public abstract Object getValue();
}
}

class HashMap implements Map{
        class Hash implements Map.Entry{
                public Object getKey();
                public Object getValue();
}
}

Ex:
class Student implements Comparable<Student>{
    private String name;
    private int age;
   
    public int compareTo(Student s){
        int num = new Integer(this.age).compareTo(new Integer(s.age));
        if(num == 0)
            return this.name.compareTo(s.name);
        return num;
    }
        //hasCode()與equals()方法用來排除相同元素的重覆   
    public int hashCode(){
        return name.hashCode() + age*34;
    }
   
    public boolean equals(Object obj){
        if(!(obj instanceof Student))
            throw new ClassCastException("不屬於Student");
        Student s = (Student)obj;
        return this.name.equals(s.name) && this.age == s.age;
    }
   
    Student(String name, int age){
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public String toString(){
        return name + ": " + age;
    }
}

public class Main{
    public static void main(String[] args){
        HashMap<Student, String> hm = new HashMap<Student, String>();
        hm.put(new Student("B", 21), "TW");
        hm.put(new Student("A", 18), "HK");
        hm.put(new Student("D", 25), "US");
        hm.put(new Student("C", 30), "JP");
       
        //第一種取出方式 keySet
        Set<Student> keySet = hm.keySet();
        Iterator<Student> it = keySet.iterator();
        while(it.hasNext()){
            Student stu = it.next();
            String addr = hm.get(stu);
            System.out.println(stu + "... " + addr);
        }
        //第二種取出方式 entrySet
        Set<Map.Entry<Student, String>> entrySet = hm.entrySet();
        Iterator<Map.Entry<Student, String>> iter = entrySet.iterator();
        while(iter.hasNext()){
            Map.Entry<Student, String> me = iter.next();
            Student stu = me.getKey();
            String addr = me.getValue();
            System.out.println(stu + "... " + addr);
        }
    }
}



排序
class Student implements Comparable<Student>{
    private String name;
    private int age;
   
    public int compareTo(Student s){
        int num = new Integer(this.age).compareTo(new Integer(s.age));
        if(num == 0)
            return this.name.compareTo(s.name);
        return num;
    }
   
    public int hashCode(){
        return name.hashCode() + age*34;
    }
   
    public boolean equals(Object obj){
        if(!(obj instanceof Student))
            throw new ClassCastException("不屬於Student");
        Student s = (Student)obj;
        return this.name.equals(s.name) && this.age == s.age;
    }
   
    Student(String name, int age){
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public String toString(){
        return name + ": " + age;
    }
}

public class Main{
    public static void main(String[] args){
        TreeMap<Student, String> tm = new TreeMap<Student, String>(new StuNameComparator());
        tm.put(new Student("B", 21), "TW");
        tm.put(new Student("A", 18), "HK");
        tm.put(new Student("D", 25), "US");
        tm.put(new Student("C", 30), "JP");
       

        Set<Map.Entry<Student, String>> entrySet = tm.entrySet();
        Iterator<Map.Entry<Student, String>> it = entrySet.iterator();
        while(it.hasNext()){
            Map.Entry<Student, String> me = it.next();
            Student stu = me.getKey();
            String addr = me.getValue();
            System.out.println(stu + "... " + addr);
        }
    }
}
//自定義比較器 依姓名排序 在依年齡排序
class StuNameComparator implements Comparator<Student>{
    public int compare(Student s1, Student s2){
        int num = s1.getName().compareTo(s2.getName());
        if(num == 0)
            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        return num;
    }
}

獲取字串中的字母出現的次數,產生結果如: a(1), b()3, …
表示每一個字母都有對應的關係,可以選擇map集合,利用其映射關係
當數據之間存在映射關係時,就要先想到map集合

/**
 * 1. 將字串轉成字元陣列
 * 2. 定義map集合,因為結果的字母有順序
 * 3. 將每一個字母作為鍵去查map集合,如果返回null,將該字母和1存入到map集合中
 *    如果返回不是null,說明該字母在map集合已經存在並有對應次數,更新資料
 * 4. map集合中的數據變成指定的字串形式傳回   
 *
 * */
public class Main{
    public static void main(String[] args){
        String result = charCount("aiejoeifcea");
        System.out.println(result);
    }
    public static String charCount(String str){
        char[] chs = str.toCharArray();
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
       
        for(int x = 0; x < chs.length ; x++){
            Integer value = tm.get(chs[x]);
            if(value == null){
                tm.put(chs[x], 1);
            }else{
                value = value + 1;
                tm.put(chs[x], value);
            }
        }
        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<Character, Integer>>entrySet = tm.entrySet();
        Iterator<Map.Entry<Character, Integer>> it = entrySet.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();
    }
}

map集合被使用是因為具備映射關係,
public class Main{
    public static void main(String[] args){
        HashMap<String, String> a = new HashMap<String, String>();
        a.put("11""x1");
        a.put("12""x2");
       
        HashMap<String, String> b = new HashMap<String, String>();
        b.put("21""y1");
        b.put("22""y2");
         
        HashMap<String, HashMap<String, String>> c = new HashMap<String, HashMap<String, String>>();
        c.put("01", a);
        c.put("02", b);
    }
}


Collections
public class Main{
    public static void main(String[] args){
        sortDemo();
    }
    public static void sortDemo(){
        List<String> list = new ArrayList<String>();
        list.add("asc");
        list.add("vdko");
        list.add("aqsqs");
        list.add("zaxce");
        list.add("plldw");
       
        sop(list); //[asc, vdko, aqsqs, zaxce, plldw]
        //Collections.sort(list);
        Collections.sort(list, new StrLenComparator());
        sop(list); //[asc, vdko, aqsqs, plldw, zaxce]
        sop(Collections.max(list)); // zaxce
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

class StrLenComparator implements Comparator<String>{
    public int compare(String s1, String s2){
        if(s1.length() > s2.length()){
            return 1;
        }
        if(s1.length() < s2.length()){
            return -1;
        }
        return s1.compareTo(s2);
    }
}



public class Main{
    public static void main(String[] args){
        sortDemo();
    }
    public static void sortDemo(){
        List<String> list = new ArrayList<String>();
        list.add("c");
        list.add("b");
        list.add("a"); 
       
        Collections.sort(list);
        sop(list);//要先排序 [a, b, c] 否則結果會錯誤
        sop(Collections.binarySearch(list, "b"));//1
        sop(Collections.binarySearch(list, "c"));//2
        sop(Collections.binarySearch(list, "a"));//0

    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}
class StrLenComparator implements Comparator<String>{
    public int compare(String s1, String s2){
        if(s1.length() > s2.length()){
            return 1;
        }
        if(s1.length() < s2.length()){
            return -1;
        }
        return s1.compareTo(s2);
    }
}


class Hello{
    public static void main(String[] args){
        sortDemo();
    }
    public static void sortDemo(){
        List<String> list = new ArrayList<String>();
        list.add("c");
        list.add("b");
        list.add("a"); 
       
        Collections.reverse(list);
        sop(list);//[a, b, c]
        //fill方法可以將list集合中所有元素替換成指定元素
        Collections.fill(list, "123");
        sop(list);//[123, 123, 123]
        Collections.replaceAll(list, "123""a");
        sop(list);//[a, a, a]
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

Collections.reverseOrder
class Hello{
    public static void main(String[] args){
        Demo();
    }
    public static void Demo(){
        TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder());
        ts.add("a");
        ts.add("b");
        ts.add("c");
        ts.add("d");
        Iterator it = ts.iterator();
        while(it.hasNext()){
            sop(it.next());
        }
    }
    public static void sop(Object obj){
        System.out.println(obj); //d, c, b, a
    }
}

直接使得Collections.reverseOrder將實作的比較類傳入,可直接反轉自定義的排序內容
原本是由字串長度由小到大,反轉後變由大到小
class Hello{
    public static void main(String[] args){
        Demo();
    }
    public static void Demo(){
        TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new StrLenComparator()));
        ts.add("aaaa");
        ts.add("bb");
        ts.add("c");
        ts.add("dddddd");
       
        Iterator it = ts.iterator();
        while(it.hasNext()){
            sop(it.next());
        }
    }
    public static void sop(Object obj){
        System.out.println(obj); //d, c, b, a
    }
}

class StrLenComparator implements Comparator<String>{
    public int compare(String s1, String s2){
        if(s1.length() > s2.length())
            return 1;
        if(s1.length() < s2.length())
            return -1;
        return s1.compareTo(s2);
    }
}

Collections其他方法:
非同步方法轉為同步方法:   static <T>List<T> synchronizedList(List<T> list)
隨機排列方法:   static void shuffle(List<?> list)

Arrays用於操作陣列的工具類,其方法為靜態
ArraysList
class Hello{
    public static void main(String[] args){
        int[] arr = {1, 2, 3};
        sop(Arrays.toString(arr));
       
        //asList將陣列轉為list集合
        //好處為可以使用集合的方法來操作陣列中的元素
        //注意將陣列轉為集合後不可以使用集合的增刪方法
        //因為陣列的長度是固定誤用會發生異常
        String[] arrStr = {"a""b""c"};
        List<String> list = Arrays.asList(arrStr);
        sop(list);
       
        int[] nums = {2, 4, 5};
        List<int[]> list2 = Arrays.asList(nums);
        sop(list2);//[[I@af993e]
        //如果陣列中的元素為物件那轉為集合後陣列中元素可直接轉為集合中的元素
        //如果陣列中的元素為基本數據類型那會將該陣列作為集合中的元素存在
        Integer[] nums2 = {1, 2, 3};
        List<Integer> list3 = Arrays.asList(nums2);
        sop(list3);//[1, 2, 3]
       
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

集合轉陣列
class Hello{
    public static void main(String[] args){
        ArrayList<String> al = new ArrayList<String>();
        al.add("a");
        al.add("b");
        al.add("c");
       
        /**
         * 1. 指定類型陣列所需定義的長度?
         * 2. 若定義小於集合的size 則該方法內部會創建一個新的陣列 長度為集合size
         * 3. 若定義大於集合的size 則不會創建新陣列 而是使用傳遞過來的陣列
         * 利用al.size()最正確*/
       
        /**
         * 集合轉陣列原因
         * 為了限定元素的操作 限定增刪操做*/
        String[] arr = al.toArray(new String[0]);
        sop(Arrays.toString(arr));
       
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

foreach
for(數據類型 變量名被遍歷集合或陣列)
對集合進行遍歷
只能獲取集合元素,但是不能對集合進行操作

迭代器除了遍歷,還可以進行remove集合中元素的動作
如果用ListIterator,還可以在遍歷過程中對集合進行增刪改查的動作
class Hello{
    public static void main(String[] args){
        ArrayList<String> al = new ArrayList<String>();
        al.add("a");
        al.add("b");
        al.add("c");
       
        for(String s: al){
            //s只能取出 不能修改
            sop(s);
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

JDK1.5版本出現的新特性 可變參數
隱式將這些參數封裝成陣列,一定要定義在參數的最後面
class Hello{
    public static void main(String[] args){
        show(2, 3, 4);
    }
    public static void show(int ...arr){
        System.out.println(arr.length);
    }
}

StaticImport 靜態導入
import java.util.ArrayList;
//靜態導入導入的是Arrays這個類中所有靜態成員
import static java.util.Arrays.*;
import static java.lang.System.*;

class Hello{
    public static void main(String[] args){
        int[] arr = {3, 1, 5};
        sort(arr);
        //當類名重名時,需指定具體的包名
        //當方法重名時,指定具備所屬的物件或類
        out.println(Arrays.toString(arr));
    }
}

沒有留言:

張貼留言