Map(和Collection<E>一样都是集合框架的顶层接口)

|--Hashtable:底层是哈希表数据结构,不可以用null对象作为键或值。它是线程同步的。

|--HashMap:底层是哈希表。允许使用null键null值,该集合是不同步的,效率高,将Hashtable替代。

|--TreeMap:底层是二叉树数据结构。线程不同步,可以用于给Map集合中的键进行排序。

Map和Set很像,其实,Set底层使用了Map集合。

Map<K, V>:K-此映射所维护的键的类型,V-映射值的类型。

Map集合的特点:该集合存储键值对。一对一对往集合里面存,而且要保证键的唯一性。

以下是Map集合中的共性方法:

1.添加:V put(K key, V value)用相同的键添加值,会覆盖原来的值,每次添加返回原来键所对应的值; void putAll(Map<? extends K, ? extends V> m);

2.删除:void clear(); V remove(Object key);

3.判断:boolean containsKey(Object key); boolean containsValue(Object value);boolean isEmpty();

4.获取:V get(Object key)可以通过get方法的返回值来判断一个键值对是否存在; int size(); Collection<V> values();

两个重要的方法(Map集合的两种取出方式):

Set<Map.Entry<K, V>> entrySet():返回此映射中包含的映射关系的Set视图。而这个映射关系的数据类型就是Map.Entry。获得关系对象Map.Entry后,就可以通过Map.Entry中getKey和getValue方法获得键和值。

Set<K> keySet():返回此映射中包含的键的Set视图。因为Set具备迭代器,所有可以用迭代方式取出所有的键,再根据get方法,获取每一个键对应的值。

 

Java代码 Java集合框架(3) _3 Java集合框架(3) _3_02
  1. interface Map<K, V> {
  2. public static interface Entry<K ,V> {
  3. // 只有接口处于处于成员变量的位置,才可以用static修饰
  4. }
  5. }
  6.  
  7. class HashMap implements Map<K, V> {
  8. class HashEntry implements Map.Entry<K, V> {
  9.  
  10. }
  11. }

如果某个类需要创建多个对象,最好实现Comparable<E>接口(具备自然顺序),覆写hashCode()和equals()方法 。

 

Java代码 Java集合框架(3) _3 Java集合框架(3) _3_02
  1. /* 练习:获取某个字符串中的字母出现的次数
  2. 什么时候使用Map集合?当数据之间存在着映
  3. 射关系时,就要先想到Map集合 */
  4.  
  5. import java.util.Map;
  6. import java.util.Set;
  7. import java.util.TreeMap;
  8.  
  9. public class TreeMapDemo {
  10.  
  11.  
  12. public static void main(String[] args) {
  13. charCount("dgadfhfsdghrsahfswrteurirwxvnxmxmxmbxhahaf");
  14. }
  15.  
  16. public static void charCount(String str) {
  17. char[] chs = str.toCharArray();
  18.  
  19. TreeMap<Character, Integer> treeMap = new TreeMap<Character, Integer>();
  20. Integer temp;
  21. int count = 0;
  22. for (int i=0; i<chs.length; i++) {
  23.  
  24. if((temp = treeMap.get(chs[i])) != null) {
  25. count = temp;
  26. }
  27. count++;
  28. treeMap.put(chs[i], count);
  29. count = 0;
  30. }
  31. //(1)从Map集合中的第一种取出方式:entrySet()
  32. System.out.println("--------------first---------------------");
  33. Set<Map.Entry<Character, Integer>> treemapEntry = treeMap.entrySet();
  34.  
  35. for (Map.Entry<Character, Integer> me : treemapEntry){
  36. Character character = me.getKey();
  37. Integer integer = me.getValue();
  38. System.out.print(character + "(" + integer + ")");
  39. }
  40. System.out.println("\n" + "--------------second---------------------");
  41. //(1)从Map集合中的第一种取出方式: keySet()
  42. Set<Character> ketSet = treeMap.keySet();
  43.  
  44. for (Character character : ketSet) {
  45. Integer integer = treeMap.get(character);
  46. System.out.print(character + "(" + integer + ")");
  47. }
  48. }
  49. }

Map扩展知识

Map集合被使用是因为具备映射关系

Map<K, Map<K1, V1>>

Map<K, Collection<T>>

上面是一个一对多映射关系,第二种形式在开发中比较常见。

 

-----------------------分----------割-------------线---------------

集合框架中的工具类:

(1)Collections:集合工具类

1. public static <T extends Comparable<? super T>> void sort(List<T> list);//默认排序

2. public static <T> void sort(List<T>, Comparator<? super T> c);// 自定义排序,利用比较器

3. public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)

4. binarySearch();

5. static <T> void fill(List<? super T> list, T obj); // 用obj替代集合中的元素

6. reverseOrder(),返回一个相反的比较器,直接查文档,这个类中有很多有用的静态方法。

7.<T> T[] toArray(T[] a);//集合变数组,

1. 传入的形参数组到底应该定义多长呢?当传入的形参数组长度小于集合的size,那么该方法内部会创建一个新的数组。它的长度刚刚好是集合的size。 当传入的形参数组长度大于集合的size,那么就不会创建新的数组。就使用传进来的数组。

2. 为什么要将集合变成数组?为了限定对元素的操作。不需要进行增删了。

(2)Arrays:数组工具类

1. asList():将数组变成List集合,这样可以使用集合的思想和方法来操作数组中的元素。注意:将数组变成集合,不可以使用集合的增删方法,因为数组的长度是固定的。如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。如果数组中的元素都是基本类型,那么会将该数组作为集合中的元素存在。

2. 其他方法可以看文档

增强for循环(JDK 1.5):为了简化书写,但是会有局限性,即只能获取元素,但是不能对集合进行操作。但是迭代器除了遍历,还可以进行remove集合中的元素。如果是用ListIterator,还可以在遍历过程中进行增删改操作。要使用foreach语句,需要实现Iterable<T>接口

可变参数:JDK 1.5 版本出现的新特性,其实是数组参数的简写形式,不用每一次都手动的建立数组对象,只要将要操作的元素作为参数传递即可,隐式将这些参数封装成了数组。在使用时注意:可变参数一定要定义在参数列表的最后面。

静态导入:import static 导入的是某一类中的所有静态成员。