[Java][华为云Java编程创造营][学习笔记][第三阶段][06_Java集合][03_Map接口及子类]

举报
John2021 发表于 2021/12/21 20:32:47 2021/12/21
【摘要】 3,Java集合Map接口及子类 3.1,Map接口和简介Map集合中存储的元素是一组键值对象,是key与value的一个映射。Map提供了一个更通用的元素存储方法,每个键映射一个值。Map集合中一个key对应一个value,不能存在相同的key值,value值可以相同。key和value之间存在单向一对一关系,即通过指定的key总能找到唯一确定的value。Map接口的常用实现类有Has...

3,Java集合Map接口及子类

3.1,Map接口和简介

  • Map集合中存储的元素是一组键值对象,是key与value的一个映射。

  • Map提供了一个更通用的元素存储方法,每个键映射一个值。

  • Map集合中一个key对应一个value,不能存在相同的key值,value值可以相同。

  • key和value之间存在单向一对一关系,即通过指定的key总能找到唯一确定的value。

  • Map接口的常用实现类有HashMap,Hashtable,LinkedHashMap,TreeMap,ConcurrentHashMap。

  • Map集合的功能特点:

    1. 添加功能
      • V put(K key,V value):添加元素。如果是相同的键再次添加,这时候体现的是替换功能,即只存储最后一个数据。
    2. 删除功能
      • void clear();移除所有的键值对元素。
      • V remove(Object key);根据键删除键值对元素,并把值返回。
    3. 判断功能
      • boolean containsKey(Object key);判断集合是否包含指定的键。
      • boolean containsValue(Object value);判断集合是否包含指定的值。
      • boolean isEmpty();判断集合是否为空。
    4. 获取功能
      • Set<Map.Entry<K,V>> entrySet():返回集合的键值对对象。
      • V get(Object key):根据键获取值。
      • Set<K> keySet():获取集合中的所有键的集合。
  • Map集合和Collection集合区别:

    1. Map集合存储元素是成对出现的,也就是键值对出现,而且键是不可以重复的。
    2. Collection集合存储元素是一个个存储的,也就是单一存储的。

3.2,HashMap子类和API

  • HashMap根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因此具有很快的访问速度,但遍历顺序却是不确定的。
  • HashMap由数组+链表组成的。
  • HashMap最多只允许一条记录的键为null,允许多条记录的值为null。
  • HashMap非线程安全,即同一时刻可以有多个线程同时操作HashMap,可能会导致数据的不一致。
  • 如果需要满足线程安全,可以用Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。
import java.util.HashMap;

public class Test
{
    public static void main(String[] args)
    {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("demo", 1);
        //Value的类型,得到map中key相应的value的值
        System.out.println(map.get("1"));//null
        //key区分大小写
        System.out.println(map.get("DEMO"));//null
        System.out.println(map.get("demo"));//1
        //boolean判断map是否为空
        System.out.println(map.isEmpty());//false
        //boolean判断map中是否存在key
        System.out.println(map.containsKey("DEMO"));//false
        //boolean判断map中是否存在value
        System.out.println(map.containsValue(1));//true
        //Integer删除key值下的value
        System.out.println(map.remove("1"));//null
        //Collection<Integer>显示所有的value值
        System.out.println(map.values());//[1]
        //int显示map里的值的数量
        System.out.println(map.size());//1
        //SET<String> 显示map所有的key
        System.out.println(map.keySet());//[demo]
        //SET<map<String,Integer>> 显示所有的key和value
        System.out.println(map.entrySet());//[demo=1]
    }
}
  • HashMap的线程非安全
import java.util.HashMap;
import java.util.concurrent.CountDownLatch;

class MapThread extends Thread
{
    HashMap<Integer, Integer> maps;
    CountDownLatch cd;

    public MapThread(HashMap<Integer, Integer> maps, CountDownLatch cd)
    {
        this.maps = maps;
        this.cd = cd;
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 100; i++)
        {
            this.maps.put(i, i);
        }
        cd.countDown();
    }
}

public class Test
{
    public static void testHashMap()
    {
        HashMap<Integer, Integer> maps = new HashMap<>();
        CountDownLatch cd = new CountDownLatch(100);
        for (int i = 0; i < 100; i++)
        {
            new MapThread(maps, cd).start();
        }
        try
        {
            cd.await();
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        System.out.println("测试HashMap大小:" + maps.size());
    }

    public static void main(String[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            testHashMap();
        }
    }
}

3.3,LinkedHashMap子类和API

  • LinkedHashMap是链表和哈希表组合的一个数据存储结构。
  • LinkedHashMap存储数据是有序的。
  • LinkedHashMap是线程不安全的。
  • LinkedHashMap元素存放的有序机制:
import java.util.LinkedHashMap;

public class Test
{
    public static void main(String[] args)
    {
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        map.put("key4", "444");
        map.put("key3", "333");
        map.put("key2", "222");
        map.put("key1", "111");
        for (String key : map.keySet())
        {
            System.out.println(key + ":" + map.get(key));
        }
    }
    /*
    * 输出结果
    *   key4:444
        key3:333
        key2:222
        key1:111
    * */
}

3.4,ConcurrentHashMap子类和API

