2017

来源:互联网 发布:男士背包 知乎 编辑:程序博客网 时间:2024/04/30 22:33
1 Map
  作为学生来说,是根据学号来区分不同的学生的,那么假设我现在已经知道了学生的学号,我要根据学号去获取学生姓名,请问怎么做呢?
  如果采用前面讲解过的集合,我们只能把学号和学生作为一个对象的成员,然后存储整个对象,将来遍历的时候,判断,获取对应的名称。
  但是,如果我都能把学生姓名拿出来了,我还需要根据编号去找吗?
  针对我们目前的这种需求,仅仅知道学号,就想知道学生姓名的情况,java就提供了一种新的集合 Map
  通过查看API,我们知道Map集合的一个最大的特点,就是它可以存储键值对的元素,这个时候存储我们上面的需求,就可以这样做
    学号1         姓名1
    学号2         姓名2
    学号3         姓名3
    学号2(不行)   姓名4
    学号4         姓名4

Map集合的特点:
  将键映射到值得对象,一个映射不能包含重复的键:每个键最多只能映射到一个值。
Map集合和Collection集合的区别?
  Map集合存储元素是成对出现的,Map集合的键是唯一的,值是可重复的。可以把这个理解为:夫妻对。
  Collection集合存储元素是单独出现的,Collection的儿子Set是唯一的,List是可重复的,可以把这个理解为:光棍。      
注意:
Map集合的数据结构值针对键有效,跟值无关
Collection集合的数据结构是针对元素有效

HashMap,TreeMap

2 Map集合的功能概述
(1)添加功能
     V put(K key,V value):添加元素。这个其实还有另一个功能,先不讲。
           如果键是第一次存储,就直接存储元素,返回null 
           如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
(2)删除功能
     void clear():移除所有的键值对元素
     V remove(Object key):根据键删除键值对元素,并把值返回
(3)判断功能
     boolean containsKey(Object key):判断集合是否包含指定的键
     boolean containsValue(Object value):判断集合是否包含指定的值
     boolean isEmpty():判断集合是否为空
(4)获取功能
     Set<Map.Entry<E,V>> entrySet():???
     V get(Object key):根据键获取值
     Set<E> keySet():获取集合中所有键的集合
     Collection<V> values():获取集合中所有值得集合
(5)长度功能
     int size():返回集合中的键值对的对数
---------------------------------------------
     //创建集合对象
     Map<String,String> m = new HashMap<String,String>();
     //添加元素
     //V put(K key,V value):添加元素。这个其实还有另一个功能,先不讲。   
     System.out.println("put:"+m.put("学号1","学生1"));
     System.out.println("put:"+m.put("学号1","学生2"));
     //输出集合名称
     System.out.println("map:"+map);
     //输出: put:null 
                    put:学生1
                    map:{学号1=学生2}
----------------------------------------------------------
     //创建集合对象
     Map<String,String> m = new HashMap<String,String>();
     //添加元素
     map.put("学号1","学生1");
     map.put("学号2","学生2");
     map.put("学号3","学生3");
     //输出集合名称
     //System.out.println("map:"+map);
     //输出:map:{学号1=学生2,学号3=学生3,学号2=学生2} //无序
      
     System.out.println("remove:"+map.remove("学号1"));  
     System.out.println("remove:"+map.remove("学号1"));
     //输出: remove:学生1
              remove:null
              map:{学号3=学生3,学号2=学生2}

3 Map 获取功能
     Set<Map.Entry<E,V>> entrySet():???
     V get(Object key):根据键获取值
     Set<E> keySet():获取集合中所有键的集合
     Collection<V> values():获取集合中所有值得集合
-----------------------------------------------------------
     //创建集合对象
     Map<String,String> m = new HashMap<String,String>();
     //添加元素
     map.put("学号1","学生1");
     map.put("学号2","学生2");
     map.put("学号3","学生3");
     // V get(Object key):根据键获取值
     System.out.println("get:"+map.get("学号1"));
     //输出:  get:学生1

     //Set<E> keySet():获取集合中所有键的集合
     Set<String> set = map.keySet();
     for(String key : set){
           System.out.println(key);
       }
     //输出:  学号1
               学号2
               学号3
       
     //  Collection<V> values():获取集合中所有值得集合
     Collection<String> con = map.values();
     for(String value : con){
            System.out.println(value);
         }
     //输出:  学生1
               学生2
               学生3

