摘要:JAVA 集合(4) Map
Map集合
該集合存儲鍵值對,而且要保證鍵的唯一性
- 增加
- put(K key, V value)
- putAll(Map<? extneds K, ?extends V> m)
- 刪除
- clear()
- remove(Object key)
- 判斷
- containsKey(Object key)
- containsVaule(Object value)
- isEmpty()
- 獲取
- value get(Object key)
- size()
- values()
- entrySet()
- keySet()
Map子類
- Hashtable: 底層是雜湊表數據結構,不可存入null鍵null值,該集合是線程同步
- HashMap: 底層是雜湊表數據結構,允許存入null鍵null值,該集合是不同步
- TreeMap: 底層是二元樹數據結構,線程不同步,可以用於map集合中的鍵進行排序
Map和Set很像,Set底層就是使用Map集合
HashMap 基本方法:
public class Main{
public static void main(String[] args){
Map<String, String> map = new HashMap<>();
//加入元素,加入時如果出現相同的鍵,則新的値會覆蓋原有的鍵對應值,並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();
// [null, a, b]
System.out.println(col);
}
}
map集合的兩種取出方式
- Set<k> keySet(): 將map中所有的鍵存入到Set集合,因為set具備迭代器,可以用迭代方式取出所有的鍵,在根據get方法,獲取每一個鍵對應的値
- 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<>();
map.put("01", "a");
map.put("02", "b");
map.put("03", "c");
//獲取map集合中的所有鍵的Set集合, keySet()
Set keySet = map.keySet();
//有了set集合就可以獲取迭代器
Iterator 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 map = new HashMap();
map.put("01", "a");
map.put("02", "b");
map.put("03", "c");
//將map集合中的映射關係取出,存入到Set集合中
Set> entrySet = map.entrySet();
Iterator> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry me = it.next();
String key = me.getKey();//
String value = me.getValue();
System.out.println("key: " + key + ", vaule: " + value);
}
}
}//map.entry
Map.Entry: 其實Entry也是一個介面,他是Map介面中的一個內部介面
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{
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 hm = new HashMap();
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 keySet = hm.keySet();
Iterator it = keySet.iterator();
while(it.hasNext()){
Student stu = it.next();
String addr = hm.get(stu);
System.out.println(stu + "... " + addr);
}
//第二種取出方式 entrySet
Set> entrySet = hm.entrySet();
Iterator> iter = entrySet.iterator();
while(iter.hasNext()){
Map.Entry me = iter.next();
Student stu = me.getKey();
String addr = me.getValue();
System.out.println(stu + "... " + addr);
}
}
} /map.entry
排序:
class Student implements Comparable{
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 tm = new TreeMap(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> entrySet = tm.entrySet();
Iterator> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry me = it.next();
Student stu = me.getKey();
String addr = me.getValue();
System.out.println(stu + "... " + addr);
}
}
}
//自定義比較器 依姓名排序 在依年齡排序
class StuNameComparator implements Comparator{
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;
}
} /map.entry
獲取字串中的字母出現的次數,產生結果如: 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 tm = new TreeMap();
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>entrySet = tm.entrySet();
Iterator> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry me = it.next();
Character ch = me.getKey();
Integer value = me.getValue();
sb.append(ch + "(" + value + ")");
}
return sb.toString();
}
} /map.entry
map集合被使用是因為具備映射關係
public class Main{
public static void main(String[] args){
HashMap a = new HashMap();
a.put("11", "x1");
a.put("12", "x2");
HashMap b = new HashMap();
b.put("21", "y1");
b.put("22", "y2");
HashMap> c = new HashMap>();
c.put("01", a);
c.put("02", b);
}
}
Collections類
public class Main{
public static void main(String[] args){
sortDemo();
}
public static void sortDemo(){
List list = new ArrayList();
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{
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 list = new ArrayList();
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{
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 list = new ArrayList();
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 ts = new TreeSet(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 ts = new TreeSet(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{
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用於操作陣列的工具類,其方法為靜態
Arrays轉List
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 list = Arrays.asList(arrStr);
sop(list);
int[] nums = {2, 4, 5};
List list2 = Arrays.asList(nums);
sop(list2);//[[I@af993e]
//如果陣列中的元素為物件, 那轉為集合後, 陣列中元素可直接轉為集合中的元素
//如果陣列中的元素為基本數據類型, 那會將該陣列作為集合中的元素存在
Integer[] nums2 = {1, 2, 3};
List 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 al = new ArrayList();
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 al = new ArrayList();
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));
}
}