毕向东之Map

/*
Map集合:该集合存储键值对。一对一对往里存,而且要保证键的唯一性.(Collection集合是单个存的)
    存在映射关系时就用Map集合。
共性方法:
    1.添加
        put(K key,V value);//如果添加相同的键,那么后添加的值会覆盖原有键对应的值,
                并且put方法会返回被覆盖的值;  添加不相同的键时返回null.
        putAll(Map<? extends K,? extends V> m);
    2.删除
        clear()
        remove(Object key)
    3.判断
        containsValue(Object value)
        containsKey(Object key)
        isEmpty()
    4.获取
        get(Object key);//存在则返回对应值,不存在返回null
        size()
        values();//获取所有的值
Map集合的两种取出方式:返回类型都是Set
1.keySet:将map中所有的键存入到Set集合,因为Set具备迭代器。
        所以可以用迭代方法取出所有的键,再根据get方法获取每一个键对应的值。
        Map集合的取出原理:将Map集合转成Set集合,再通过迭代器取出。
2.entrySet:返回类型Set<Map.Entry<k,v>>,将Map集合中的映射关系存入了Set集合,
        这个关系就是Map.Entry类型(Entry接口是Map接口中的静态接口)
Map
    |--Hashtable:底层是哈希表数据结构,不可以存入null键和null值,该集合是线程同步的。
    |--HashMap:底层是哈希表数据结构,可以存入null键和null值,该线程是不同步的。(哈希值排序)
    |--TreeMap:底层是二叉树数据结构,可以用于给map集合中的键进行排序。(自定义方式排序如TreeSet)
 */
import java.util.*;
public class Test1 {
    public static void main(String[] args) {
        HashMap<Integer,String> map=new HashMap<Integer,String>();
        map.put(1,"abc1");
        System.out.println(map.put(2,"abc2"));//null
        map.put(3,"abc3");
        System.out.println(map.containsKey(1));
        System.out.println(map.containsValue("abc2"));
        System.out.println(map.get(1));
        map.put(null, "abc4");
        System.out.println(map.values());
        System.out.println(map);
        
        //方法一:利用keySet方法取出键值
        HashMap<String,String> map1=new HashMap<String,String>();
        map1.put("01", "张山01");
        map1.put("02", "张山02");
        map1.put("03", "张山03");
        map1.put("04", "张山04");
        //先获取map1集合中的键的Set集合
        Set<String> keySet=map1.keySet();
        //再获取Set集合的迭代器
        Iterator<String> it=keySet.iterator();
        //就可以输出每个键
        while(it.hasNext()){
            String key=it.next();
            System.out.println(key);
            //有了键就可以输出键对应的每个值
            System.out.println(map1.get(key));
        }
        
        //方法二:利用entrySet方法取出键值
        HashMap<String,String> map2=new HashMap<String,String>();
        map2.put("01", "王五01");
        map2.put("02", "王五02");
        map2.put("03", "王五03");
        map2.put("04", "王五04");
        Set<Map.Entry<String, String>>Entry=map2.entrySet();//返回Map.Entry类型
        Iterator<Map.Entry<String, String>> it1=Entry.iterator();
        while(it1.hasNext()){
            Map.Entry<String,String> me=it1.next();//关系迭代器给关系对象
            String key=me.getKey();//通过对象调用关系中的键值
            String value=me.getValue();
            System.out.println("Key:"+key+",Value:"+value);
        }
    }
}

 

hashCode()和equals()的关系是这样的:

如果两个对象相等(equal),它们的hashcode一定相同;

如果两个对象有相同的hashcode,它们不一定相等(equal);

/*要求:学生对象的年龄和姓名相同为同一个键
 */
import java.util.*;
public class Test2 {
    public static void main(String[] args) {
        HashMap<Student,String> hm=new HashMap<Student,String>();
        hm.put(new Student("张山",23),"上海");
        hm.put(new Student("张山",23),"北京");
//Map:如果添加相同的键,那么后添加的值会覆盖原有键对应的值,下文的equals做为判断键的依据
        hm.put(new Student("李四",24),"北京");
        hm.put(new Student("王五",25),"长沙");
        hm.put(new Student("小六",26),"永州");
        
        //第一种取出方式:
        Set<Student> set=hm.keySet();
        Iterator<Student> iter=set.iterator();
        while(iter.hasNext()){
            Student s=iter.next();
            String value=hm.get(s);
            System.out.println(s.getName()+","+s.getAge()+","+value);
        }
        System.out.println();
        //第二种取出方式:
        Set<Map.Entry<Student, String>> se=hm.entrySet();
        Iterator<Map.Entry<Student, String>> it=se.iterator();
        while(it.hasNext()){
            Map.Entry<Student, String> me=it.next();
            Student key=me.getKey();
            String value=me.getValue();
            System.out.println(key.getName()+","+key.getAge()+","+value);
        }
    }
}
//Students创建的对象太多时,也许会存到HashSet中、TreeSet中去,所以要方法重写
class Student implements Comparable<Student>{
    private String name;
    private int age;
    public 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:"+name+",age:"+age;
    }
    public int hashCode(){//对象的hash值,name也是个对象
        return name.hashCode()+age*34;//34是保证每个对象hash值的唯一性
    }//重写hashCode和equals方法是为了改变当存到HashSet集合中去的时候元素重复的条件
    public boolean equals(Object obj){
        if(!(obj instanceof Student))
            throw new ClassCastException("类型转换异常啦");//运行时异常不需要throws声明
        Student s=(Student)obj;
        return this.name.endsWith(s.name) && this.age==s.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;
    }
}

 

 

