Map集合

1.概述

生活中经常有一一对应的关系,例如:ip地址和主机名,身份证号与姓名,系统用户名与系统用户对象等等,这种关系可以叫做映射。

Java提供了专门的集合来存放这种对应关系的对象,也就是java.util.Map接口

Map接口下的集合,Collection接口下的集合,存储形式不同。

Map接口的结合都需要指定两个泛型K,V 这两个泛型可以数据类型相同,也可以不同。

  • Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个一个元素的方式存储。

  • Map中的集合,元素是成对出现的。每个元素由键和值两个部分组成,通过键可以找到对应的值。

  • Collection中的集合称之为单列集合,Map中的集合称之为双列集合。

  • 注意: Map中集合不能包含重复的键,值可以重复,每个键只能对应一个值。

    2.Map的常用子类

    通过查看Map接口发现有很多子类,这里我们主要讲常用的HashMap集合、LinkedHashMap集合。

  • HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致,由于要保证键的唯一,不重复,需要重写键的hashCode方法、equals方法。

  • LikedHashMap<K,V>:HashMap的子类LinkedHashMap,存储数据结构采用哈希表+链表的结构,通过链表可以保证元素的存取顺序一致;通过哈希表可以保证键的唯一、不重复,需要重写键的hashCode方法、equals方法。

3.Map中的常用方法

public V put(K key, V value);添加元素到集合,使用put方法如果指定键在集合中不存在,返回null,存在则返回替换前的值,添加重复键时新的键会覆盖老数据,返回老数据的值。

public V remove(Object key);删除键为K的元素,使用remove方法如果指定键在集合中不存在,返回null,存在则返回该键映射的值。

public V get(Object key); 拿到键查找对应的值,返回该键映射的值。

public boolean containsKey(Object key)判断该集合中是否有这个键。

public boolean containsValue(Object value)判断该集合中是否有这个值。

代码演示:

public class Demo01 {
    public static void main(String[] args) {

//        创建Map对象
        HashMap<String,String> map=new HashMap<>();
//        添加元素到集合  map.put(key,value)
        //添加重复键时新的键会覆盖老数据
//        使用put方法如果指定键在集合中不存在,返回null,存在返回替换前的值
        String str = map.put("007", "张飞");
        System.out.println("str = "+str);
        map.put("008","关羽");
        String str1 = map.put("009", "刘备");
        System.out.println("str1 = "+str1);
        String str2 = map.put("009", "赵云");
        System.out.println("str2 = "+str2);
        map.put("010","张飞");
        System.out.println("map = "+map);
//        删除 map.remove(key)
        String remove = map.remove("002");
        System.out.println("remove = "+remove);

        String remove1 = map.remove("007");
        System.out.println("remove1 = "+remove1);

        System.out.println("map = "+map);

//        查看   拿到键查找对应的值
        System.out.println(map.get("008"));

//        判断该集合中是否有这个键
        System.out.println(map.containsKey("009"));

//        判断该集合中是否有这个值
        System.out.println(map.containsValue("张飞"));
    }
}

4.Map集合的遍历

假设对如下Map集合遍历:

 HashMap<Integer,String> hashMap=new HashMap<>();
        hashMap.put(1,"aaa");
        hashMap.put(2,"bbb");
        hashMap.put(3,"ccc");
        hashMap.put(4,"ddd");
        hashMap.put(5,"eee");

方式1:键找值的方式

  • public Set<K> keySet(): 获取map集合中的所有键,存储到set集合中。

步骤:

1.获取Map中所有的键,由于键是唯一的,所以返回到一个set集合中。

2.用增强for遍历键的set集合,得到每一个键.

3.根据键,获取键所对应的值.

代码演示:

Set<Integer> set=hashMap.keySet();//将Map中的键存到Set中
       for (Integer integer : set) {
            System.out.println(integer+" : "+hashMap.get(integer));
        }

方式2:键值对方式

通过集合中的每个键值对(Entry)对象,获取键值 对(Entry)对象中的键与值.

Entry键值对对象:

Map中的键与值是一一对应的,这一对对象在map中称之为一个Entry.Entry将键值对的对应关系封装成了对象,也就是键值对对象,我们可以在遍历map时获取对应的所有键值对对象.

  • public Set<Map.Entry<K,V>> entrySet();获取map集合中的所有键值对对象的集合(Set集合);

获取了Entry对象表示获取了一对键值对,Entry中也提供了获取键和获取值的方法;

  • public K getKey():获取Entry对象中的key.

  • public V getValue:获取Entry对象中的value.

遍历步骤:

  1. 获取Map集合中所有键值对对象,以set集合形式返回.方法: entrySet();

  2. 遍历包含键值对的set集合 得到每一个entry对象.

  3. 通过entry对象,获取entry对象中的键和值.方法:getKey() , getValue();

eg1:

 Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
        for (Map.Entry<Integer, String> entry : entries) {
            System.out.println(entry.getKey()+" : "+entry.getValue());

eg2:

//   遍历方式2.1    使用迭代器  hashMap没有迭代器,先转为键值对的Set集合再使用迭代器方式遍历
            Iterator<Map.Entry<Integer, String>> iterator = hashMap.entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<Integer, String> next = iterator.next();
                System.out.println(next.getKey()+" : "+next.getValue());
            }

5.Map集合练习

需求:

计算一个字符串中每个字符出现的次数.

