首页 > 编程语言 >【JavaSE】集合Collection{List(ArrayList, LinkedList), Set(TreeSet, HashSet, LinkedHashSet)} + Map(HashMa

【JavaSE】集合Collection{List(ArrayList, LinkedList), Set(TreeSet, HashSet, LinkedHashSet)} + Map(HashMa

时间:2023-12-09 17:23:06浏览次数:44  
标签:Map 遍历 LinkedHashSet List Set compareTo 集合 排序 TreeSet

集合

单列集合:Collection接口

单列集合:一次添加一个元素;

如果集合中添加的是类,要重写equals方法,否则比较的是地址,无法正常删除内容相同的元素。

单列集合通用遍历方式

1. 迭代器遍历

2. 增强for循环遍历

  • 增强for循环底层逻辑还是迭代器,字节码文件反编译为java会发现还是迭代器遍历。

3. forEach方法

  • 底层仍然是迭代器遍历
  • forEach需要实现一个函数式接口,因此使用匿名函数类/lambda表达式都可
forEach方法举例
        Collection<String> c = new ArrayList<>();

        c.add("abc");
        c.add("def");
        c.add("abc");
        // 匿名函数类
        c.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        // lambda表达式
        c.forEach(s -> System.out.println(s));

List接口

  • 存取有序,有索引,可以存储重复数据

List独有API

并发修改异常

List集合的遍历方式

其中ListIterator迭代器中独有的逆序遍历Previous方法前必须通过正序遍历让cursor指到集合最后才可以正常逆序遍历成功

逆序遍历Previous方法
        List<String> c = new ArrayList<>();
        c.add("abc");
        c.add("def");
        c.add("xyz");

        ListIterator<String> it = c.listIterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        System.out.println("------------------------");
        while(it.hasPrevious()) {
            System.out.println(it.previous());
        }

ArrayList【List中用得最多】

底层数据结构是数组
ArrayList详解

LinkedList

底层数据结构是双链表

注意:LinkedList的get(index)方法复杂度是O(n)
因为LinkedList是List体系中的集合,继承了List接口,因此也有get(index)方法可以根据索引获取元素。但是底层实现逻辑仍然是基于双向链表,判断索引靠链表头还是链表尾,然后再从头/尾进行遍历查询,因此复杂度还是O(n)


Set接口

存取无序,无索引,不可以存储重复数据

TreeSet

底层数据结构是红黑树,可以对集合中的元素进行排序操作
特点:排序,去重

自然排序
  1. 类实现Comparable接口
  2. 重写compareTo方法
  3. 根据方法返回值组织排序规则
compareTo方法返回值:

0: 元素相同,不存
1: 大的右边走
-1: 小的左边走

当调用add方法,向TreeSet添加元素时,内部会自动调用compareTo方法,根据这个方法的返回值决定节点怎么走

public class Xxx implements Comparable<Xxx>{

    @Override
    public int compareTo(Student o) {
        return this.xxx - o.xxx;    // 按xxx正序排列
        return o.xxx - this.xxx;    // 按xxx降序排列
    }
}
[自然排序]多属性排序Student类
public class Student implements Comparable<Student>{

    @Override
    public int compareTo(Student o) {
        // 以年龄做主要排序条件,姓名做次要排序条件
        if(this.age != o.age) return this.age - o.age;
        return this.name.compareTo(o.name);
    }

    private String name;
    private int age;
}
比较器排序
  1. 在TreeSet构造方法中传入Comparable接口的实现类对象
  2. 重写compareTo方法
  3. 根据方法返回值组织排序规则

比较器排序优先级高于自然排序
如果需要修改Java已经写好的类的自然排序规则(String,Integer等),就用比较器排序覆盖

[比较器排序]多属性排序Student类
        // 匿名内部类实现
        TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.getAge() != o2.getAge()) return o2.getAge() - o1.getAge();
                return o2.getName().compareTo(o1.getName());
            }
        });

        // lambda表达式实现
        TreeSet<Student> set = new TreeSet<>((o1, o2) -> {
            if(o1.getAge() != o2.getAge()) return o2.getAge() - o1.getAge();
            return o2.getName().compareTo(o1.getName());
        });

HashSet【Set中用得最多】

底层数据结构:哈希表,且依赖于HashMap,[哈希表存储原理及源码分析]

特点:去重——可以保证元素的唯一性
去重原理:需要重写自定义类的equals方法hashCode方法

  • 如何避免哈希冲突?
    重写hashCode方法时把类的成员属性都考虑到,以尽量避免哈希冲突

LinkedHashSet

底层数据结构:哈希表,另外每个元素又额外多了一个双链表的机制记录存储的顺序

特点:有序,去重,无索引

单列集合使用场景

单列集合工具类:Collections


