Day18-Java
文章目錄
- Day18-Java
- 1、Map集合
- 1.1 子類:HashMap
- 面試題:解釋HashMap的原理
- 1.2 子類:Hashtable
- 1.3 ConcurrentHashMap子類
- 1.4 Map使用Iterator輸出
- 1.5 Map中的key實作說明
- 1.6 TreeMap子類
1、Map集合
偶物件指的是一對物件,即:兩個物件同時保存,這兩個物件是按照了“key=value”的形式進行定義的,即:可以通過key找到對應的value資料,就好像電話本一樣,例如,電話本之中保存了如下的資訊:
Key =張三,value=123456;
Key=李四,value=234567;
現在如果要想找到張三的電話,那么肯定根據張三的key,取得對應的value,而如果現在要想找到王五的電話,由于沒有王五這個key,所以回傳的結果就是null,
Map就是實作這樣一種操作的資料結構,這個介面之中的定義的主要操作方法如下,
| 方法名稱 | 型別 | 描述 |
|---|---|---|
| public V put(K key, V value) | 普通 | 向集合之中保存資料 |
| public V get(Object key) | 普通 | 通過指定的key取得對應value |
| Public Set keyset() | 普通 | 將Map中的所有key以Set集合的方式回傳 |
| Public Set<Map,Entry<K,V>>entrySet() | 普通 | 將Map集合變為Set集合 |
在Map介面之中有兩個常用的子類:HashMap,Hashtable,
1.1 子類:HashMap
HashMap是Map介面之中使用最多的一個子類
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
HashMap演示Map介面中各個主要方法的作用
驗證Map
package com.day18.demo;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1, "Hello,world!!");
map.put(2, "zsr");
map.put(3, ".com");
Set<Integer> keyset = map.keySet();//取得所有的key資訊
Iterator<Integer> iterator = keyset.iterator();
while(iterator.hasNext()){
Integer key = iterator.next();
System.out.println(key + "=" + map.get(key));
}
}
}
面試題:解釋HashMap的原理
? 在資料量小的時候HashMap是按照鏈表的模式存盤的,當資料量變大之后,為了進行快速的查找,將這個鏈表變為一個紅黑樹(均衡二叉樹),用hash碼作為資料定位,來進行保存的,
? 所有的方法都是異步的,屬于執行緒不安全操作,
1.2 子類:Hashtable
jdk1.0提供三大主要類:Vector、Enumeration、Hashtable,
Hashtable是最早實作這種二元偶物件資料結構,由于后期的設計也讓其與Vector一樣多實作了MMap介面,
package com.day18.demo;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashtableDemo {
public static void main(String[] args) {
Map<Integer,String> map = new Hashtable<>();
map.put(1, "Hello,world!!");
map.put(2, "zsr");
map.put(3, ".com");
map.put(null, null);
System.out.println(map);
}
}
Exception in thread "main" java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:460)
at com.day18.demo.HashtableDemo.main(HashtableDemo.java:15)
以上Hashtable無法傳入空值并對其進行輸出,而HashMap可以
package com.day18.demo;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashtableDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1, "Hello,world!!");
map.put(2, "zsr");
map.put(3, ".com");
map.put(null, null);
System.out.println(map);
}
}
{null=null, 1=Hello,world!!, 2=zsr, 3=.com}
| 區別 | HashMap | Hashtable |
|---|---|---|
| 時間 | JDK1.2 | JDK1.0 |
| 性能 | 采用異步處理方式,性能高 | 采用同步處理方式性能相對較低 |
| 安全性 | 執行緒安全 | 執行緒不安全 |
| 設定null | 允許key、value設定為null | 不允許key、value設定為null,否則出現例外 |