/*要求:对学生对象年龄进行升序排序
 因为数据是以键值对形式存在的,所以要使用可以排序的Map集合TreeMap
 调用了Test2中的Student类
 */
import java.util.*;
public class Test3 {
    public static void main(String[] args) {
        TreeMap<Student,String> tm=new TreeMap<Student,String>();
//TreeMap<Student,String> tm=new TreeMap<Student,String>(new Mycompare());
        //用自定义比较器按照姓名比较
        tm.put(new Student("张山",23),"上海");
        tm.put(new Student("张山",23),"北京");
//Map:如果添加相同的键,那么后添加的值会覆盖原有键对应的值,下文的equals做为判断键的依据
//和Test2不同的是这个使用TreeMap按照Student类中的compareTo方法排序,而前者使用哈希值排序。
        tm.put(new Student("王五",25),"长沙");
        tm.put(new Student("李四",24),"北京");
        tm.put(new Student("小六",26),"永州");
        Set<Student> set=tm.keySet();
        Iterator<Student> iter=set.iterator();
        while(iter.hasNext()){
            Student s=iter.next();
            String value=tm.get(s);
            System.out.println(s+","+value);
        }
        System.out.println();
        //方法二获取
        Set<Map.Entry<Student, String>> setEntry=tm.entrySet();
        Iterator<Map.Entry<Student, String>> it=setEntry.iterator();
        while(it.hasNext()){
            Map.Entry<Student, String> me=it.next();//关系对象=对象;
            Student s=me.getKey();//获取关系中的键
            String str=me.getValue();//获取关系中的值
            System.out.println(s+","+str);
        }
    }
}
class Mycompare implements Comparator<Student>{//自定义比较器
    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;
    }
}
/*===================================
 常用工具类:
 一.Collections(对list集合的操作)静态方法
    1.SynchronizedList(List<T> list) :返回一个安全的List,list里面的所以方法都加锁成安全的
      2.swap(List<T> list,int i,int j) :交换角标i、j的位置
      3.shuffle(List<?> list) :对元素随机排列(洗牌)
      4.sort(List<T> list) :按自然顺序排列 升序,但是T必须继承了Comparable
      5.sort(List<T> list,Comparator<? super T> c) :Collections.sort(list,new LenComparator());按照指定比较器排序
      6.max(list) :自然顺序的最大值
      7.max(list,comparator) :按照指定的比较器找最大值
      8.binarySearch(list,元素) :二分法查找  找不到时返回负的角标减一(找不到的这个元素插入有序集合的角标)
      9.fill(list,"pp") :将list中的所有元素都替换成pp
      10.replaceAll(list,oldval,newval) :替换旧的
      11.reverse(list) :反转
      12.reverseOrder() :返回一个逆字典顺序的比较器
      13.reverseOrder(comparator) :返回一个指定比较器的逆序比较器
 二、 Arrays
     1.asList :将数组变成list集合
         好处:可以使用集合的方法操作数组中的元素(contains get indexof subList),但是不能使用增删方法,会报不支持操作异常
         注意:如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素
             如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在
     2.toString(arr[]) :将指定数组以字符串的形式输出
三、Collection接口中的toArray方法
    1.toArray(new String[0]) :将集合转变成指定类型的数组 (大小刚好比较合适)
    为什么要将集合转变成数组?:限制操作,不能增删
四、静态导入:StaticImport
    不需要写类.静态方法()中的类名
    import static java.util.Arrays.*; //导入的是Arrays中的所有类的静态成员,而不是导入类
    注意:当类名重名时,需要指定具体的包名
        当方法重名时,指定具备所属的对象或者类
五、System 系统信息
    1.Properties getProperties();//获取系统属性信息
        Properties是Map的子类,所以可以通过map的方法取出
六、Runtime    对运行的处理 不可以new对象
    1、getRuntime() 返回当前应用程序运行时对象
七、Date 日期
    1.DateFormat-->SimpleDateFormat
        如:SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
           String time=sdf.format(new Date()); 用模式格式化指定Date对象
八、Calendar 日历   比Date方法多
    1.Calendar c=Calendar.getInstance();//当前日期
      c.get(Calendar.Year);获取年份 比Date方便
九、Math 
    1.round 四舍五入
    2.math.ceil(16.34) 返回大于指定数据的最小整数
    3.floor 返回小于指定数据的最大整数
 */

 

posted @ 2016-05-31 12:52  ts-android  阅读(343)  评论(0编辑  收藏  举报