集合框架map_DAY18

1:map集合(掌握)

    (1)Map集合存储的是键值对元素。键是唯一的,值可以重复。 

    (2)Map和Collection的区别?

             A:Map是双列集合,存储的元素键值对,键唯一,值可以重复。

             B:Collection是单列集合,存储的元素是单一的,List集合可以重复,Set集合元素唯一。

    (3)Map集合的功能

           A:添加功能

                   V put(K key,V value)

          B:删除功能

             remove(K key)

          C:判断功能

             containsKey(K key)

             containsValue(V value)

          D:获取功能

             V  get(K key)

             Set<K>   keySet()

             Collection<V>   values()

             Set<Map.Entry<K,V>>   entrySet()      返回所有键值对对应关系

                   Map.Entry是Map内的一个内部接,包含的主要方法

                            K   getKey()

                            V   getValue()

                               V    setValue(V value)  设置值

            E:长度功能

             int   size()

    (4)Map集合的数据结构问题:

         Map集合的数据结构对键有效,跟值无关。

         它的底层数据结构和Set中讲解的一致。

               如果是哈希表结构,就需要重写hashCode()和equals(),保证存储元素的唯一性。

              如果是二叉树结构,就有两种方式:Comparable,Comparator,保证存储的元素的有序性。 例子程序如下:

mport java.util.Comparator;
import java.util.TreeMap;

/*
 * 使用TreeMap存储<Person,String>
 */
public class Demo7 {

    public static void main(String[] args) {
        //第一种方式:使键的类型实现Comparable接口,完成比较大小的逻辑
        TreeMap<Person, String> map = new TreeMap<>();
        Person p = new Person("唐嫣", 28);
        String s = "貂蝉";
        
        Person p2 = new Person("卢俊义",42);
        String s2 = "玉麒麟";
        
        Person p3 = new Person("2张顺",32);
        String s3 = "浪里白条";
        
        Person p4 = new Person("1花荣",32);
        String s4 = "小李广";
        
        map.put(p, s);
        map.put(p2, s2);
        map.put(p3, s3);
        map.put(p4, s4);
        
        System.out.println(map);
        
        //第二种方式:创建集合对象时给予对应的比较器Comparator
        TreeMap<Person, String> map2 = new TreeMap<>(new Comparator<Person>(){

            @Override
            public int compare(Person o1, Person o2) {
                int result = o1.getName().compareTo(o2.getName());
                if(result==0) {
                    result = o1.getAge()-o2.getAge();
                }
                return result;
            }});
        
        map2.put(p, s);
        map2.put(p2, s2);
        map2.put(p3, s3);
        map2.put(p4, s4);
        
        System.out.println(map2);
    }

}
View Code
public class Person implements Comparable<Person>{

    private String name;
    private int age;
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    
    //先比较年龄,后比较姓名
    @Override
    public int compareTo(Person o) {
        //this:新传进来的对象    o:旧的对象
        int result = this.age-o.age;
        if(result==0) {
            result = this.name.compareTo(o.name);
        }
        return result;
    }
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
}
View Code

  

  (5)Map的遍历方式

         假设有一个HashMap集合,存储的键和值都是String类型。名称叫hm。

         A:根据键找值(掌握)

             a:获取所有键的集合

             b:遍历键的集合,获取到每一个键

             c:根据键找值

             代码体现:

             Set<String> set = hm.keySet();

             for(String key : set) {

                String value = hm.get(key);

                System.out.println(key+"---"+value);

             }

 

         B:根据键值对对象找键和值(理解)

             a:获取所有键值对对象的集合

             b:遍历键值对对象的集合,获取到每一个键值对对象

             c:根据键值对对象获取键和值

             代码体现:

             Set<Map.Entry<String,String>> set = hm.entrySet();

             for(Map.Entry<String,String> me : set) {

                String key  = me.getKey();

                String value = me.getValue();

                System.out.println(key+"---"+value);

             }

    (6)案例:

         A:统计一个字符串中每个字符出现的次数  

import java.util.Set;
import java.util.TreeMap;

/**
 * “aabcbdeeeeedbddcc”,获取字符串中每一个字母出现的次数。要求结果:a(2)b(3)c(3)d(4)e(5)
 * 思路:字符串中的字符和数字存到treemap集合里,然后遍历输出
 */
