Java集合之HashMap和TreeMap

一、初识Map接口

Map集合和Collection集合的区别:

Map集合是有Key和Value的,Collection集合是只有Value。

Collection集合底层也是有Key和Value,只是隐藏起来。

Map集合的特点:

一个映射不能包含重复的键,每个键最多只能映射到一个值。

要是当Map集合利用put方法添加相同的键时,从前的键对应的值将会被覆盖

二、HashMap集合

1、特点:

  • 双列集合,存入的是(Key,Value),主要针对键的操作;
  • 底层的实现利用Hash算法
  • 集合输出的时候是无序的
  • add()方法:当加相同的键时,从前的键对应的值将会被覆盖,并返回被覆盖的值。
    是因为:HashMap还是运用了hash算法,重写他的equals和hascode方法

2、常用API:

方法摘要
 voidclear()
          从此映射中移除所有映射关系(可选操作)。
 booleancontainsKey(Object key)
          如果此映射包含指定键的映射关系,则返回 true。
 booleancontainsValue(Object value)
          如果此映射将一个或多个键映射到指定值,则返回 true。
 Set<Map.Entry<K,V>>entrySet()
          返回此映射中包含的映射关系的 Set 视图。
 booleanequals(Object o)
          比较指定的对象与此映射是否相等。
 Vget(Object key)
          返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
 inthashCode()
          返回此映射的哈希码值。
 booleanisEmpty()
          如果此映射未包含键-值映射关系,则返回 true。
 Set<K>keySet()
          返回此映射中包含的键的 Set 视图。
 Vput(K key, V value)
          将指定的值与此映射中的指定键关联(可选操作)。
 voidputAll(Map<? extends K,? extends V> m)
          从指定映射中将所有映射关系复制到此映射中(可选操作)。
 Vremove(Object key)
          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
 intsize()
          返回此映射中的键-值映射关系数。
 Collection<V>values()
          返回此映射中包含的值的 Collection 视图。

3、Map集合的遍历:

①:利用迭代器和增强for循环遍历

Map<String,Integer> map = new HashMap<>();
        map.put("张三",12);
        map.put("李四",13);
        map.put("王五",14);

        /*利用迭代器遍历*/
       /* Set<String> keySet = map.keySet();          //获取所有键的集合
        Iterator<String> it = keySet.iterator();    //获取迭代器
        while (it.hasNext()){
            String key = it.next();                 //获取每一个键
            Integer value = map.get(key);           //根据键获取值
            System.out.println(key+"="+value);
        }*/
        /*增强for循环遍历*/
        for(String key : map.keySet()){
            System.out.println(key + "="+ map.get(key));
        }

② 对Map.Entry对象进行遍历

将键值对封装为Map.entry对象,再用对象的getKey和getValue方法遍历
 for(Map.Entry<String,Integer> en : map.entrySet()){//获取键的集合
            System.out.println(en.getKey()+"="+en.getValue());//
        }

三、 TreeMap

特点:可以对集合实现排序,重写Compareable接口

比较键的:重写Compareable接口对象进行比较,比较是的键。 或者传入比较器

注:具体实现可以参考TreeSet集合。

四、补充   LinkedHashMap 、Hashtable

①:LinkedHashMap特点:底层是链表,可以实现顺序存储。

②:Hashtable:

面试题:
* 共同点:底层都是哈希算法,都是双列集合
* 区别:1、HashMap是线程不安全的,效率高,JDK1.2
*       Hashtable是线程安全的,效率度,JDK1.0的版本
*       2、HashMap可以存储null键和null值
*       Hashtable不可以存储null键和null值、会影响程序的进一步执行

五、运用Map集合做的一些小demo

①:从键盘输入 统计字符串中每个字符出现的次数

