黑马程序员_JAVA笔记16——集合(Map)

来源:互联网 发布:大屏幕windows平板电脑 编辑:程序博客网 时间:2024/05/04 06:37
------- android培训、java培训、期待与您交流! ----------
1、Map,接口Map<K V>,将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值。
                K:此映射锁维护的键的类型
                V:映射值的类型
    特点:该集合存储键值对,一对一对往里存,而且保证键的唯一性
        添加
               V  put(K key, V value)
                putAll(Map <? extends K,? extends V> m);
        删除
                clear();清空此影身中所有映射关系
                remove(Object key)
        判断
                boolean containKey(Object value);判断此映射中是否含有映射关系value
                containsKey(Object key)
                isEmpty()
        获取
                get(Object key)
                size()
                Collection <V> values()
                entrySet()
                keySet()
2、Map:
                Hashtable:底层是哈希表数据结构,不可以存入null键null值情况。该集合是线程同步的(1.0)
                HashMap:底层是哈希表数据结构,可以存入null键null值。该集合不同步(1.2,效率高)。
                TreeMap:底层二叉树数据结构,线程不同步,可以用于给map集合中的键进行排序

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

import java.util.*;
class  MapDemo
{
        public static void sop(Object obj)
        {
                System.out.println(obj);
        }
        public static void main(String[] args)
        {
                Map<String ,String> map = new HashMap<String ,String>();
                //添加元素,如果出现相同的值,那么后添加的值会覆盖原有键的对应值,put方法会返回原有键的对应值
                map.put("01","zhangsan1");
                map.put("01","wangwu");//此时因为两个01,后来的wangwu会替换zhangsan1,并且该方法返回被替代的值,即zhangsan1
                map.put("02","zhangsan2");
                map.put("03","zhangsan3");
                map.put("04","zhangsan4");//键值对存入后,在map中是无序的
                
                sop(map.containsKey("39"));//判断是否含有key39,返回值true false
                sop(map.remove("08"))//若不存在,返回null。若存在,先获取再删除

                sop(map.get("02"));//若不存在,返回null

                map.put(null,"fdfd");//HashMap可以将null存入
                sop(map.get(null));//可以取null,返回fdfd
                //可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断。

                //获取map集合中所有值
                Collection<String> coll = map.values();
                sop(coll);
        }
}

3、keySet;将map中所有的键都存入到Set集合,因为set具备迭代器,所以可以迭代方式取出所有的键,再根据get方法,获取每一个键对于值。
    Map集合取出原理,将map集合转成set集合,再通过迭代器取出

import java.util.*;
class  MapDemo
{
        public static void sop(Object obj)
        {
                System.out.println(obj);
        }
        public static void main(String[] args)
        {
                Map<String ,String> map = new HashMap<String ,String>();
    
                map.put("01","zhangsan1");
                map.put("02","zhangsan2");
                map.put("03","zhangsan3");
                map.put("04","zhangsan4");
                
                //创建Set集合,获取所有键
               Set<String> keySet = map.keySet();
                //迭代器方法,将所有键获取
                Iterator<String> it = keySet.iterator();
                while(it.hasNext())
                {
                        String key = it.next();
                        //通过获取的键,将键对应值取出。
                        String value = map.get(key);
                        sop(key+"........."value);
                }
        }
}

4、entrySet();
        Set<Map.Entry<k,v>> entrySet();将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry。后面的<K,V>是泛型,K表示键的数据类型,V表示值的数据类型。直观的说,map中映射关系的数据类型是Map.Entry,换句话说就是 映射关系是Map.Entry的一个实例对象。得到这个映射关系实例(映射关系是一个对象)后,可以通过getKey()获得映射关系的键,通过getValue()获得映射关系的值:
        注意:public static interface Map.Entry<K,V>    是一个接口。将该接口封闭在Map集合中,叫嵌套类:static interface Map.Entry<K,V>     ,叫映射项(键值对)
        Map.Entry,其实Entry也是一个接口,是Map接口中的一个内部接口。

interface Map
{
        public static interface Entry
        {
                public abstract Object getKey();
                public abstract Object getValue();
        }
}
class HashMap implements Map.Entry
{
        class Haha implements Map.Entry
        {
                public abstract Object getKey()
                {
                }
                public abstract Object getValue()
                {
                }
        }
}

示例:
import java.util.*;
class  MapDemo
{
        public static void sop(Object obj)
        {
                System.out.println(obj);
        }
        public static void main(String[] args)
        {
                Map<String ,String> map = new HashMap<String ,String>();
    
                map.put("01","zhangsan1");
                map.put("02","zhangsan2");
                map.put("03","zhangsan3");
                map.put("04","zhangsan4");
                
                //将map集合中映射关系存放到set集合中
                Set<Map.Entry<String,String>> entrySet = map.entrySet();
                //迭代器方式取出映射关系
                Iterator<Map.Entry<String,String>> it = entrySet.iterator();
                while(it.hasNext())
                {
                        Map.Entry<String,String> me = it .next();
                        //通过数据类型 Map.Entry<K,V>中的方法取出键值
                        String  key = me.getKey();
                        String value = me.getValue();
                }
             
        }
}