public class MapTest1 {
    public static void main(String[] args) {
        // 定义一个字符串(可以改进为键盘录入)
        String content ="aababcabcdabcde";
        // 定义一个TreeMap集合
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();

        //把字符串转换为字符数组
        char[] chs = content.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);
    }
}
View Code

     B:Map集合的嵌套存储和遍历

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

/*
 * List集合内元素为Map集合
 */
public class Test {

    public static void main(String[] args) {
        //List嵌套List
        //创建集合对象
        ArrayList<ArrayList<String>> arrayList = new ArrayList<ArrayList<String>>();
        //创建元素对象
        ArrayList<String> list = new ArrayList<String>();
        list.add("吕布");
        list.add("赵云");
        list.add("典韦");
        list.add("关羽");
        list.add("马超");
        
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("高俅");
        list2.add("高衙内");
        list2.add("蔡京");
        list2.add("西门大官人");
        
        //将集合元素放入集合对象
        arrayList.add(list);
        arrayList.add(list2);
        
        System.out.println(arrayList);
        
        //List嵌套Map
        //创建集合对象
        ArrayList<HashMap<String, Person>> arrayList2 = new ArrayList<HashMap<String, Person>>();
        //创建元素对象
        HashMap<String, Person> hashMap = new HashMap<String, Person>();
        hashMap.put("五虎上将之一", new Person("关羽",38));
        hashMap.put("五虎上将之二", new Person("张飞",34));
        hashMap.put("五虎上将之三", new Person("赵云",32));
        hashMap.put("五虎上将之四", new Person("马超",30));
        hashMap.put("五虎上将之五", new Person("黄忠",60));
        
        HashMap<String, Person> hashMap2 = new HashMap<String, Person>();
        hashMap2.put("行者", new Person("武松",28));
        hashMap2.put("神行太保", new Person("戴宗",34));
        hashMap2.put("入云龙", new Person("公孙胜",32));
        hashMap2.put("九纹龙", new Person("史进",30));
        hashMap2.put("拼命三郎", new Person("石秀",29));
        //将集合元素添加到集合中
        arrayList2.add(hashMap);
        arrayList2.add(hashMap2);

        //迭代外层的ArrayList,里边的每个元素均为Map对象
        for (HashMap<String, Person> myMap : arrayList2) {
            //HashMap<String, Person> myMap
            //返回该map的所有key的Set集合
            Set<String> keySet = myMap.keySet();
            
            for (String key : keySet) {//迭代key的集合,获取每一个key
                Person value = myMap.get(key);  //通过键获取值
                //拼写字符串,完成对每个map中元素的打印
                System.out.println(key+":"+value.getName()+" "+value.getAge());
            }
        }
    }

}
View Code
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/*
 * 使用Map嵌套List
 */
public class Test2 {

    public static void main(String[] args) {
        //创建map集合
        Map<String, ArrayList<Person>> map = new HashMap<String, ArrayList<Person>>();
        
        //创建集合元素
        String class1 = "0315基础班";
        ArrayList<Person> arrayList = new ArrayList<Person>();
        arrayList.add(new Person("唐嫣",28));
        arrayList.add(new Person("龙哥",23));
        arrayList.add(new Person("小龙女",16));
        arrayList.add(new Person("涛哥",31));
        
        String class2 = "0426就业班";
        ArrayList<Person> arrayList2 = new ArrayList<Person>();
        arrayList2.add(new Person("唐嫣",28));
        arrayList2.add(new Person("高圆圆",32));
        arrayList2.add(new Person("baby",26));
        arrayList2.add(new Person("熊黛林",32));
        
        //将集合元素添加到集合中
        map.put(class1, arrayList);
        map.put(class2, arrayList2);
        
        //遍历map集合
        Set<Entry<String,ArrayList<Person>>> entrySet = map.entrySet();
        
        Iterator<Entry<String, ArrayList<Person>>> iterator = entrySet.iterator();
        
        while (iterator.hasNext()) {
            Map.Entry<java.lang.String, java.util.ArrayList<cn.itcast2.Person>> entry = (Map.Entry<java.lang.String, java.util.ArrayList<cn.itcast2.Person>>) iterator
                    .next();
            String key = entry.getKey();
            ArrayList<Person> listValue = entry.getValue();
            System.out.println(key);
            Iterator<Person> iterator2 = listValue.iterator();
            while (iterator2.hasNext()) {
                Person person = (Person) iterator2.next();
                System.out.println(person);
            }
        }
    }

}
View Code
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*
 * Map嵌套Map
 */
