|--HashMap:底層是哈希表數據結構。允許使用null鍵null值,該集合是不同步的。JDK1.2,效率高。
|--TreeMap:底層是二叉樹數據結構。線程不同步。可以用於給Map集合中的鍵進行排序。
voidputAll(Map <? extends K,? extends V> m);//添加一個集合
b、刪除
clear();//清空
remove(Object key);//刪除指定鍵值對
c、判斷
containsKey(Objectkey);//判斷鍵是否存在
containsValue(Objectvalue)//判斷值是否存在
isEmpty();//判斷是否爲空
d、獲取
get(Object key);//通過鍵獲取對應的值
size();//獲取集合的長度
values();//獲取Map集合中所有的值,返回一個Collection集合
還有兩個取出方法,接下來會逐個講解:
Set<Map.Entry<K,V>>entrySet();
Set<K> keySet();
代碼示例:
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class MapDemo
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
//put方法添加元素時,如果添加相同的鍵,那麼後添加的值會覆蓋原有鍵對應的值,並且會返回被覆蓋的值。
System.out.println("put:"+map.put("01","wangwu"));
System.out.println("put:"+map.put("01","zhangsan1"));
map.put("02","zhangsan2");
map.put("03","zhangsan3");
System.out.println("containsKey:"+map.containsKey("02"));
System.out.println("remove:"+map.remove("07"));
map.put("08",null);
System.out.println("get:"+map.get("02"));
//可以通過get方法的返回值來判斷一個鍵是否存在。通過返回null來判斷。
//獲取map集合中所有的值
Collection<String> coll = map.values();
System.out.println(coll);
System.out.println(map);
}
}</span>
1、Set<k> keySet():將Map中所有的鍵存入到Set集合。因爲Set具備迭代器。所以可以通過迭代方式取出所有的鍵,再通過get方法。獲取每一個鍵對應的值。
2、Set<Map.Entry<k,v>> entrySet():將Map集合中的映射關係存入到Set集合中,而這個關係的數據類型就是:Map.Entry
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class MapDemo1
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
map.put("01","zhangsan1");
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("04","zhangsan4");
//先取出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("keySet:key="+key+",value="+value);
}
//將Map集合中的映射關係取出,存入到Set集合中。
Set<Map.Entry<String,String>> entryset = map.entrySet();
Iterator<Map.Entry<String,String>> it1 = entryset.iterator();
while(it1.hasNext())
{
Map.Entry<String,String> me = it1.next();
//有了鍵就可以通過Map集合的get方法獲取其對應的值。
String key = me.getKey();
String value = me.getValue();
System.out.println("entrySet:key="+key+",value="+value);
}
}
}</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
/*
每一個學生都有對應的歸屬地。
學生Student,地址String。
學生屬性:姓名,年齡。
注意:姓名和年齡相同的視爲同一個學生。
保證學生的唯一性。
思路:1、描述學生類
2、定義一個Map集合,存儲學生對象和地址值
3、獲取Map中的元素
*/
class Student implements Comparable<Student>
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Student s)
{
int num = this.name.compareTo(s.name);
if(num==0)
return new Integer(this.age).compareTo(new Integer(s.age));
return num;
}
public int hashCode()//重寫hashcode
{
return name.hashCode()+age*39;
}
public boolean equals(Object obj)//重寫equals
{
if(!(obj instanceof Student))
throw new ClassCastException("類型不匹配");
Student s = (Student)obj;
return this.name.equals(s.name) && this.age == s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name+":"+age;
}
}
class StuAgeComparator implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
int num = new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
if(num==0)
return s1.getName().compareTo(s2.getName());
return num;
}
}
class MapTest
{
public static void main(String[] args)
{
//HashMap
HashMap<Student,String> hm = new HashMap<Student,String>();
hm.put(new Student("lasi1",21),"beijing");
hm.put(new Student("lasi2",22),"shanghai");
hm.put(new Student("lasi3",23),"nanjing");
hm.put(new Student("lasi4",24),"wuhan");
hm.put(new Student("lasi4",24),"tianjin");
//第一種取出方式 keySet
Set<Student> keyset = hm.keySet();
Iterator<Student> it = keyset.iterator();
while(it.hasNext())
{
Student stu = it.next();
String add = hm.get(stu);
System.out.println("HashMap第一種取出方式keySet:"+stu.toString()+"--"+add);
}
System.out.println("------------------------------------");
//第二種取出方式 entrySet
Set<Map.Entry<Student,String>> entryset = hm.entrySet();
Iterator<Map.Entry<Student,String>> it1 = entryset.iterator();
while(it1.hasNext())
{
Map.Entry<Student,String> me = it1.next();
Student stu = me.getKey();
String add = me.getValue();
System.out.println("HashMap第二種取出方式 entrySet:"+stu.toString()+"::"+add);
}
System.out.println("------------------------------------");
//TreeMap
TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuAgeComparator());
tm.put(new Student("blisi1",21),"beijing");
tm.put(new Student("alisi2",22),"shanghai");
tm.put(new Student("dlisi3",23),"nanjing");
tm.put(new Student("clisi4",24),"wuhan");
tm.put(new Student("clisi4",24),"tianjin");
//第二種取出方式 entrySet
Set<Map.Entry<Student,String>> entryset1 = tm.entrySet();
Iterator<Map.Entry<Student,String>> it2 = entryset1.iterator();
while(it2.hasNext())
{
Map.Entry<Student,String> me = it2.next();
Student stu = me.getKey();
String add = me.getValue();
System.out.println("TreeMap比較器 按年齡排序:"+stu.toString()+"..."+add);
}
System.out.println("------------------------------------");
TreeMap<Student,String> tm1 = new TreeMap<Student,String>();
tm1.put(new Student("blisi1",21),"beijing");
tm1.put(new Student("alisi2",22),"shanghai");
tm1.put(new Student("dlisi3",23),"nanjing");
tm1.put(new Student("clisi4",24),"wuhan");
tm1.put(new Student("clisi4",24),"tianjin");
//第二種取出方式 entrySet
Set<Map.Entry<Student,String>> entryset2 = tm1.entrySet();
Iterator<Map.Entry<Student,String>> it3 = entryset2.iterator();
while(it3.hasNext())
{
Map.Entry<Student,String> me = it3.next();
Student stu = me.getKey();
String add = me.getValue();
System.out.println("TreeMap元素自身比較性 按姓名排序:"+stu.toString()+"..."+add);
}
}
}</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">/*
"fajkgvzvbzjhfaf"獲取該字符串中的字母出現的次數,
希望打印的結果是:a(1)c(2).....
通過結果發現,每個字母都有對應的次數,說明字母和次數之間有映射關係
何時使用Map集合:當量數據之間存在着映射關係的時候,就應該想到使用Map集合。
思路:1、將字符串轉換爲字符數組 ,因爲要對每一個字母進行操作。
2、定義一個Map集合,因爲打印結果的字母有順序,所以使用TreeMap集合。
3、遍歷字符數組。
將每一個字母作爲鍵去查Map集合。
如果返回null,將該字母和1存入到Map集合中。
如果返回不是null,說明該字母在Map集合已經存在並有對應次數。
那麼就獲取該次數並進行自增。然後將該字母和自增後的次數存入到Map集合中,覆蓋掉原來鍵所對應的值。
用數組去遍歷集合,如果集合中有該字母則次數加1,如果集合中沒有則存入
4、將Map集合中的數據變成指定的字符串形式返回。
*/
import java.util.*;
class MapTest1
{
public static void main(String[] args)
{
charCount("fajkgvzvbzjhfaf");
}
public static String charCount(String s)
{
char[] ch = s.toCharArray();
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
for (int x=0; x<ch.length; x++)
{
Integer value = tm.get(ch[x]);
if (value==null)
tm.put(ch[x],1);
else
{
value = value+1;
tm.put(ch[x],value);
}
}
Set<Character> keyset = tm.keySet();
Iterator<Character> it = keyset.iterator();
while(it.hasNext())
{
Character c = it.next();
Integer i = tm.get(c);
System.out.print(c.toString()+"("+i+")");
}
return null;
}
}</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
/*
Map擴展知識:Map集合被使用是因爲具備映射關係。
"yureban" "01" "zhangsan"
"yureban" "02" "lisi"
"jiuyeban" "01" "wangwu"
"jiuyeban" "02" "zhaoliu"
*/
class Student
{
private String num;
private String name;
Student(String num,String name)
{
this.num = num;
this.name = name;
}
public String toString()
{
return num+"...."name;
}
}
class MapTest2
{
public static void main(String[] args)
{
HashMap<String,String> yure = new HashMap<String,String>();
yure.put("01","zhangsan");
yure.put("02","lisi");
HashMap<String,String> jiuye = new HashMap<String,String>();
jiuye.put("01","wangwu");
jiuye.put("02","zhaoliu");
HashMap<String,HashMap<String,String>> czbk =new HashMap<String,HashMap<String,String>>();
czbk.put("yureban",yure);
czbk.put("jiuyeban",jiuye);
Set<String> keyset = czbk.keySet();
Iterator<String> it = keyset.iterator();
while(it.hasNext())//雙重循環
{
String s = it.next();
HashMap<String,String> room = czbk.get(s);
Set<String> keyset1 = room.keySet();
Iterator<String> it1 = keyset1.iterator();
while(it1.hasNext())//雙重循環
{
String num = it1.next();
String name = room.get(num);
System.out.println(s+":"+num+"--"+name);
}
}
}
}</span>
Collections是對集合框架的一個工具類。它裏邊的方法都是靜態的,不需要創建對象。並未封裝特有數據。
在Collections工具類中大部分方法是用於對List集合進行操作的,如比較,二分查找,隨機排序等。
2、常見操作
void sort(Lsit<T> list);//根據自然順序對list集合中的元素進行排序
void sort(List<T> lsit,Comparator<? super T> c);//根據指定比較器c的排序方式對list集合進行排序
b、查找
Tmax(Collection<? extends T> coll);//根據集合的自然順序,獲取coll集合中的最大元素
Tmax(Collection<? extends T> coll,Comparator<? super T> comp);//根據指定比較器comp的順序,獲取coll集合中的最大元素
intbinarySearch(Lsit<? extends Comparable<? super T>> list,Tkey);//二分法查找list集合中的指定對象
c、替換
voidfill(List<? super T> list, T obj);//將list集合中的全部元素替換成指定對象obj
booleanreplaceAll(List<T> lsit,T oldVal,T newVal);//用newVal替換集合中的oldVal值
void swap(Listlist,int i,int j);/在指定列表的指定位置處交換元素
reverse(List<?> list);//反轉list集合中元素的順序
Comparator reverseOrder();//返回一個比較器,強行逆轉了實現Comparable接口的對象的自然順序
ComparatorreverseOrder(Comparator<T> cmp);//返回一個比較器,強行逆轉了指定比較器的順序
e、同步的集合
List<T>synchronizedList(List<T> list);//返回支持的同步(線程安全的)List集合
Map<K,V>synchronizedList(Map<K,V> m);//返回支持的同步(線程安全的)Map集合
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class CollectionsDemo
{
public static void main(String[] args)
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("z");
list.add("kkkkkk");
list.add("qq");
list.add("cc");
sop(list);
//元素自身比較性排序
Collections.sort(list);
sop(list);
String max = Collections.max(list);
sop("max="+max);
int index = Collections.binarySearch(list,"aaa");
sop("''aaa'':index="+index);
index = Collections.binarySearch(list,"aaaa");
sop("''aaaa'':index="+index);
sop("------------------------------------------------");
//比較器排序
Collections.sort(list,new StuLenComparator());
sop(list);
max = Collections.max(list,new StuLenComparator());
sop("max="+max);
index = Collections.binarySearch(list,"aaa",new StuLenComparator());
sop("''aaa'':index="+index);
sop("------------------------------------------------");
Collections.reverse(list);
sop(list);
Collections.replaceAll(list,"z","fff");
sop(list);
Collections.fill(list,"shasha");
sop(list);
}
//二分法原理
public static int halfSearch(List<String> list,String key)//,Comparator<String> cmp)
{
int max,min,mid;
max = list.size()-1;
min = 0;
while(min<=max)
{
mid = (max+min)>>1;
String str = list.get(mid);
int num = str.compareTo(key);//cmp.compare(str,key);
if(num>0)
max = mid - 1;
else if (num<0)
min = mid + 1;
else
return mid;
}
return -min-1;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
class StuLenComparator 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);
}
}</span>
2、常見操作
數組變集合
注意:
a、將數組轉換成集合,不可使用集合的增刪方法,因爲數組的長度是固定的。如果進行增刪操作,則會產生UnsupportedOperationException的編譯異常。
b、如果數組中的元素都是對象,則變成集合時,數組中的元素就直接轉爲集合中的元素。
c、如果數組中的元素都是基本數據類型,那麼會將該數組作爲集合中的元素存在。
Collection接口中的toArray方法。
<T> T[]toArray(T[] a);將集合變爲指定類型的數組。
a、指定類型的數組到底要定義多長呢?
當指定類型的數組長度小於了集合的size,那麼該方法內部會創建一個新的數組。長度爲集合的size。
當指定類型的數組長度大於了集合的size,就不會新創建了數組。而是使用傳遞進來的數組。
所以創建一個剛剛好的數組最優。
b、爲什麼要將集合變數組?
爲了限定對元素的操作。不需要進行增刪了。
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class ArraysDemo
{
public static void main(String[] args)
{
//將數組轉換爲集合
sop("數組變集合-----------------");
int[] arr = {2,5,9};
sop(Arrays.toString(arr));
String[] str = {"abc","cc","kkkkk"};
List<String> list = Arrays.asList(str);
sop(list);
sop("contains:"+list.contains("cc"));
//list.add("uu");//UnsupportedOperationException
List<int[]> li = Arrays.asList(arr);
sop(li);
Integer[] num = {2,5,9};
List lis = Arrays.asList(num);
sop(lis);
//集合變數組
sop("集合變數組-----------------");
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
String[] s = al.toArray(new String[al.size()]);
sop(Arrays.toString(s));
s = al.toArray(new String[5]);
sop(Arrays.toString(s));
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}</span>
1、格式:
for(數據類型 變量名 :被遍歷的集合(collection)或者數組)
a、對集合進行遍歷。只能獲取集合元素。但是不能對集合進行操作。可以看作是迭代器的簡寫形式。
b、迭代器除了遍歷,還可以進行remove集合中元素的動作。如果使用ListIterator,還可以在遍歷過程中對集合進行增刪改查的操作。
高級for有一個侷限性。必須有被遍歷的目標(集合或數組)。
建議在遍歷數組的時候,還是希望使用傳統for。因爲傳統for可以定義腳標。
<span style="font-family:Microsoft YaHei;font-size:14px;">import java.util.*;
class ForEachDemo
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
for(String s : al)
System.out.println(s);
int[] arr = {3,5,8};
for(int i : arr)
System.out.println(i);
HashMap<Integer,String> hm = new HashMap<Integer,String>();
hm.put(1,"a");
hm.put(2,"b");
hm.put(3,"c");
for(Integer i : hm.keySet())
System.out.println(i+"---"+hm.get(i));
for(Map.Entry<Integer,String> me : hm.entrySet())
System.out.println(me.getKey()+"..."+me.getValue());
}
}</span>
在使用時注意:可變參數一定要定義在參數列表的最後面。
import static java.util.Arrays.*;//導入的是Arrays這個類中的所有靜態成員。
import static java.lang.System.*//導入了Ssytem類中所有靜態成員。
沒加static導入的是類,加上static導入的全是某一個類中所有的靜態成員。這樣寫在調用該類的靜態方法時可以不用再寫類名。如:Arrays.sort(數組);就可以直接寫sort(數組);
2、注意:
當類名重名時,需要指定具體的包名。當方法重名時,需要指定具體所屬的對象或者類。