练习:学生属性:姓名年龄,注意姓名和年龄相同视为同一个学生,保证学生的唯一性


class Student implements comparable<Student>//实现comparable接口具备自然顺序
{
        private String name;
        private int age;
/*
如果一个类产生很多对象,就有可能存到二叉树中,因此我们需要该类对象具备自然顺序
该类实现comparable接口(表示该类对象具备自然顺序),重写compareTo方法(自然顺序是调用compareTo方法来实现的)以便按照我们自己的要求来决定如何排序。
*/
        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
        }
        Student(String name,int age)
        {
                this.name= name;
                this.age = age;
        }
        public String getName()
        {
                return name;
        }
        public int getAge()
        {
                return age;
        }
/*
HashSet中先判断地址(hashCode()方法获取)是否相同,若地址相同再判断地址值是否相同(equals()方法判断)。
HashSet中判断元素唯一性,用hashCode().    Student对象要存到HashSet中,需要重写hashCode方法,以便于按照我们自己的要求来判断元素唯一,如果不重写,会有默认的hashCode方法,该默认方法返回的是对象地址值,就算有相同的姓名和年龄,因为new的关系,多个对象地址不同,默认对象不同,这不符合我们自己要求。我们要求是年龄姓名相同视为同一个对象。
equals方法的重写,是因为需要按照我们自己的要求来决定两个对象是否相同,这里我们把姓名和年龄都相同的学生视为同一个学生。
*/
        public int hashCode()
        {
                return name.hashCode()+age*34;
        }
        public boolean equals(Object obj)
        {
                if(!(obj.instanceof Student))
                        throw ClassCastException("类型不匹配");
                Student s = (Student)obj;
                return this.name.equals(s.name)&&this.age ==s.age;
        }
}

class MapTest
{
        public static void main(String[] args)
        {
                HashMap<Student,,String> hm = new HashMap<Student,String>();
                hm.put(new Student("lisi1",21),"beijing");
                hm.put(new Student("lisi2",221),"shanghai");
                hm.put(new Student("lis13i",31),"wuhan");
                hm.put(new Student("lisi14",24),"nanjing");
                hm.put(new Student("lisi14",24),"beijing");//重写了hashCode和equals方法,此时beijing替代nanjing,hashmap中依然只有四个元素,若没有重写,那么就不替代了,hashmap中有五个元素了。

                //取出,第一种方式keySet
                Set<Student> s = hm.keySet();
                Iterator<Student> it = s.iterator();
                while(it.hasNext())
                {
                        Student stu = it.next();
                        String addr = hm.get(stu);
                }
                //取出,第二种方式entrySet()
                Set<Map.Entry<Student,String>> entrySet = hm.entrySet();
                Iterator<Map.entry<Student,String>> itl = entrySet.iterator();
                while(itl.hasNext())
                {
                        Map.Entry<Student,String> me = itl.next();
                        Student stu = me.getKey();
                        String addr = me.getValue();
                }
        }
}

 对学生对象的年龄进行升序排序,因为数据是以键值对形式存放的,所以要使用可以排序的Map集合,TreeMap
import java.util.*;
class StuNameComparator  implements Comparator<Student>//自定义比较器按照,姓名排序,此时应该将该类对象传给TreeMap,TreeMap才能知道要调用这个比较器,如果不传该比较器,那么会使用默认比较器。
{
        public int compare(Student s1,Student s2)
        {
                int num = s1.getName().compareTo(s2.getName());
                if(num==0)
                {
                        return new Integer(s1.getAfe()).compareTo(new Integer(s2.getAge()));
                }
                return num
        }
}
class Student implements comparable<Student>
{
        private String name;
        private int 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
        }
        Student(String name,int age)
        {
                this.name= name;
                this.age = age;
        }
        public String getName()
        {
                return name;
        }
        public int getAge()
        {
                return age;
        }
        public int hashCode()
        {
                return name.hashCode()+age*34;
        }
        public boolean equals(Object obj)
        {
                if(!(obj.instanceof Student))
                        throw ClassCastException("类型不匹配");
                Student s = (Student)obj;
                return this.name.equals(s.name)&&this.age ==s.age;
        }
}

class MapTest
{
        public static void main(String[] args)
        {
                TreeMap<Student ,String> tm = new TreeMap<Student,String>(new StuNameComparator());
                tm.put(new Student("lisi1",21),"beijing");
                tm.put(new Student("lisi2",221),"shanghai");
                tm.put(new Student("lis13i",31),"wuhan");
                tm.put(new Student("lisi14",24),"nanjing");
            
                Set<Map.Entry<Student,String>> entryset = tm.entrySet();
                Iterator<Map.Entry<Student,String>> esit = entryset.iterator();
                while(esit.hasNext())
                {
                        Map.Entry<Student,String> me = esit.next();
                        Student s = me.getKey();
                        String addr = me.getValue();
                        sop(s+"..."+addr);
                }
        }
}一般什么时候使用Map?当有一一对应关系时,可以选择Map,因为map中存的就是映射关系。
原创粉丝点击