public class Test3 {

    public static void main(String[] args) {

        Map<String, Map<String, Person>> map = new HashMap<String, Map<String,Person>>();
        
         Map<String, Person> innerMap = new HashMap<String, Person>();
         innerMap.put("师傅", new Person("唐三藏",34));
         innerMap.put("大师兄", new Person("孙悟空",500));
         innerMap.put("二师兄", new Person("朱悟能",800));
         innerMap.put("三师弟", new Person("沙悟净",600));
         
         Map<String, Person> innerMap2 = new HashMap<String, Person>();
         innerMap2.put("顽石", new Person("贾宝玉",14));
         innerMap2.put("十二金钗之一", new Person("薛宝钗",19));
         innerMap2.put("十二金钗之二", new Person("王熙凤",28));
         
         map.put("西游记", innerMap);
         map.put("红楼梦", innerMap2);
         
         Set<String> keySet = map.keySet();
         
         for (String key : keySet) {
             Map<String, Person> value = map.get(key);
             System.out.println(key);
             Set<String> keySet2 = value.keySet();
             for (String innerKey : keySet2) {
                 Person innerValuePerson = value.get(innerKey);
                 System.out.println(innerKey+":"+innerValuePerson);
            }
        }
    }

}
View Code

    (7)Map集合的体系

         Map

             |--HashMap

                    |--LinkedHashMap

             |--Hashtable

             |--TreeMap

 

         A:HashMap和Hashtable的区别?

      HashMap键无序,不可重复,不安全,速度快,键和值都可以存放空值。

      Hashtable键无序,不可重复,安全,速度慢,键和值都不可以存放空值。

         B:LinkedHashMap的键的特点?

      键有序,不可重复。

2:集合总结(什么时候使用谁?)

     是否键值对:

           是:Map

          是否排序:

                是:TreeMap

                否:HashMap

               不知道,HashMap

         否:Collection

             是否唯一:

                  是:Set

                       是否排序:

                         是:TreeSet

                         否:HashSet

                        不知道,HashSet

                 否:List

                    增删多:LinkedList

                    查询多:ArrayList

                    不知道,ArrayList

        不知道,用ArrayList

 

3:集合体系总结

    集合:

       |--Collection

           |--List

                |--ArrayList

                    底层数据结构是数组,查询快,增删慢。

                    线程不安全,效率高。

                |--Vector

                    底层数据结构是数组,查询快,增删慢。

                    线程安全,效率低。

                |--LinkedList

                    底层数据结构是链表,查询慢,增删快。

                    线程不安全,效率高。

           |--Set

                |--HashSet

                    底层数据结构是哈希表。

                    如何保证唯一性?

                         依赖hashCode()和equals()

                    顺序:

                      先判断hashCode()值是否相同:

                             是:继续走equals(),看返回值

                                  true:元素重复。不添加

                                  false:元素不重复。添加

                             否:直接添加

                       |--LinkedHashSet

                       底层数据结构是链表和哈希表。

                           由链表保证有序(存储和取出一致)。

                           由哈希表保证元素唯一。

                      |--TreeSet

                    底层数据结构是二叉树。

                    如果保证唯一性?

                          根据返回值是否是0。

                    如何排序:

                         自然排序:Comparable

                         比较器排序:Comparator

        |--Map

             |--HashMap

                  |--LinkedHashMap

             |--Hashtable

             |--TreeMap

 

附:例子

1、Map嵌套Map的例子

import java.util.HashMap;
import java.util.Set;

/**
 * 使用集合进行以下分类:
     北京总部
          -JAVAEE班:5个
          -JAVASE班:8个
 上海分校
          -JAVAEE:4个
          -JAVASE:7个

 */