4 Map 集合的遍历
(1)  //创建集合对象
     Map<String,String> m = new HashMap<String,String>();
     //添加元素
     map.put("学号1","学生1");
     map.put("学号2","学生2");
     map.put("学号3","学生3");
     //遍历
     //获取所有的键
     Set<String> set = map.keySet();
     //遍历集合的键,获取得到每一个键
     for(String key : set){
           //根据键去找值
           String value = map.get(key) ;
           System.out.println(key+"---"+value);
       }

(2)  
A:获取所有键值对对象的集合
B:遍历键值对对象的集合,得到每一个键值对对象
C:根据键值对对象获取键和值
这里麻烦的是键值对对象如何表示呢?
     看看我们开始的一个方法:
      Set<Map.Entry<E,V>> entrySet():返回的是键值对对象的集合

     //创建集合对象
     Map<String,String> m = new HashMap<String,String>();
     //添加元素
     map.put("学号1","学生1");
     map.put("学号2","学生2");
     map.put("学号3","学生3");
     //获取所有键值对对象的集合
     Set<Map.Entry<String,String>> set = map.entrySet();
     //遍历键值对对象的集合,得到每一个键值对对象
     for(Map.Entry<String,String> me : set){
             //根据键值对对象获取键和值
             String key = me.getKey();
             String value = me.getValue();
             System.out.println(key + "---" + value);
       }
     //输出:   学号1---学生1
                      学号2---学生2
                      学号3---学生3

(3) 两种方式的图解



5 HashMap
  HashMap:是基于哈希表的Map接口实现。
  哈希表的作用是用来保证键的唯一性的。
----------------------------------------------------
(1)HashMap<String,String>
     //创建集合对象
     HashMap<String,String> hm = new HashMap<String,String>();
     //创建元素并添加元素
     hm.put("it001","马云");
     hm.put("it002","马化腾");
     hm.put("it003","乔布斯");
     hm.put("it004","张朝阳");
     hm.put("it001","马云2"); //覆盖掉马云 保证唯一性
     //遍历
     Set<String> set = hm.keySet();
     for(String key : set){
             String value = hm.get(key);
             System.out.println(key + "---" +value);
       }
-----------------------------------------------------
(2)HashMap<Integer,String>
     //创建集合对象
     HashMap<Integer,String> hm = new HashMap<Integer,String>();
     //创建元素并添加元素
     hm.put(1,"马云");
     hm.put(2,"马化腾");
     hm.put(3,"乔布斯");
     hm.put(4,"张朝阳");
     //下面的写法是八进制,但是不能出现8以上的单个数据
     //hm.put(001,"hello"); //不报错
     //hm.put(005,"hello"); //不报错
     //hm.put(008,"hello"); //报错
     //遍历
     Set<Integer> set = hm.keySet();
     for(Integer key : set){
             String value = hm.get(key);
             System.out.println(key + "---" +value);
       }
-------------------------------------------------------
(3) HashMap<String,Student>

     //创建集合对象
     HashMap<String,Student> hm = new HashMap<String,Student>();
     //创建学生对象
     Student s1 = new Student("学生1",15);
     Student s2 = new Student("学生2",15);
     Student s3 = new Student("学生3",15);
     Student s4 = new Student("学生4",15);
     //添加元素
     hm.put("957",s1);
     hm.put("958",s2);
     hm.put("959",s3);
     hm.put("960",s4);
     //遍历
     Set<String> set = hm.keySet();
     for(String key : set){
        //注意了:这次值不是字符串了
        //String value = hm.get(key);
        Student value = hm.get(key);
        System.out.println(key+"---"+value.getName()+"---"+value.getAge());
        }
      //输出:
             957---学生1---15
             958---学生2---15
             959---学生3---15
             960---学生4---15
---------------------------------------------------------
(4) HashMap<Student,String>
键:Student
       要求:如果两个对象的成员变量值都相同,则为同一个对象
