Map
Map<K,V>
K-Key ,V -ValueSet的底层其实就是Map(Map在英语里是地图就是一一对应的意思)
public interface Map<K,V>
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
此接口取代 Dictionary 类,后者完全是一个抽象类,而不是一个接口。
Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集
的形式查看某个映射的内容。映射顺序 定义为迭代器在映射的
collection 视图上返回其元素的顺序。某些映射实现可明确保证其顺序,
如 TreeMap 类;另一些映射实现则不保证顺序,如HashMap 类。
注:将可变对象用作映射键时必须格外小心。
当对象是映射中某个键时,如果以影响 equals
比较的方式更改了对象的值,则映射的行为将是不确定的。
此项禁止的一种特殊情况是不允许某个映射将自身作为一个键包含。
虽然允许某个映射将自身作为值包含,但请格外小心:在这样的映射上
equals 和 hashCode 方法的定义将不再是明确的。
HashMap
Class HashMap<K,V>
- 从名字我们就可以得知它的底层数据结构是Hash表(Hash表的实质是数组+链表)
- Hash表?、Hash算法?
- HashMap实现原理分析
- HashMap 是我们在程序中用的很多的一个类,我们常说它是一个无序的容器那么这个无序到底是什么意思呢?
- 无序、有序?
意思就是说它是存取无序的(注意不是随机),存储是有序的。它每次输出的顺序是一样的这个是Hash算法决定的。
import java.util.*;
class MapDemo{
public static void main(String[] args){
Map<String,String> m = new HashMap<String,String>();
print("put:"+m.put("01","w111"));
print("put:"+m.put("01","w112"));
//会返回这个键对应的原来的值并覆盖
m.put("02","w2");
m.put("03","w3");
m.put(null,"w3");
m.put("04",null);
print(m.containsKey("01"));
print(m.get(null));
print(m.get("04"));
print(m.values());
}
public static void print(Object obj){
System.out.println(obj);
}
}
- 它有两个重要的方法
entrySet() KeySet()
会返回Set集合 entrySet:public Set<Map.Entry<K,V>> entrySet()
keySet:public Set<K> keySet()
Map.Entry
public static interface Map.Entry<K,V>
映射项(键-值对)。- 可以看见Map.Entry接口有静态修饰符。从接口的概念上来讲,接口只能由抽象方法和全局常量组成,但是内部结构是不受概念限制的,正如抽象类中可以定义抽象内部类一样,在接口中也可以定义普通内部类、抽象内部类和内部接口
- Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类。获得映射项引用的唯一 方法是通过此 collection 视图的迭代器来实现。
- 举一个一对多的例子
/*一对多 Map<T,Set<类>> 、 Map<T,Map<T,T>>*/
import java.util.*;
class MapTest{
public static void main(String[] args){
Map<String,Map<String,Integer>> school = new HashMap<String,Map<String,Integer>>();
Map<String,Integer> class01 = new HashMap<String,Integer>();
Map<String,Integer> class02 = new HashMap<String,Integer>();
school.put("class01",class01);
school.put("class02",class02);
class01.put("xiaoa",01);
class01.put("xiaob",02);
class02.put("xiaoc",01);
class02.put("xiaod",02);
getClassInfo(school);
}
public static void getClassInfo(Map<String,Map<String,Integer>> school){
// Set<String> keySet = school.keySet();
for (Iterator it = school.keySet().iterator();it.hasNext() ; ) {
Map<String,Integer> cls = school.get(it.next());
// for(Iterator clit = cls.keySet().iterator();clit.hasNext();){
// System.out.println(cls.get(clit.next()));
// }
Set<Map.Entry<String,Integer>> clsme = cls.entrySet();
for (Iterator<Map.Entry<String,Integer>> cli = clsme.iterator();cli.hasNext() ; ) {
Map.Entry<String,Integer> me = cli.next();
System.out.println(me.getKey()+"::"+me.getValue());
}
}
}
}
HashMap&HashTable
- HashTable 不允许null
- HashMap 运行null键和null值
- HashTable 同步
- HashMap 不同步
TreeMap
public class TreeMap<K,V>
- 基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
//统计字符出现次数
import java.util.*;
class TreeMapTest2{
public static void main(String[] args){
String str = "asdfkcv43_gergxzkzsdaa";
char[] chs = str.toCharArray();
//Character 实现了自然排序 Comparable
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
for (int x=0;x<chs.length;x++ ) {
if(!(chs[x]>='a'&&chs[x]<='z'||chs[x]>='A'&&chs[x]<='Z'))
continue;
Integer value = tm.get(chs[x]);
tm.put(chs[x],value==null?1:++value);
}
StringBuilder sb = new StringBuilder();
Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
for (Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();it.hasNext() ; ) {
Map.Entry<Character,Integer> me= it.next();
sb.append(me.getKey()+"("+me.getValue()+")");
}
System.out.println(sb);
}
}