public class Map3 {
    public static void main(String[] args) {

        //创建HashMap集合
        HashMap<String,HashMap<String,String>> hashMap=new HashMap<String,HashMap<String,String>>();

        //创建元素
        HashMap<String,String> innerHashMap1=new HashMap<String,String>();
        innerHashMap1.put("JavaEE班","5个");
        innerHashMap1.put("JavaSE班","8个");

        HashMap<String,String> innerHashMap2=new HashMap<String,String>();
        innerHashMap2.put("JavaEE班","4个");
        innerHashMap2.put("JavaSE班","7个");

        //添加元素
        hashMap.put("北京总部",innerHashMap1);
        hashMap.put("上海分校",innerHashMap2);

        //遍历输出
        Set<String> keySet=hashMap.keySet(); //外层key集合
        for(String key:keySet){
            System.out.println(key); //输出外层key
            HashMap<String,String> innerHashMap= hashMap.get(key);//获取外层key对应的Value值
            Set<String> inKeySet=innerHashMap.keySet();//内层key集合
            for(String innerkey:inKeySet){
                String innerValue=innerHashMap.get(innerkey);
                System.out.println("   "+innerkey+":"+innerValue);//输出内层key与内层Vakue
            }

        }
    }

}
View Code

2、模拟地主洗牌发牌

方法一:

import java.util.ArrayList;
import java.util.Collections;

/*
 * 模拟斗地主洗牌发牌版本1
 */
public class Test5 {

    public static void main(String[] args) {

        /*准备:
         * 花色:♠♥♦♣  ArrayList
         * 数字:3,4,5,6,7,8,9,10,J,Q,K,A,2  ArrayList
         * 大小王:☺☻
         * 得有一副54张的牌 ArrayList
         * 洗牌:
         *     打乱这副牌的顺序
         * 发牌:
         *     将54张牌分发到4个list手中,前三个17张,最后一个3张
         *     player    ArrayList
         *     player2    ArrayList
         *     player3    ArrayList
         *  dipai     ArrayList
         */

        //准备花色
        ArrayList<String> color = new ArrayList<String>();
        color.add("♠");
        color.add("♥");
        color.add("♦");
        color.add("♣");

        //准备数字
        ArrayList<String> number = new ArrayList<String>();
        Collections.addAll(number, "3","4","5","6","7","8","9","10","J","Q","K","A","2");

        //准备一副新牌
        ArrayList<String> cards = new ArrayList<String>();

        for (String thisColor : color) {
            for (String thisNumber : number) {
                cards.add(thisColor+thisNumber);
            }
        }
        //加入大小王
        cards.add("大☻");
        cards.add("小☺");

        System.out.println(cards);
        //洗牌
        Collections.shuffle(cards);
        System.out.println(cards);

        //发牌

        //准备四个list作为3个玩家和底牌
        ArrayList<String> player = new ArrayList<String>();
        ArrayList<String> player2 = new ArrayList<String>();
        ArrayList<String> player3 = new ArrayList<String>();
        ArrayList<String> dipai = new ArrayList<String>();

        //遍历这副洗好的牌,遍历过程中,将牌发到三个玩家和dipai手中
        for (int i = 0; i < cards.size(); i++) {

            if(i>=51) {//分配底牌
                dipai.add(cards.get(i));
            } else {
                if(i%3==0) {
                    player.add(cards.get(i));
                }else if(i%3==1) {
                    player2.add(cards.get(i));
                }else {
                    player3.add(cards.get(i));
                }
            }
        }

        //看牌
        System.out.println(player);
        System.out.println(player2);
        System.out.println(player3);
        System.out.println(dipai);
    }

}
View Code

方法二:

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;

/*
 * 斗地主洗牌发牌版本2:每个人手中的元素是有顺序的。
 */
public class Test5 {

         /*准备:
         * 花色:♠♥♦♣  ArrayList
         * 数字:3,4,5,6,7,8,9,10,J,Q,K,A,2  ArrayList
         * 大小王:☺☻ 
         * !!!!!!!!定义一个map集合:用来将数字与每一张牌进行对应
         * 得有一副54张的牌 ArrayList里边为1-54的数  
         * 洗牌:
         *     打乱这副牌的顺序
         * 发牌:
         *     将54张牌分发到4个TreeSet手中,前三个17张,最后一个3张
         *     player    TreeSet
         *     player2   TreeSet
         *     player3   TreeSet
         *  dipai     TreeSet
         */
    
