当前位置:

首页 > 编程开发 > Java集合注意事项有哪些

Java集合注意事项有哪些

一、Map接口1、注意事项(实用)Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value(双列元素)Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中Map中的key不允许重复,原因和HashSet一样Map中的value可以重复Map的key可以为null,value也可以为null。但是,注意key为null只能存在一个,而value为null可以存在多个常用String类来作为Map的keykey和value之间存在单向一对一关

本文目录

    Java集合注意事项有哪些

    一、Map 接口

    1、注意事项(实用)

    • Map与Collection并列存在。用于保存具有映射关系的数据 : Key-Value(双列元素)

    • Map 中的key 和 value 可以是任何引用类型的数据,会封装到 HashMap$Node
      对象中

    • Map 中的 key 不允许重复,原因和HashSet一样

    • Map 中的 value 可以重复

    • Map的 key 可以为null, value 也可以为null 。但是,注意 key为 null 只能存在一个,而value 为 null 可以存在多个

    • 常用String 类来作为 Map 的key

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

    2、Key-Value 示意图

    Java集合注意事项有哪些

    3、Map接口常用方法

    Map map = new HashMap(); 
    
    map.put("第一", "节点1");
    map.put("第二", "节点2");
    map.put("第三", "节点3");
    map.put("第四", "节点4");

    (1)remove : 根据键删除映射关系

    map.remove("第二");
     

    (2)get :根据键获取值

    Object val = map.get("第三");
     

    (3)size : 获取元素个数

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

    (4)isEmpty :  判断个数是否为  0

    System.out.println( map.isEmpty() ); //False

    (5)clear :  清除  key-value

    map.clear();

    (6)containsKey :  查找键是否存在

    System.out.println(map.containsKey("第四")); //true

    4、Map的遍历方式

    (1)四种遍历方式

    • containsKey : 查找键是否存在

    • keySet : 获取所有的键

    • entrySet : 获取所有关系K-V

    • values : 获取所有的值

    Map map = new HashMap();

    (2)keySet 遍历方式

    //先取出 所有的 Key , 通过 Key 取出对应的 Value
    Set keyset = map.keySet();
    
    
    //(1)第一种方式: 增强 for循环
    for (Object key : keyset) {
    
        System.out.println(key + "-" + map.get(key));
    
    }
    
    
    //(2)第二种方式:迭代器
    Iterator iterator = keyset.iterator();
    while (iterator.hasNext()) {
    
        Object key = iterator.next();
        System.out.println(key + "-" + map.get(key));
    
    }
     

    (3)values 遍历方式

    //把所有的 values 取出
    Collection values = map.values();
    
    
    //注意:这里可以使用所有的 Collections 使用的遍历方法
    
    //(1)取出所有的 value 使用增强 for 循环
    for (Object value : values) {
    
        System.out.println(value);
    
    }
    
    
    //(2)取出所有的 value 使用迭代器
    Iterator iterator2 = values.iterator();
    while (iterator2.hasNext()) {
    
        Object value = iterator2.next();
    
        System.out.println(value);
    
    }
       

    (4)entrySet 遍历方式

    //通过 EntrySet 来获取 key-value
    Set entrySet = map.entrySet();  // EntrySet>
    
    
    //(1)使用 EntrySet 的 增强 for循环遍历方式
    for (Object entry : entrySet) {
    
        //将 entry 转成 Map.Entry
        Map.Entry m = (Map.Entry) entry;
    
        System.out.println(m.getKey() + "-" + m.getValue());
    
    }
    
    
    //(2)使用 EntrySet 的迭代器遍历方式
    Iterator iterator3 = entrySet.iterator();
    while (iterator3.hasNext()) {
        //HashMap$Node -实现-> Map.Entry (getKey,getValue)
        Object entry = iterator3.next();
    
        //向下转型 Map.Entry
        Map.Entry m = (Map.Entry) entry;
    
        System.out.println(m.getKey() + "-" + m.getValue());
    }
     

    二、HashMap 类

    1、注意事项

    • Map接口的常用实现类:HashMap、Hashtable 和 Properties

    • HashMap是 Map 接口使用频率最高的实现类(重点掌握)

    • HashMap 是以key-value 一对的方式来存储数据(HashMap$Node类型)

    • key 不能重复, 但是value值可以重复,二者都允许使用null键。

    • 如果添加相同的key,则会覆盖原来的key-value,等同于修改(key不会替换,value会替换)

    • 与HashSet一样, 不保证映射的顺序, 因为底层是以Hash表的方式来存储的(jdk8的HashMap 底层数组+链表+红黑树)

    • HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有
      synchronized 关键字

    2、底层机制

    1. HashMap底层维护了Node类型的数组table,默认为null

    2. 当创建对象时, 将加载因子(loadfactor)初始化为0.75

    3. 当添加key-value时,通过key的哈希值得到在table的素引。 然后判断该索引处是否有元素,如果没有元素直接添加。 如果该索引处有元素, 继续判断该元素的key和准备加入的key是否相等, 如果相等,则直接替换value; 如果不相等需要判断是树结构还是链表结构,做出相应处理。 如果添加时发现容量不够, 则需要扩容。

    4. 第1次添加, 则需要扩容table容量为16, 临界值(threshold)为12 (16*0.75)

    5. 以后再扩容, 则需要扩容table容量为原来的2倍(32). 临界值为原来的2倍,即24(32*0.75),依次类推

    6. 在Java8中,如果一条链表的元素个数超过 TREEIFY_THRESHOLD(默认是8),并且 table的大小 >= MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)

    3、底层原理图

    Java集合注意事项有哪些


    三、HashTable 类

    1、基本介绍

    • 存放的元素是键值对:即Key-Value

    • HashTable 的键和值都不能为null

    • HashTable 的使用方法基本上和HashMap一样

    • HashTable 是线程安全的,HashMap 是线程不安全

    • Hashtable 和 HashMap 的比较:    

    Java集合注意事项有哪些

    2、底层结构示意图

    Java集合注意事项有哪些

    3、HashTable 常用方法

    Map map = new HashTable(); 
    
    map.put("第一", "节点1");
    map.put("第二", "节点2");
    map.put("第三", "节点3");
    map.put("第四", "节点4");

    (1)remove : 根据键删除映射关系

    map.remove("第二");
     

    (2)get :根据键获取值

    Object val = map.get("第三");

    (3)size : 获取元素个数

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

    (4)isEmpty :  判断个数是否为  0

    System.out.println( map.isEmpty() ); //False

    (5)clear :  清除  key-value

    map.clear();

    (6)containsKey :  查找键是否存在

    System.out.println(map.containsKey("第四")); //true

    四、Properties 类

    1、基本介绍

    • Properties 类继承自HashTable类并且实现了Map接口,也是使用一种键值对的形
      式来保存数据。(可以通过 key-value 存放数据,当然 key 和 value 也不能为 null)

    • 它的使用特点和Hashtable类似

    • Properties 还可以用于从xx.properties文件中,加载数据到Properties类对象,并进行读取和修改(在IO流中会详细介绍)

    2、常用方法

    Properties properties = new Properties();

    (1)put 方法

    properties.put(null, "abc");//抛出 空指针异常
    properties.put("abc", null); //抛出 空指针异常
    
    properties.put("lic", 100);
    properties.put("lic", 88);//如果有相同的 key , value 被替换

    (2)get 方法

    System.out.println(properties.get("lic"));

    (3)remove 方法  

    properties.remove("lic");

    五、Collections 工具类

    1、基本介绍

    • Collections 是一个操作Set. List 和 Map等集合的工具类

    • Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作排序

    2、排序操作(均为static方法)

    方法作用
    reverse(List)反转 List 中元素的顺序
    shuffle(List)对 List集合元素进行随机排序
    sort(List)根据元素的自然顺序对指定List集合元素按升序排序
    sort(List,Comparator)根据指定的Comparator 产生的顺序对 List集合元素进行排序
    swap(List, int i, int j)将指定list 集合中的 i 处元素和 j 处元素进行交换
    List list = new ArrayList(); 
    
    list.add("第一个"); 
    list.add("第二个"); 
    list.add("第三个");

    (1)reverse(List):  反转  List  中元素的顺序

    Collections.reverse(list);

    (2)shuffle(List):对 List 集合元素进行随机排序

    for (int i = 0; i < 5; i++) {
    
        Collections.shuffle(list);
    
        System.out.println("list=" + list);
    
    }

    (3)sort(List):  根据元素的自然顺序对指定   List   集合元素按升序排序   

    Collections.sort(list);

    (4)sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序   

    //匿名内部类
    Collections.sort(list, new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
    
        return ((String) o2).length() - ((String) o1).length();
    
        }
    
    });

    (5)swap(List,int, int): 将指定  list  集合中的  i  处元素和  j  处元素进行交换     

    Collections.swap(list, 0, 1);

    .......................................................

    3、查找、替换操作

    方法作用
    Object max(Collection)根据元素的自然顺序,返回给定集合中的最大元素
    Object max(Collection, Comparator)根据 Comparator 指定的顺序,返回给定集合中的最大元素
    Object min(Collection)根据元素的自然顺序,返回给定集合中的最小元素
    Object min(Collection, Comparator)根据 Comparator 指定的顺序,返回给定集合中的最小元素
    int frequency(Collection, Object)返回指定集合中指定元素的出现的次数
    void copy(List dest,List src)将src中的内容复制到dest中
    boolean replaceAll(List list, Object oldVal, Object newVal)使用新值替换 List对象的所有旧值

    (1)Object max(Collection):  根据元素的自然顺序,返回给定集合中的最大元素

    System.out.println("自然顺序最大元素=" + Collections.max(list))

    (2)Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素

    //匿名内部类
    Object maxObject = Collections.max(list, new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
    
        return ((String)o1).length() - ((String)o2).length();
    
        }
    
    })

    (3)int frequency(Collection,Object):   返回指定集合中指定元素的出现次数   

    System.out.println("第一个 出现的次数=" + Collections.frequency(list, "第一个"));

    (4)void copy(List dest,List src):将 src 中的内容复制到 dest 中  

    ArrayList dest = new ArrayList();
    
    //为了完成一个完整拷贝,我们需要先给 dest 赋值,大小和 list.size()一样
    for(int i = 0; i < list.size(); i++) {
    
        dest.add("");
    
    }
    
    //拷贝
    Collections.copy(dest, list);

    (5)boolean replaceAll(List list,Object oldVal,Object newVal): 使用新值替换  List  对象的所有旧值     

    //如果 list 中,有 “第一个” 就替换成 “0”
    Collections.replaceAll(list, "第一个", "0");

    六、总结 (必背)

    1、开发中如何选择集合来使用?

    (1)第一步:先判断存储的类型:是一组对象?还是一组键值对?


    (2)一组对象: Collection接口
           List允许重复:
                   增删多 : LinkedList [底层维护了一个双向链表]
                    改查多 : ArrayList 底层维护Object类型的可变数组]


           Set不允许重复:
                   无序 : HashSet {底层是HashMap,维护了一个哈希表即(数组+链表+红黑树)}
                    排序 : TreeSet
                    插入和取出顺序一致 :  LinkedHashSet , 维护数组+双向链表


    (3)一组键值对: Map 接口
                   键无序 : HashMap [底层是:哈希表 jdk7:数组+链表,jdk8:数组+链表+红黑树]
                    键排序 : TreeMap
                    键插入和取出顺序一致 : LinkedHashMap

                   读取文件 :Properties

    2、HashSet 和 TreeSet分别如何实现去重的?

    HashSet 的去重机制 : hashCode() + equals(),底层先通过存入对象,进行运算得到一个hash值,通过hash值得到对应的索引,如果发现table索引所在的位置没有数据, 就直接存放;如果有数据,就进行equals比较[遍历比较]。如果比较后不相同,就加入;否则就不加入。

    TreeSet 的去重机制 : 如果你传入了一个Comparator 匿名对象,就使用实现的compare去重,如果方法返回0,就认为是相同的元素或数据, 就不添加;如果你没有传入一个Comparator 匿名对象,则以你添加的对象实现的Compareable接口的compareTo去重。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。