分析:

  1. 获取一个字符串对象

  2. 创建一个Map集合 思考key , value 分别是什么

  3. 遍历字符串 得到每个字符

  4. 判断map中是否存过这个字符

  5. 如果没有 就是第一次出现 ,存次数为1, 如果有 说明出现过 次数++.

  6. 最终打印结果.

    public class Demo03 {
        public static void main(String[] args) {
            System.out.println("请输入一个字符串");
            String str = new Scanner(System.in).next();
    //            定义一个 每个字符出现字数的方法
            findChar(str);
        }
        private static void findChar(String str) {
    //        1: 创建一个集合  存储字符  以及出现的次数。
            Map<Character, Integer> map = new HashMap<>();
            for (int i = 0; i < str.length(); i++) {
    //        2:  遍历字符串。
                char c = str.charAt(i);
    //        3.  判断该字符是否出现在集合中
                if (!map.containsKey(c)) {//不包含说明没有出现过这个字符 就是第一次出现
                    map.put(c, 1);
                }else {// 包含代表出现过  获取之前的次数然后+1
                    Integer count = map.get(c);
                    map.put(c,++count);
                }
            }
            System.out.println("map = " + map);
        }
    }
    

    6.HashMap存储自定义类型(无序且唯一)

    练习: 每个学生都有自己的姓名,年龄,有对应关系,将学生对象和家庭住址存入到map集合中,学生为键,住址为值.

    注意: 学生姓名和年龄相同视为同一个学生.(所以得重写equals和hashCode方法)这里对学生类的创建不予展示了

    public class Demo04 {
        public static void main(String[] args) {
    //        1.创建一个map集合。
            Map<Student,String> map =new HashMap<>();
    //        2.添加元素
            map.put(new Student("zhang3",22),"哈尔滨");
            map.put(new Student("zhang3",22),"重庆");
            map.put(new Student("zhang4",33),"四川");
            map.put(new Student("zhang5",22),"广东");
    //        3.遍历集合, 键找值的方式。
            Set<Student> students = map.keySet();
            for (Student student : students) {
                String value = map.get(student);
                System.out.println(student+" : "+value);
            }
        }
    }

    7.HashMap综合练习

  7. 设计一个HashMap来存储购物车种的商品, 其中K为商品编号(新增时动态获取),V为商品对象(包含商品名称、价格和数量属性);

  8. 实现功能: a.添加商品到购物车(根据商品编号和商品) b.更新购物车中商品的数量 c.从购物车中移除商品(根据商品编号) d.计算购物车中所有商品的总价 e.打印购物车中所有商品的信息 要求使用java的异常处理机制处理可能出现的问题,如添加重复商品 、移除不存在的商品等。 并测试。

  9. 代码演示(Product类不在此写明):

    public class ShoppingCar {
    
        public Map<String, Product> car;
    
        public ShoppingCar() {
            this.car = new HashMap<>();
        }
    
    //    a.添加商品到购物车(根据商品编号和商品)
    
        public void addProduct(String productId, Product p) throws Exception {
            if (car.containsKey(productId)){
                throw new Exception("商品已经存在,添加异常");
            }else {
                car.put(productId,p);
            }
        }
    //    b.更新购物车中商品的数量
        public void updateProduct(String productId,int newCount) throws Exception {
            if (!car.containsKey(productId)){
                throw new Exception("商品不存在,异常");
            }else {
                car.get(productId).setNum(newCount);//找到对应编号的商品并对商品数量重新赋值
            }
        }
    //    c.从购物车中移除商品(根据商品编号)
        public void remove(String productId) throws Exception {
            if (car.containsKey(productId)){
                car.remove(productId);
            }else {
                throw new Exception("商品不存在,移除异常");
            }
        }
    //    d.计算购物车中所有商品的总价
    
        public void totalPrice ( ){
            double sum=0.0;
            Set<Map.Entry<String, Product>> entries = car.entrySet();
            for (Map.Entry<String, Product> entry : entries) {
                Product value = entry.getValue();
                sum+=value.getPrice()*value.getNum();
            }
            System.out.println("当前购物车商品总结"+sum);
        }
    //    e.打印购物车中所有商品的信息
        public void printProduce(){
            Set<Map.Entry<String, Product>> entries = car.entrySet();
            for (Map.Entry<String, Product> entry : entries) {
                System.out.println("id:"+entry.getKey());
                System.out.println("name:"+entry.getValue().getName());
                System.out.println("price:"+entry.getValue().getPrice());
                System.out.println("num:"+entry.getValue().getNum());
            }
        }
    }
    

    测试类:

    public class Test {
        public static void main(String[] args)  {
    
            Product p1=new Product("可口可乐",3,2);
            Product p2=new Product("乐事薯片",6.9,3);
            Product p3=new Product("豪士面包",3,5);
            ShoppingCar car=new ShoppingCar();
            try {
                car.addProduct("001",new Product("可口可乐",3,2));
                car.addProduct("002",new Product("乐事薯片",6.9,3));
                car.addProduct("003",new Product("豪士面包",3,5));
    
                car.updateProduct("001",6);
    
                car.totalPrice();
    
                car.remove("002");
                car.printProduce();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

  10. 8.LinkedHashMap介绍(有序且唯一)

    HashMap下有一个子类LinkedHashMap,它是链表和哈希表组合的一个数据存储结构.

    public class Demo03 {
        public static void main(String[] args) {
    
    //        1.创建集合对象   有序
            Map<String,String> map=new LinkedHashMap<>();
            map.put("zhang3","777");
            map.put("li4","888");
            map.put("wang5","99");
            map.put("zhang6","333");
    //        2.遍历
            Set<Map.Entry<String, String>> entries = map.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                System.out.println(entry.getKey()+" : "+entry.getValue());
            }
        }
    }
    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值