值:String
       
     //创建集合对象
     HashMap<Student,String> hm = new HashMap<Student,String>();
     //创建学生对象
     Student s1 = new Student("学生1",15);
     Student s2 = new Student("学生2",15);
     Student s3 = new Student("学生3",15);
     Student s4 = new Student("学生4",15);
     Student s4 = new Student("学生4",15);
     //添加元素
     hm.put(s1,"957");
     hm.put(s2,"958");
     hm.put(s3,"959");
     hm.put(s4,"960");
     hm.put(s4,"961");
     //遍历
     Set<Student> set = hm.keySet();
     for(Student key : set){    
        String value = hm.get(key);
        System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
  }
     //输出:
            学生1---15---957
            学生2---15---958
            学生3---15---959
            学生4---15---960
            学生4---15---961
      //因为HashMap 底层是Hash  依赖于equals和hashCode
      //需要在学生类中重写 equals类即可。

6 LinkedHashMap
    是Map接口的哈希表和链表实现,具有可预知的迭代顺序
    由哈希表保证键的唯一性
    由链表保证键类的有序(存储和取出的顺序一致)

  import java.util.LinkedHashMap;
  import java.util.Set;
    //创建集合对象
    LinkedHashMap<String,String> hm = new LinkedHashMap<String,String>();
    //创建并添加元素
    hm.put("1","hello");
    hm.put("2","world");
    hm.put("3","java");
    hm.put("4","javaee");
    hm.put("4","javaeeee");
    //遍历
     Set<String> set = hm.keySet();
     for(String key : set){
             String value = hm.get(key);
             System.out.println(key + "---" +value);
       }
     //输出:
             1---hello 
             2---world
             3---java
             4---javaeeee

7 TreeMap
   是基于红黑树的Map接口的实现。
------------------------------------------------------------
    //创建集合对象
    TreeMap<String,String> tm = new TreeMap<String,String>();
    //创建并添加元素
    tm.put("1","hello");
    tm.put("2","world");
    tm.put("3","java");
    tm.put("4","javaee");
    tm.put("4","javaeeee");
    //遍历
     Set<String> set = tm.keySet();
     for(String key : set){
             String value = tm.get(key);
             System.out.println(key + "---" +value);
       }
    //输出(自然排序):
             1---hello 
             2---world
             3---java
             4---javaeeee
-------------------------------------------------------------
     //创建集合对象
     TreeMap<Student,String> tm = new TreeMap<Student,String>();
     //创建学生对象
     Student s1 = new Student("学生1",15);
     Student s2 = new Student("学生2",15);
     Student s3 = new Student("学生3",15);
     Student s4 = new Student("学生4",15);
     Student s4 = new Student("学生4",15);
     //添加元素
     tm.put(s1,"957");
     tm.put(s2,"958");
     tm.put(s3,"959");
     tm.put(s4,"960");
     tm.put(s4,"961");
     //遍历
     Set<Student> set = tm.keySet();
     for(Student key : set){    
        String value = tm.get(key);
        System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
  }
      //会报错   因为没有给定排序
-----------------------比较器排序----------------------
      //创建集合对象
     TreeMap<Student,String> tm = new TreeMap<Student,String>(
                new Comparator<Student>(){
                    @Override
                public int compare(Student s1 , Student s2){
                    //主要条件
                    int num = s1,getAge() - s2.getAge();
                    //次要条件
                    int num2 = num == 0 ? s1.getName().compareTo(                                     s2.getName()) :num ;
                    return num ;
               }
}
);

8 练习:统计字符串中每个字符串出现的次数
要求:"aaaabbbcccdd"  结果:a(4)b(3)c(3)d(2)

  //定义一个字符串(可以改进为键盘录入)
  Scanner sc = new Scanner(System.in);
  System.out.println("请输入一个字符串:");
  String line = sc.nextLine();
  //定义一个TreeMap的集合
  TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
  //把字符串转为字符数组
  char[] chs = line.toCharArray();
  //遍历字符数组,得到每一个字符
  for(char ch : chs){
     //拿刚才得到的字符作为键到集合中去找值,看返回值
     Integer i = tm.get(ch);
     //是null:说明该键不存在,就把该字符作为键,1作为值存储
     if(i == null){
         tm.put(ch,1);
  }else{
     //不是null:说明该键存在,就把值加1,然后重写存储该键和值
         i++;
         tm.put(ch,i);
       }
 }
      //定义字符串缓冲区变量
      StringBuilder sb = new StringBuilder();
      //遍历集合,得到键和值,进行按照要求拼接
      Set<Character> set = tm.keySet();
      for(Character key : set){
                   Integer value = tm.get(key);
                   sb.append(key).append("(").append(value).append(")");
 }
      //把字符串缓冲区转换成字符串输出
      String result = sb.toString();
      System.out.println("result:"+result);
     