    public static void main(String[] args) {

        //准备花色
        ArrayList<String> color = new ArrayList<String>();
        color.add("♠");
        color.add("♥");
        color.add("♦");
        color.add("♣");
        
        //准备数字
        ArrayList<String> number = new ArrayList<String>();
        Collections.addAll(number, "3","4","5","6","7","8","9","10","J","Q","K","A","2");
        
        //定义一个map集合:用来将数字与每一张牌进行对应
        HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
        
        int index = 1;
        for (String thisNumber : number) {
            for (String thisColor : color) {
                hashMap.put(index++, thisNumber+thisColor);
            }
        }
        
        //加入大小王
        hashMap.put(index++, "小☺");
        hashMap.put(index++, "大☻");
        
        System.out.println(hashMap);
        
        //得有一副54张的牌 ArrayList里边为1-54的数的新牌
        ArrayList<Integer> cards = new ArrayList<Integer>();
        
        for (int i = 1; i <= 54; i++) {
            cards.add(i);
        }
        
        //洗牌
        Collections.shuffle(cards);
        System.out.println(cards);
        
        //创建三个玩家和底牌
        TreeSet<Integer> player = new TreeSet<Integer>();
        TreeSet<Integer> player2 = new TreeSet<Integer>();
        TreeSet<Integer> player3 = new TreeSet<Integer>();
        TreeSet<Integer> dipai = new TreeSet<Integer>();
        
        //遍历这副洗好的牌,遍历过程中,将牌发到三个玩家和dipai手中
        for (int i = 0; i < cards.size(); i++) {
            if(i>=51) {
                dipai.add(cards.get(i));
            } else {
                if(i%3==0) {
                    player.add(cards.get(i));
                }else if(i%3==1) {
                    player2.add(cards.get(i));
                }else {
                    player3.add(cards.get(i));
                }
            }
        }
        
        //看牌
        for (Integer key : dipai) {
            System.out.print(hashMap.get(key)+", ");
        }
        System.out.println();
        for (Integer key : player) {
            System.out.print(hashMap.get(key)+", ");
        }
        System.out.println();
        for (Integer key : player2) {
            System.out.print(hashMap.get(key)+", ");
        }
        System.out.println();
        for (Integer key : player3) {
            System.out.print(hashMap.get(key)+", ");
        }
    }

}
View Code

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
set user_write_ugi:afs://kunpeng.afs.baidu.com:9902=lbs-huiyan,lbs-huiyan; insert overwrite directory 'afs://kunpeng.afs.baidu.com:9902/user/lbs-huiyan/warehouse/huiyan.db/map_huiyan_mall_userpic/event_type=monthly/event_day={FORWARD_MONTH_END}' using CSV options('compression'='GZIP', sep='\t', escapeQuotes=false) SELECT source.mall_id AS mall_id, COUNT(1) AS total FROM (SELECT cuid, mall_id, mall_name, date_type FROM huiyan_ns.huiyan.map_huiyan_mall_basic_source WHERE event_day = '{FORWARD_MONTH_END}') source JOIN (SELECT cuid, * FROM huiyan_ns.huiyan.map_huiyan_parse_userpic WHERE event_day >= '{FORWARD_7_DAY}' AND event_day <= '{FORWARD_MONTH_END}') userpic ON userpic.cuid = source.cuid GROUP BY source.mall_id, source.mall_name, source.date_type; alter table huiyan_ns.huiyan.map_huiyan_mall_userpic_raw add partition(event_day='{FORWARD_MONTH_END}') location 'afs://kunpeng.afs.baidu.com:9902/user/lbs-huiyan/warehouse/huiyan.db/map_huiyan_mall_flow_userpic_raw/event_day={FORWARD_MONTH_END}'; set user_write_ugi:afs://kunpeng.afs.baidu.com:9902=lbs-huiyan,lbs-huiyan; insert overwrite directory 'afs://kunpeng.afs.baidu.com:9902/user/lbs-huiyan/warehouse/huiyan.db/map_huiyan_mall_userpic/event_type=monthly/event_day={FORWARD_MONTH_END}' using CSV options('compression'='GZIP', sep='\t', escapeQuotes=false) SELECT TRANSFORM(mall_id, ) USING 'python3 mall_userpic_streaming.py' AS(mall_id, ) FROM huiyan_ns.huiyan.map_huiyan_mall_userpic_raw WHERE event_day = '{FORWARD_MONTH_END}' ; alter table huiyan_ns.huiyan.map_huiyan_mall_userpic add partition(event_type='monthly', event_day='{FORWARD_MONTH_END}') location 'afs://kunpeng.afs.baidu.com:9902/user/lbs-huiyan/warehouse/huiyan.db/map_huiyan_mall_userpic/event_type=monthly/event_day=${FORWARD_MONTH_END}'; 将这两段代码合并为一段
07-22

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值