/*
* 从键盘输入 统计字符串中每个字符出现的次数
*  1、创建Scanner对象,接受输入的字符串
*  2、将字符串转换为字符数组
*  3、创建双列集合,存储字符和字符出现的次数
*  4、遍历字符数组,获取每个字符并将字符存储在双列集合中
*  5、存储过程中进行判断,如果集合无该字符,存储该字符,并将值设置为1,如如果存在则在原来的值基础上加1
*  6、遍历集合
* */
public class TotalCharNumberTest01 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        char []arr = line.toCharArray();

        HashMap<Character,Integer> hm = new HashMap<>();
        for(Character c : arr){
          /*  if(!hm.containsValue(c)){
                hm.put(c,1);
            }else {
                hm.put(c,hm.get(c)+1);
            }*/
          hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c)+1 );
        }
        for(Map.Entry<Character,Integer> en : hm.entrySet()){
            System.out.println(en.getKey()+"="+en.getValue());
        }
        for(Character key : hm.keySet()){//获取键的集合
            System.out.println(key+"="+hm.get(key));//获取值得集合
        }
    }
}

②:利用map集合模拟斗地主发牌,洗牌,看牌,抢地主的效果

/*
* 需求:模拟斗地主游戏
* 分析:
* 1、生成一副扑克牌
* 2、洗牌
* 3、发牌
* 4、看牌:留三张底牌
* 5、抢地主
            具体细节:
            * 大小关系:黑桃大于红心,红心大于梅花,梅花大于方块
            *
            * 思路:第一步:利用双列集合(HashMap)将牌的的大小从小到大原始排序,并标上序号:键存储的是索引,值存储的是牌
            * 例如:0---黑桃3  1---红心3 2---梅花3  3---方块3
            * 第二部:利用ArrayList存储牌的索引  洗牌:对索引洗牌,再根据索引获取值
            * 第三部:创建三个TreeSet集合,将各个人手中的牌通过对索引排序从而对卡牌进行排序
            *
*/
public class PokerDemo {
    public static void main(String[] args) {
        /*
        1、创建一副牌
        */
        String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        String[] color = {"黑桃","红心","梅花","方块"};

        //创建一个双列集合,存储索引和牌
        HashMap<Integer,String> hm = new HashMap<>();
        //创建一个ArrayList集合存取索引,对索引操作,从而对牌进行操作
        // 例如:0---黑桃3  1---红心3 2---梅花3  3---方块3
        ArrayList<Integer> list = new ArrayList<>();
        int index = 0;
        //创建一副牌、并将索引存入ArrayList集合
        for(String s1 : num){
            for(String s2 : color){
                list.add(index);
                hm.put(index,s2.concat(s1));
                index++;
            }
        }
        //再加入大王、小王
        hm.put(index,"小王");
        list.add(index);
        index++;
        hm.put(index,"大王");
        list.add(index);
       // System.out.print(list);
        /*
        * 2、洗牌
        * */
        Collections.shuffle(list);

        /*
        * 3、发牌
        * 定义三个TreeSet集合,模拟玩家;在定义一个TreeSet集合,模拟剩下的底牌
        * */
        TreeSet<Integer> hss = new TreeSet<>();
        TreeSet<Integer> wys = new TreeSet<>();
        TreeSet<Integer> xsc = new TreeSet<>();
        TreeSet<Integer> dipai = new TreeSet<>();
        for(int i=0;i<list.size();i++){
            if(i>=list.size()-3){
                dipai.add(list.get(i));
            }else if(i % 3 == 0){
                hss.add(list.get(i));
            }else if(i % 3 == 1){
                wys.add(list.get(i));
            }else {
                xsc.add(list.get(i));
            }
        }
        /*
        * 4、看牌
        * 因为定义了三个集合模拟三个人,我们可以定义一个看牌的方法,来进行每个人的看牌
        * */
        lookPoke(hm,hss,"黄ss");
        lookPoke(hm,wys,"王ys");
        lookPoke(hm,xsc,"熊sc");
        lookPoke(hm,dipai,"底牌是");
    }
    //看牌的方法:参数有传入定义索引对应的牌号集合HashMap;每个人TreeSet集合;姓名String
    public static void lookPoke(HashMap<Integer,String> hm,TreeSet<Integer> ts,String name){
        System.out.print(name+"的牌是:");
        for (Integer i:ts){
            System.out.print(hm.get(i)+"  ");
        }
        System.out.println();
    }
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值