9 HashMap 集合嵌套HashMap
  //创建集合对象
  HashMap<String,HashMap<String,Integer>> bigMap = new HashMap<String,HashMap<String,Integer>>;
  //创建小班集合对象
  HashMap<String,Integer> smallMap = new HashMap<String,Integer>();
  //添加元素
  smallMap.put("小班学生1",20); 
  smallMap.put("小班学生2",22); 
  smallMap.put("小班学生3",21); 
  smallMap.put("小班学生4",20);
  //把小班加到大集合中
  bigMap.put("small",smallMap);
  
  //创建小班2集合对象
  HashMap<String,Integer> small2Map = new HashMap<String,Integer>();
  //添加元素
  small2Map.put("小班2学生1",20); 
  small2Map.put("小班2学生2",22); 
  small2Map.put("小班2学生3",21); 
  small2Map.put("小班2学生4",20);
  //把小班2加到大集合中
  bigMap.put("small2",small2Map);
  
  //遍历集合
  Set<String> bigMapSet = bigMap.keySet();
  for(String bigMapKey : bigMapSet){
         System.out.println(bigMapKey);
          HashMap<String,Integer> bigMapValue = bigMap.get(bigMapKey);
          Set<String> bigMapValueSet = bigMapValue.keySet();
           for(String bigMapValueKey : bigMapValueSet){
              Integer bigMapValueValue = bigMapValue.get(bigMapValueKey);
                System.out.println(bigMapValueKey+"---"+bigMapValueValue);
     }
 }

10 HashMap 嵌套 ArrayList
   //创建集合对象
   HashMap<String,ArrayList<String>> hm = now HashMap<String,ArrayList<String>>();
   //创建元素集合1
   ArrayList<String> array1 = new ArrayList<String>();
   array1.add("吕布");
   arrayl.add("周瑜");
   hm.put("三国演义",array1);

   //创建元素集合2
   ArrayList<String> array2 = new ArrayList<String>();
   array1.add("令狐冲");
   arrayl.add("林平之");
   hm.put("笑傲江湖",array2);

   //创建元素集合3
   ArrayList<String> array3 = new ArrayList<String>();
   array1.add("郭靖");
   arrayl.add("杨过");
   hm.put("神雕侠侣",array3);

   //遍历集合
   Set<String> set = hm.keySet();
   for(String key : set){
           System.out.println(key);
            ArrayList<String> value = hm.get(key);
            for(String s : value){
                 System.out.println(s);
        }
 }
  //输出
             三国演义
                            吕布
                            周瑜
             笑傲江湖     
                            令狐冲
                            林平之
             神雕侠侣
                            郭靖
                            杨过


11 ArrayList 嵌套 HashMap
   //创建集合对象
   ArrayList<HashMap<String,String>> array = new ArrayList<HashMap<String,String>>();
   //创建元素1
   HashMap<String,String> hm1 = new HashMap<String,Stirng>();
   hm1.put("周瑜","小乔");
   hm1.put("吕布","貂蝉");
   //把元素添加到array里面
   array.add(hm1);

   //创建元素2
   HashMap<String,String> hm2 = new HashMap<String,Stirng>();
   hm2.put("郭靖","黄蓉");
   hm2.put("杨过","小女龙");
   //把元素添加到array里面
   array.add(hm2);

   //创建元素1
   HashMap<String,String> hm3 = new HashMap<String,Stirng>();
   hm3.put("令狐冲","任盈盈");
   hm3.put("林平之","岳灵珊");
   //把元素添加到array里面
   array.add(hm3);

   //遍历
   for(HashMap<String,String> hm : array){
            set<String> set = hm.keySet();
            for(String key : set){
                 String value = hm.get(key);
                  System.out.println(key +"---"+value);
                }
       }