  • ConcurrentHashMap底层采用数组+链表+红黑树的存储结构。
  • ConcurrentHashMap的key和value都不能为空。
  • ConcurrentHashMap线程是安全的,支持高并发操作。
  • ConcurrentHashMap采用分段锁技术有效提升并发访问效率。
  • ConcurrentHashMap是线程安全且高效的案例:
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

class ConcurrentHashMapThread extends Thread
{
    ConcurrentHashMap<Integer, Integer> maps;
    CountDownLatch cd;

    public ConcurrentHashMapThread(ConcurrentHashMap<Integer, Integer> maps, CountDownLatch cd)
    {
        this.maps = maps;
        this.cd = cd;
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 100; i++)
        {
            this.maps.put(i, i);
        }
        cd.countDown();
    }
}

public class Test
{
    public static void testConMap()
    {
        ConcurrentHashMap<Integer, Integer> maps = new ConcurrentHashMap<>();
        CountDownLatch cd = new CountDownLatch(100);
        for (int i = 0; i < 100; i++)
        {
            new ConcurrentHashMapThread(maps, cd).start();
        }
        try
        {
            cd.await();
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        System.out.println("测试ConcurrentHashMap:" + maps.size());
    }

    public static void main(String[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            testConMap();
        }
    }
}

3.5,Hashtable子类和API

  • Hashtable是线程同步安全的。
  • Hashtable的键和值不能为null。
import java.util.Hashtable;

public class Test
{
    public static void main(String[] args)
    {
        Hashtable hashtable = new Hashtable();
        hashtable.put(null, null);
        /*
         * 输出结果
         * Exception in thread "main" java.lang.NullPointerException
         * */
    }
}
  • Hashtable是线程安全的案例:
import java.util.Hashtable;
import java.util.concurrent.CountDownLatch;

class TableThread extends Thread
{
    Hashtable<Integer, Integer> maps;
    CountDownLatch cd;

    public TableThread(Hashtable<Integer, Integer> maps, CountDownLatch cd)
    {
        this.cd = cd;
        this.maps = maps;
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 100; i++)
        {
            this.maps.put(i, i);
        }
        cd.countDown();
    }
}

public class Test
{
    public static void testtableMap()
    {
        Hashtable<Integer, Integer> maps = new Hashtable<>();
        CountDownLatch cd = new CountDownLatch(100);
        for (int i = 0; i < 100; i++)
        {
            new TableThread(maps, cd).start();
        }
        try
        {
            cd.await();
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        System.out.println("测试Hashtable的大小为:" + maps.size());
    }

    public static void main(String[] args)
    {

    }
}

3.6,Map的五种遍历方式

  • 1,通过Map.Entry(String,Integer)获取,然后使用entry.getKey()获取到键,通过entry.getValue()获取到值。
import java.util.HashMap;
import java.util.Map;

public class Test1
{
    public static void main(String[] args)
    {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("hello", 1);
        map1.put("world", 2);
        map1.put("java", 3);
        for (Map.Entry<String, Integer> entry : map1.entrySet())
        {
            System.out.println("键 key : " + entry.getKey() + " 值value:" + entry.getValue());
        }
    }
    /*
    * 输出结果
    *   键 key : world 值value:2
        键 key : java 值value:3
        键 key : hello 值value:1
    * */
}
  • 2,通过Map的keySet()获取key,通过key,获取value
import java.util.HashMap;
import java.util.Map;

public class Test2
{
    public static void main(String[] args)
    {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("hello", 1);
        map1.put("world", 2);
        map1.put("java", 3);
        for (String key : map1.keySet())
        {
            Integer value = map1.get(key);
            System.out.println("key: " + key + ", value:" + value);
        }
    }
    /*
    * 输出结果
    *   key: world, value:2
        key: java, value:3
        key: hello, value:1
    * */
}
  • 3,应用新特性foreach循环:
import java.util.HashMap;
import java.util.Map;

public class Test3
{
    public static void main(String[] args)
    {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("hello", 1);
        map1.put("world", 2);
        map1.put("java", 3);
        for (String s1 : map1.keySet())
        {
            System.out.println("键key: " + s1 + ",值为:" + map1.get(s1));
        }
    }
    /*
    * 输出结果
    *   键key: world,值为:2
        键key: java,值为:3
        键key: hello,值为:1
    * */
}

  • 4,Iterator遍历获取,然后获取到Map.Entry<String,String>,再得到getKey()和getValue()
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Test4
{
    public static void main(String[] args)
    {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("hello", 1);
        map1.put("world", 2);
        map1.put("java", 3);
        Iterator<Map.Entry<String, Integer>> it = map1.entrySet().iterator();
        while (it.hasNext())
        {
            Map.Entry<String, Integer> entry = it.next();
            System.out.println("键key:" + entry.getKey() + ",value:" + entry.getValue());
        }
    }
    /*
    * 输出结果 
    *   键key:world,value:2
        键key:java,value:3
        键key:hello,value:1
    * */
}
  • 5,通过Map的values()方法获取值,局限在于不能获取键
import java.util.HashMap;
import java.util.Map;

public class Test5
{
    public static void main(String[] args)
    {
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("hello", 1);
        map1.put("world", 2);
        map1.put("java", 3);
        for (Integer val : map1.values())
        {
            System.out.println("值为:" + val);
        }
    }
    /*
    * 输出结果
    *   值为:2
        值为:3
        值为:1
    * */
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。