1.3 ConcurrentHashMap子類
ConcurrentHashMap 的特點 = Hashtable的執行緒安全性 + HashMap的高性能,在使用ConcurrentHashMap處理的時候既可以保證多個執行緒更新資料的同步,又可以保證很高效的查詢速度,
public class ConcurrentHashMap<K,V>
extends AbstractMap<K,V>
implements ConcurrentMap<K,V>, Serializable
如果說現在采用一定的演算法,將保存的大量資料平均分在不同的桶(資料區域),這樣在進行資料查找的時候就可以避免這種全部的資料掃描,
資料分桶
package com.day18.demo;
import java.util.Random;
public class ConcurrentHashMapDemo {
public static void main(String[] args) {
for(int i = 0; i <10 ; i++){
new Thread(()->{
Random random = new Random();
int temp = random.nextInt(9999);
int result = temp % 3;
switch(result){
case 0:
System.out.println("第0桶" + temp);
break;
case 1:
System.out.println("第1桶" + temp);
break;
case 2:
System.out.println("第2桶" + temp);
break;
}
}).start();
}
}
}
采用分桶之后每一個資料必須有一個明確的分桶標記,很明顯使用hashCode(),




1.4 Map使用Iterator輸出
在實際的開發之中,如果你存盤資料是為了輸出,那么優先考慮一定是Collection,使用Map的主要操作就是設計我們的內容,而后通過get()進行查找,使用Map迭代輸出的需求會有,但是不多,
通過一個簡單的圖形來觀察Collection與Map保存資料的區別


通過Iterator輸出Map內容
package com.day18.demo;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MapIteratorDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1, "hELLO,");
map.put(2, "WORLD!!!");
//1.將map變為Set集合
Set<Map.Entry<Integer,String>> set = map.entrySet();
//2.實體化Iterator介面
Iterator<Entry<Integer, String>> iter = set.iterator();
//3.迭代輸出每一個Map.Entry物件
while(iter.hasNext()){
//4.取出Map.Entry
Map.Entry<Integer, String> me = iter.next();
//5.取得key和value
System.out.println(me.getKey() + "=" + me.getValue());
}
}
}
1.5 Map中的key實作說明
自定義Key型別
package com.day18.demo;
import java.util.HashMap;
import java.util.Map;
class Person2{
private String name;
public Person2(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person2 other = (Person2) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class PersonDemo {
public static void main(String[] args) {
Map<Person2,String> map = new HashMap<Person2,String>();
map.put(new Person2("張三"), new String("zs"));
System.out.println(map.get(new Person2("張三")));
}
}
因為實際開發,對于map集合中key型別,不是String就是Integer,這些系統類都幫用戶覆寫了equals()、hashCode()方法了,
1.6 TreeMap子類
可以排序的Map子類,他是按照key的內容來進行排序的,
TreeMap操作
package com.day18.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
class Person2{
private String name;
public Person2(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person2 other = (Person2) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class PersonDemo {
public static void main(String[] args) {
Map<Person2,String> map = new TreeMap<Person2,String>();
map.put(new Person2("張三"), new String("zs"));
System.out.println(map.get(new Person2("張三")));
}
}
Exception in thread "main" java.lang.ClassCastException: com.day18.demo.Person2 cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at com.day18.demo.PersonDemo.main(PersonDemo.java:51)
出現以上問題是因為沒有實作Comparable介面,
package com.day18.demo;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
class Person2 implements Comparable<Person2>{
private String name;
public Person2(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public int compareTo(Person2 o) {
// TODO Auto-generated method stub
return this.name.compareTo(o.name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person2 other = (Person2) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class PersonDemo {
public static void main(String[] args) {
Map<Person2,String> map = new TreeMap<Person2,String>();
map.put(new Person2("張三"), new String("zs"));
System.out.println(map.get(new Person2("張三")));
}
}
Collection保存資料的目的是為了輸出、Map保存資料的目的是為了根據key查找,
Map使用Iterator輸出(Map.Entry的作用)
一些類的設計原理,這些是在你面試用得到的,而我們開發里面就是使用HashMap子類
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/297572.html
標籤:java