12 三层嵌套
     //创建大集合
     HashMap<String,HashMap<String,ArrayList<Student>>> czbkMap = new HashMap<String,HashMap<String,ArrayList<Student>>>();
     //北京校区数据
     HashMap<String,ArrayList<Student>> bjCzbkMap = new HashMap<String,ArrayList<Student>>;
     ArrayList<Student> array1 = ArrayList<Student>();
     Student s1 = new Student("林青霞",27);
     Sutdent s2 = new Student("风清扬",30);
     array1.add(s1);
     array1.add(s2);
     ArrayList<Student> array2 = ArrayList<Student>();  
     Student s3 = new Student("赵雅芝",27);
     Sutdent s4 = new Student("武鑫",30);
     array2.add(s3);
     array2.add(s4);
     bjCzbkMap.put("基础班",array1);
     bjCzbkMap.put("就业班",array2);
     czbkMap.put("北京校区",bjCzbkMap);
     
     //西安校区数据     
     HashMap<String,ArrayList<Student>> xaCzbkMap = new HashMap<String,ArrayList<Student>>;
     ArrayList<Student> array3 = ArrayList<Student>();
     Student s5 = new Student("范冰冰",27);
     Sutdent s6 = new Student("刘毅",30);
     array3.add(s5);
     array3.add(s6);
     ArrayList<Student> array4 = ArrayList<Student>();  
     Student s7 = new Student("李冰冰",27);
     Sutdent s8 = new Student("张志豪",30);
     array4.add(s7);
     array4.add(s8);
     xaCzbkMap.put("基础班",array3);
     xaCzbkMap.put("就业班",array4);
     czbkMap.put("西安校区",xaCzbkMap);

     //遍历集合
     Set<Stirng> czbkMapSet = czbkMap.keySet();
     for(String czbkMapKey : czbkMapSet){
              System.out.println(czbkMapKey);
         HashMap<String,ArrayList<Student>> czbkMapValue = czbkMap.get(czbkMapKey);
         Set<String> czbkMapValueSet =czbkMapValue.keySet();
         for(String czbkMapValueKey : czbkMapValueSet){
                  ArrayList<Student> czbkMapValueValue = czbkMapValue.get(czbkMapValueKey);
         for(Student s : czbkMapValueValue){
               System.out.println("\t"+s.getName()+"\t"+s.getAge());
               }
      }
 }

13 Hashtable 和HashMap 的区别
   Hashtable:线程安全,效率低,不允许你null键和null值
   Hashmap:线程不安全,效率高,允许null 键和null值

   List,Set,Map等接口是否都继承自Map接口
   List,Set不是继承自Map接口,它们继承自Collection接口
   Map接口本身就是一个顶层接口  

14 Collections
    是针对集合进行操作的工具类,都是静态方法
  面试题:
   Collection和Collections的区别?
     Collection:是单列集合的顶层接口,有子接口List和Set。
     Collections:是针对集合操作的工具类,有队集合进行排序和二分查找的方法。

public static <T> void sort(List<T> list) : 排序 默认情况下是自然排序
public static <T> int binarySearch(List<?> list,T key) :二分查找
public static <T> T max(Collection<?> coll) : 最大值
public static void reverse(List<?> list) :反转
public static void shuffle(List<?> list) :随机置换

15 ArrayList存储自定义对象并排序

  //创建集合对象
   List<Student> list = new ArrayList<Student>();
   //创建元素
   Student s1 = new Student("nihao",27);
   Student s2 = new Student("hello",26);
   Student s3 = new Student("world",28);
   Student s4 = new Student("java",20);
   Student s5 = new Student("javaee",20);
   //添加元素
   list.add(s1);
   list.add(s2);
   list.add(s3);
   list.add(s4);
   list.add(s5);
   //自然排序
   //Collection.sort(list);
   //比较器排序 如果同时有自然排序和比较器排序,以比较器排序为主
   Collection.sort(list,new Comparator<Student>(){
         @Override
    public int compareTo(Student s){
         int num = this.age - s.age;
         int num2 = num == 0 ? this.name.compareTo(s.name) : num;
         return num2;
          }
);
   //遍历集合
   for(Student s : ts){
         System.out.println(s.getName()+"---"+s.getAge());
    }
   //输出: java---20
            javaee---20
            hello---26
            nihao---27
            world---28

 //自然排序 需要在Student类中重写
 public class Student implements Comparable<Student>{
      ......
          @Ovrride
    public int compareTo(Student s){
         int num = this.age - s.age;
         int num2 = num == 0 ? this.name.compareTo(s.name) : num;
         return num2;
}
原创粉丝点击