Java集合框架 Map和泛型
Map集合
1.特點:該集合存儲鍵值對。一對一對往里存。而且要保證鍵的唯一性。
2.常用方法:
1.添加:v put(k key , v value); 將數據以鍵值對的方式存進集合中。
void putAll(Map<? extends k,? extends v> m) ;從指定映射中將所有映射關系復制到此映射中
2.刪除:void clear(); 清空集合
v remove(Object key); 將集合中的元素以鍵的形式移除。
3.判斷:containsKey(Object key) 判斷集合中是否有key。如果有,則返回true。
contaninValue(Object value) 判斷集合中是否有value
4.查詢:get(Object key);
size();
values();
entrySet();
keySet();
Map有三個常見子類:
|---Hashtable:此類實現一個哈希表,該哈希表將映射到相應的值。任何非null對象都可以用作鍵或值。該集合是線程同步的。 Jdk1.0 效率低
|--HashMap:底層是哈希表數據結構,允許使用null值和null鍵,該集合是不同步的。 Jdk1.2 效率高
|--TreeMap:底層是二叉樹數據結構。線程不同步。可以用于給map集合中的鍵進行排序。
和Set很像。
其實Set底層就是使用了Map集合。
注:如果添加相同的鍵,那么后添加的值會覆蓋原來鍵對應值。
map集合的兩種取出方式:
1.keySet:將map中所有的鍵存入到Set集合。因為set具備迭代器。所以可以用迭代的方式取出所有的鍵,在根據get方法。獲取每一個鍵對應的值。
Map集合的取出原理:將map集合轉成set集合。再通過迭代器取出。
2.Set<Map.Entry<k,v>> entrySet:將map集合中德映射關系存入到了set集合中,而這個關系的數據類型就是:map.entry.
Map.Entry 其實Entry也是一個接口,它是Map接口中的一個內部接口。
為何要定義在其內部呢?
原因:
a.Map集合中存的是映射關系這樣的兩個數據,是先有Map這個集合,才可有映射關系的存在,而且此類關系是集合的內部事務。
b.并且這個映射關系可以直接訪問Map集合中的內部成員,所以定義在內部。
package Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import java.util.Map.Entry; public class HashMapDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub entrySetMethod(); } //利用keySet這個方法取出map集合中的值。 public static void keySetMethod(){ //創建一個HashMap集合,并添加了泛型。鍵值都是String類型的。 HashMap<String,String> hm = new HashMap<String,String>(); hm.put("01","zhangsan01"); hm.put("02","zhangsan02"); hm.put("03","zhangsan03"); hm.put("04","zhangsan04"); Set<String> keyset = hm.keySet(); for(Iterator<String> it =keyset.iterator();it.hasNext();){ String key =it.next(); String value = hm.get(key); System.out.println("key: "+key+" "+"value:"+value); } } public static void entrySetMethod(){ HashMap<String,String> hm = new HashMap<String,String>(); hm.put("01","zhangsan01"); hm.put("02","zhangsan02"); hm.put("03","zhangsan03"); hm.put("04","zhangsan04"); Set<Entry<String, String>> entry=hm.entrySet(); for(Iterator<Entry<String, String>> it =entry.iterator();it.hasNext();){ Entry<String, String> en = it.next(); System.out.println(en.getKey()+" "+en.getValue()); } } } |
Map練習
1.描述學生。
2.定義map容器。將學生作為鍵,地址作為值。存入。
3.獲取map集合中的元素。
package Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class MapTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub entrySet(); } //第一種取出方式keySet(); public static void keySet(){ HashMap<Students,String> hm = new HashMap<Students,String>(); hm.put(new Students("lisi1",21), "beijing"); hm.put(new Students("lisi1",21), "tianjing"); hm.put(new Students("lisi4",33), "nanjing"); hm.put(new Students("lisi8",44), "ganzhou"); hm.put(new Students("lisi5",80), "hengyang"); Set<Students> keyset =hm.keySet(); for(Iterator<Students> it = keyset.iterator();it.hasNext();){ Students key =it.next(); String addrv =hm.get(key); System.out.println(key+":::"+addrv); } } public static void entrySet(){ HashMap<Students,String> hm = new HashMap<Students,String>(); hm.put(new Students("lisi1",21), "beijing"); hm.put(new Students("lisi1",21), "tianjing"); hm.put(new Students("lisi4",33), "nanjing"); hm.put(new Students("lisi8",44), "ganzhou"); hm.put(new Students("lisi5",80), "hengyang"); Set<Map.Entry<Students, String>> entryset = hm.entrySet(); for(Iterator<Map.Entry<Students, String>> it =entryset.iterator();it.hasNext();){ Map.Entry<Students, String> entry = it.next(); Students s = entry.getKey(); String addr = entry.getValue(); System.out.println(s+":::"+addr); } } } |
泛型
泛型概述
在Java SE 1.5之前,沒有泛型的情況的下,通過對類型Object的引用來實現參數的“任意化”,“任意化”帶來的缺點是要做顯式的強制類型轉換,而這種轉換是要求開發者對類型可以預知的情況下進行的。對于強制類型轉換錯誤的情況,編譯器可能不提示錯誤,在運行的時候才出現異常,這是一個安全隱患。
類的后面跟著<E>這樣的標識,如ArrayList<E>,這個<E>就代表泛型,E就是泛型類型,表示ArrayList集合里面只能存儲E類型的元素。
其本質就是實現參數化類型,也就是說所操作的數據類型被指定為一種類型。
好處:
1、將運行時期出現的問題ClassCastException轉移到了編譯時期,方便程序員解決,讓運行時期問題減少。
2、避免了強制轉換麻煩。
示例
import java.util.*; class GenericDemo{ public static void main(String[] args){ //定義了一個String類型的數組列表 ArrayList<String> al = new ArrayList<String>(); al.add("abc002"); al.add("abc013"); al.add("abc256"); al.add("abc028"); //al.add(4);//al.add(new Integer(5)); //迭代器要使用泛型 Iterator<String> it = al.iterator(); while(it.hasNext()){ String s = it.next(); System.out.println(s); } } } /* 結果 abc002 abc013 abc256 abc028 */ |
泛型使用
泛型格式:通過<>來定義要操作的引用數據類型。
在使用java提供的對象時,什么時候使用泛型呢?
通常在集合框架中創建,只要見到<>就要定義泛型。
其實<>就是用來接收類型的,當使用集合時,
將集合中要存儲的數據類型作為參數傳遞到<>中即可。
示例
import java.util.*; class TreeSetTest{ public static void main(String[] args){ TreeSet<String> ts = new TreeSet<String>(new LenComparator()); ts.add("abcd"); ts.add("cc"); ts.add("cba"); ts.add("z"); ts.add("a"); ts.add("sdcvrt"); Iterator<String> it = ts.iterator(); while(it.hasNext()){ String s = it.next(); System.out.println(s); } } } //自定義比較器,實現Comparator接口并使用泛型 class LenComparator implements Comparator<String> { public int compare(String s1,String s2){ /* //升序 int num = new Integer(s1.length()).compareTo(new Integer(s2.length())); if(num==0) return s1.compareTo(s2); return num; */ //降序 int num = new Integer(s2.length()).compareTo(new Integer(s1.length())); if(num==0) return s2.compareTo(s1); return num; } } /* 結果 sdcvrt abcd cba cc z a */ |
泛型類
什么時候定義泛型類?
當類中要操作的引用數據類型不確定的時候,
早期定義Object來完成擴展。
現在定義泛型來擴展。
class Worker{} class Student{} //泛型以前的做法 class Tool{ private Object obj; public void setObject(Object obj){ this.obj = obj; } public Object getObject(){ return obj; } } //泛型類 class Utils<QQ>{ private QQ q; public void setObject(QQ q){ this.q = q; } public QQ getObject(){ return q; } } class GenericDemo{ public static void main(String[] args){ Utils<Worker> u = new Utils<Worker>(); u.setObject(new Worker()); Worker w = u.getObject(); /* Tool t = new Tool(); t.setObject(new Worker()); Worker w = (Worker)t.getObject(); */ } } |
泛型方法
為了讓不同方法可以操作不同類型,而且類型還不確定,那么可以將
泛型定義在方法上。
class Demo{ //類型定義在方法上 public <T> void show(T t){ System.out.println("show:"+t); } public <Q> void print(Q q){ System.out.println("print:"+q); } } class GenericDemo{ public static void main(String[] args){ Demo d = new Demo(); d.show(5); d.show(new Integer(5)); d.show("haha"); d.print(8); d.print(new Integer(5)); d.print("heihei"); } } /* 結果 show:5 show:5 show:haha print:8 print:5 print:heihei */ |