双列集合:Map接口

  • 双列集合底层的数据结构,都是针对键有效,跟值没有关系

Map常见API

Map集合遍历方式

1. 键找值

2. 通过键值对对象获取键和值

  1. 通过forEach方法遍历

TreeMap

底层数据结构:红黑树
特点:键排序(实现Comparable接口,重写compareTo方法)

HashMap

底层数据结构:哈希表
特点:键唯一(重写hashCode和equals方法)

LinkedHashMap

底层数据结构:哈希表+双向链表
特点:键唯一,且可以保证存取顺序

标签:Map,遍历,LinkedHashSet,List,Set,compareTo,集合,排序,TreeSet
From: https://www.cnblogs.com/Eve7Xu/p/17877048.html

相关文章

  • 【JavaSE】数据结构-哈希表(HashSet/HashMap底层哈希表详解,源码分析)
    哈希表结构JDK8版本之前:数组+链表JDK8版本及之后:数组+链表+红黑树哈希表HashMapput()方法的添加流程创建HashSet集合时,构造方法中自动创建HashMap集合;HashMap空参构造方法会创建一个默认长度为16,默认加载因子为0.75的数组,数组名为table(tips:实际上,HashSet对象创建后,第......
  • maven 配置(cmd 黑窗口执行 mvn 时默认的 settings 文件和 idea maven 相关配置)
    写在前面:本文章用于记录博主平时遇到的问题,步骤略粗糙,目的在于记录一边后续博主自己查找,如果能帮助到其他人更好。文章中用到的链接均为自行引入,侵删,谢谢(2I2Rc*@JY8)问题说明:在一次使用cmdmvn命令通过下载到本地的第三方jar包(ojdbc8.jar)创建本地maven仓库的文件结构时发现......
  • 常见场景题-Redis的bitmap如何实现签到功能?
    Redis的bitmap实现签到系统?答:主要讲一下Redis原生的bitmap的使用方法,以及如何使用bitmap来实现签到功能先来看一下如何使用redisbitmap的原生命令实现签到功能:签到我们先来设计key:userid:yyyyMM,那么假如usera在2023年10月3日和2023年10月4日签到的话,使用以下命令:se......
  • Solution Set #3
    紧急更新。上OI-transit上加训构造,感觉OI-transit是很好的找题网站。25loj6736. 「2020集训队论文」最小连通块应该加个部分分:DFS序是\(1\simn\)。你考虑这个部分分怎么做。一种做法是剥叶子,每次找到一个叶子的父亲。存在判断一个点是否是另一个点祖先的方法:询问\(......
  • mapping映射属性
    索引库就类似数据库表,mapping映射就类似表的结构。mapping是对索引库中文档的约束,常见的mapping属性包括:type:字段数据类型,常见的简单类型有:字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)数值:long、integer、short、byte、double、float、布尔:boolean......
  • 实体类生成resultMap工具类
    将实体类转为resultMap实体类:importlombok.Data;importjava.sql.Timestamp;importjava.util.Date;@DatapublicclassTestVo{privateStringmetric;privateintvalue;privateTimestamptimeStamp;privateStringvalueType;privateStri......
  • 【SQLServer2019备份恢复】查询本身有问题、未正确设置 "ResultSet" 属性、未正确设置
    在SQLServer2019AlwaysOn节点备份策略失败:备份数据库(完整)(8502-HIS-SQLAG\HISAG)备份数据库所在的位置:本地服务器连接兼容性级别为70(SQLServer7.0版)的数据库将被跳过。数据库:所有用户数据库类型:完整追加现有任务开始:2023-12-08T14:10:07。任务结束:20......
  • nerdctl run -d 报"failed to call cni.Setup: plugin type=\"bridge\" failed (ad
    背景:执行 nerdctl run-d --namenginx-p8080:80nginx时,报如下错误FATA[0000]failedtocreateshimtask:OCIruntimecreatefailed:runccreatefailed:unabletostartcontainerprocess:errorduringcontainerinit:errorrunninghook#0:errorrunningh......
  • ComplexUpset包画upset图
    需要的数据格式:其中1、0用于表示该类别是否存在这类数据,也可以用TRUE跟FALSE来代替  upset(data_use,unique(colnames(data_use)),name="genres",#底部的标签width_ratio=0.01,#左侧图形的宽度mode='inclusive_intersection', #该包提供四种模......
  • 当创建statefulset资源后,k8s组件如何协作
    本文分享自华为云社区《当创建StatefulSet后,k8s会发生什么?》,作者:可以交个朋友。一、StatefulSet介绍StatefulSet是用来管理有状态应用的工作负载对象,StatefulSet管理基于相同容器规约的一组Pod,使用持久标识符为工作负载Pod提供持久存储。和Deployment类似,也属于副本控制器,......