集合-及其各种特征详解

集合

  • 概念:是提供一种存储空间 可变 的存储模型,存储的数据容量可以发生改变。(也就是集合容量不固定)

  • 集合关系图

绿色的代表接口,蓝色的代表接口的实现类

单列集合

Collection(接口)

  • 概述:单列集合的顶层接口,表示一组对象,这些对象也称为Collection的元素,不提供此接口的任何直接实现。

  • 常用方法:

    方法作用
    boolean add(E e)添加元素
    boolean remove(Object obj)从集合中移除指定的元素
    void clear()清空集合中的元素
    boolean contains(Object obj)判断集合中是否存在指定的元素
    boolean isEmpty()判断集合是否为空
    int size()集合的长度,也就是集合中元素的个数
  • 使用方法

    import java.util.ArrayList;
    import java.util.Collection;
    public class Test{
        // 遍历集合
        public static void show(Collection co){
            for(Object c : co){
                System.out.println(c);
            }
        }
        public static void main(String args[]){
            // 1、创建集合对象,Collection 是接口,所以创建对象只能用其子类实现类
            Collection c = new ArrayList();
            // 2、添加元素
            c.add(1);
            c.add("张三");
            c.add(true);
            // 3、遍历集合
            show(c);
            // 4、移除指定元素
            c.remove(1);
            // 5、遍历集合
            show(c);
            // 6、清空集合中元素
            c.clear();
            // 7、判断集合中是否存在指定元素
            boolean flag;
            flag = c.contains("张三");
            System.out.println(flag);
            // 8、判断集合是否为空
            flag = c.isEmpty();
            System.out.println(flag);
            // 9、得到集合元素个数
            int num = c.size();
            System.out.println(num);
        }
    }
    

    注意:我们可以看到,我们向集合中 添加了 整型 1 字符串 张三 布尔型 true ,所以集合是可以存储不同数据类型的容器,而数组是存储相同数据类型的容器


注意:接下来的集合都用泛型进行限定,如果不理解泛型,可以去参考下这篇文章:泛型-限定存储数据类型


List

  • 概述:List 集合是一个有序集合。用户可以精确控制列表中的每个元素的插入位置,用户也可以通过整数索引访问元素,并搜索列表中的元素。列表中通常允许重复的元素。List 接口是继承其父类Collection 接口的。

  • List 集合特点:

    • 有序:存储和取出的元素顺序一致
    • 可重复:存储的元素可以重复
  • List 的两个实现类

    ArrayList底层结构是数组查询快,增删慢
    LinkedList底层结构是链表查询慢,增删快
  • 集合的遍历参考这篇文章:集合的三种遍历方式


ArrayList
  • 特有方法(特指其父类 Collection 没有的那些):

    方法作用
    void add(int index , E element)在集合指定位置插入指定的元素
    E remove(int index)删除指定索引处的元素,返回被删除的元素
    E set(int index , E element)修改指定索引处的元素,返回被修改的元素
    E get(int index)返回指定索引处的元素
  • 使用方法

    import java.util.ArrayList;
    import java.util.List;
    public class Test{
        public static void main(String[] args) {
            // 1、创建集合,使用泛型限定集合存储数据类型
            List<String> list = new ArrayList<String>();
            // 2、指定位置添加元素
            list.add(0,"王五");
            list.add(1,"张三");
            // 3、返回指定索引处的元素
            String s;
            s = list.get(1);
            System.out.println("修改前:" + s);
            // 4、修改指定索引处元素
            String s1 = list.set(1, "李四");
            s = list.get(1);
            System.out.println("被修改的元素是:" + s1);
            System.out.println("修改后:" + s);
            // 5、删除指定索引元素,并返回被删除元素
            String s2 = list.remove(1);
            System.out.println("被删除的元素是:" + s2);
            // 6、集合中元素个数
            System.out.println("集合中元素个数:" + list.size());
        }
    }
    


LinkedList
  • 特有方法

    方法作用
    void addFirst(E e)在该列表开头插入指定的元素
    void addLast(E e)将指定元素追加到此列表的末尾
    E getFirst()返回此列表中的第一个元素
    E getLast()返回此列表中的最后一个元素
    E removeFirst()从此列表中删除并返回第一个元素
    E removeLast()从此列表中删除并返回最后一个元素
  • 使用方法

    import java.util.LinkedList;
    public class Test6 {
        public static void main(String[] args) {
            // 1、创建集合,使用泛型限定集合存储数据类型
            LinkedList<String> list = new LinkedList<String>();
            // 2、在列表开头插入元素
            list.addFirst("张三");
            list.add("李四");
            list.add("王五");
            // 4、在列表尾部插入元素
            list.addLast("牛六");
            // 5、返回列表第一个元素
            System.out.println("集合第一个元素:" + list.getFirst());
            // 6、返回列表最后一个元素
            System.out.println("集合最后一个元素:" + list.getLast());
            // 7、删除并返回列表第一个元素
            System.out.println("被删除的元素是:" + list.removeFirst());
            // 8、删除并返回列表最后一个元素
            System.out.println("被删除的元素是:" + list.removeLast());
            // 9、遍历集合
            System.out.print("集合中还有的元素是:");
            for (String s : list) {
                System.out.print(s + " ");
            }
        }
    }
    


Set

  • 概述:不包含重复元素的集合,没有带索引的方法,所以不能使用普通 for 循环遍历

  • 特点:

    • 对集合的迭代顺序不做任何保证(无序)
  • Set 集合的三个实现类

    HashSet底层是哈希表
    TreeSet底层是树
    LinkedHashSet底层是 哈希表和链表

HashSet
  • 概述:底层数据结构是 哈希表(数组 + 链表)

  • 特点:

    • HashSet 集合存储元素,要保证元素的唯一性【需要重写 hashCode() 和 equals() 方法】
    import java.util.HashSet;
    import java.util.Objects;
    class Pig{
        private int age;
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pig pig = (Pig) o;
            return age == pig.age;
        }
        @Override
        public int hashCode() {
            return Objects.hash(age);
        }
    }
    public class Test7 {
        public static void main(String[] args) {
            // 1、创建集合
            HashSet<Pig> hs = new HashSet<Pig>();
            // 2、添加元素(添加重复元素)
            Pig p1 = new Pig();
            Pig p2 = new Pig();
            hs.add(p1);
            hs.add(p1);
            hs.add(p2);
    
            // 3、遍历元素
            for (Pig h : hs) {
                System.out.println(h.hashCode());
            }
        }
    }
    

    可以,注销 hashCode() 和 equals() 方法,看下!


LinkedHashSet
  • 概述:哈希表和链表实现的 Set 接口,具有可预测的迭代次序

  • 特点:

    • 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
    • 由哈希表保证元素的唯一性
    public class Test{
        public static void main(String[] args) {
            // 1、创建集合对象
            LinkedHashSet<String> lhs = new LinkedHashSet<String>();
            // 2、添加元素
            lhs.add("张三");
            lhs.add("王五");
            lhs.add("张三");
            lhs.add("李四");
            // 3、遍历集合
            for (String lh : lhs) {
                System.out.print(lh + " ");
            }
        }
    }
    

    最终运行结果:张三 王五 李四

    可以看到,元素有序,并且元素唯一


TreeSet
  • 概述:底层是树的Set集合,按照一定的规则进行排序,具体排序取决于构造方法

  • 特点:

    • 元素有序:这里的顺序不是存储和取出的顺序
    • 元素唯一:Set集合重写 hashCode() 和 equals() 保持元素唯一
  • 两种排序规则:

    • 自然排序
    • 比较器排序
  • 构造方法:

    方法作用
    TreeSet()根据元素的自然排序进行排序
    TreeSet(Comparator comparator)根据指定的比较器进行排序

自然排序
  • 比较对象时候,该对象类要实现 Comparable 接口

  • 该对象类重写 compareTo(E e)方法(规则如下)

    • 返回 0 ,不比较
    • 返回 1(正数),升序输出
    • 返回 -1(负数),降序输出
  • 例子1:逆序向集合存储元素,遍历集合?

    注意:String 已经实现了 Comparable 接口,重写了 compareTo() 方法

  • 例子2:按照年龄输出,年龄相同,按照姓名字母排序(升序)?

    • this 代表当前类,s 代表的是已经在集合中的类
    import java.util.TreeSet;
    
    // 自然排序
    class Student implements Comparable<Student>{
    
        private int age;
        private String name;
    
        public Student(int age , String name){
            this.age = age;
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    
        @Override
        public int compareTo(Student s) {
            int num1 = this.age - s.age;
            // 年龄相同,按照姓名排序
            int num2 = (num1 == 0) ? this.name.compareTo(s.name) : num1;
            return num2;
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            // 1、创建集合对象
            TreeSet<Student> ts = new TreeSet<Student>();
            // 2、添加元素
            ts.add(new Student(7,"xiaoHeng"));
            ts.add(new Student(6,"xiaoBai"));
            ts.add(new Student(8,"xiaoLi"));
            ts.add(new Student(7,"abc"));
            // 3、遍历元素
            for (Student t : ts) {
                System.out.println(t);
            }
        }
    }
    


比较器排序
  • 概述:带参构造方法,使用的是比较器排序对元素进行排序

  • 比较器排序,就是让集合构造方法接收 Comparator 的实现类对象。重写compareTo(T s1, T s2)(匿名内部类的方式实现

  • 注意:

    • 重写方法时,一定要注意排序规则,按照要求的主要次要条件来写(否则有的不能实现)
    • 次要条件一定要满足所有要求
  • 例子1:按照字符串的长度进行排序,从小到大?

    import java.util.Comparator;
    import java.util.TreeSet;
    
    public class Test {
        public static void main(String[] args) {
            // 1、创建集合对象,使用比较器排序
            TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
                @Override
                public int compare(String s1, String s2) {
                    int num = s1.length() - s2.length();
                    return num;
                }
            });
            // 2、添加元素
            ts.add("abc");
            ts.add("abcd");
            ts.add("ab");
            ts.add("a");
            // 3、遍历集合
            for (String t : ts) {
                System.out.print(t + " ");
            }
        }
    }
    

    运行结果:a ab abc abcd

  • 例子2:首先按照年龄进行降序排序,再按姓名升序排序,再按照姓名长度进行升序排序?

    import java.util.Comparator;
    import java.util.TreeSet;
    
    class Pig{
        private int age;
        private String name;
    
        public Pig(int age, String name) {
            this.age = age;
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public String getName() {
            return name;
        }
    
        @Override
        public String toString() {
            return "Pig{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    public class Test2 {
        public static void main(String[] args) {
            // 1、创建集合对象,使用比较器排序
            TreeSet<Pig> ts = new TreeSet<>(new Comparator<Pig>() {
                @Override
                public int compare(Pig s1, Pig s2) {
                    int num1 = s2.getAge() - s1.getAge();
                    int num2 = (num1 == 0) ? s1.getName().compareTo(s2.getName()) : num1;
                    int num3 = (num2 == 0) ? s1.getName().length() - s2.getName().length() : num2;
                    return num3;
                }
            });
            // 2、添加元素
            ts.add(new Pig(5,"abc"));
            ts.add(new Pig(6,"efg"));
            ts.add(new Pig(7,"hij"));
            ts.add(new Pig(5,"bcde"));
            ts.add(new Pig(5,"bcd"));
            // 3、遍历集合
            for (Pig t : ts) {
                System.out.println(t);
            }
        }
    }
    

    运行结果:

    Pig{age=7, name=‘hij’}
    Pig{age=6, name=‘efg’}
    Pig{age=5, name=‘abc’}
    Pig{age=5, name=‘bcd’}
    Pig{age=5, name=‘bcde’}


Map

  • 概述:Map 集合是一个 键值对 集合,将键映射到值的对象,不能包含重复的键,每个键可以映射到最多一个值

    • Map<K,V> K:键的类型,V:值的类型
  • 特点:

    • 键唯一,值可重复
    • 键对应唯一的值,一个值可对应多个键
    • 当键第二次出现时,会将之前的值覆盖掉
  • 常用方法

    方法作用
    V put(K key , V value)添加元素
    V remove(Object key)根据键删除键值对元素(当集合中没有此键的时候返回 null)
    void clear()移除所有的键值对元素(慎用)
    boolean containsKey(Object key)判断集合是否包含指定的键
    boolean containsValue(Object value)判断集合是否包含指定的值
    boolean isEmpty()判断集合是否为空
    int size()集合的长度,集合中键值对的个数
    V get(Object key)根据键获取值(当集合中没有此键的时候返回 null)
    Set keySet()获取所有键的集合(set无法使用普通 for 循环)
    Collection values()获取所有值的集合
    Set<Map.Entry<K,V>> entrySet()获取所有键值对对象的集合
  • 使用方法

    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    public class Test3 {
        // 遍历方法一
        public static void show(Map<Integer,String> map){
            // 1、获取所有键的集合
            Set<Integer> keySet = map.keySet();
            // 2、根据键获取值
            for (Integer key : keySet) {
                // 根据键获取值
                String s = map.get(key);
                System.out.println(key + " --- " + s);
            }
        }
        // 遍历方法二
        public static void print(Map<Integer,String> map){
            // 1、获取所有键值对的集合
            Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
            // 2、遍历
            for (Map.Entry<Integer, String> es : entrySet) {
                System.out.println(es.getKey() + " --- " + es.getValue());
            }
        }
        public static void main(String[] args) {
            // 1、创建集合对象
            Map<Integer,String> m = new HashMap<Integer, String>();
            // 2、添加元素
            m.put(1,"张三");
            m.put(2,"李四");
            m.put(3,"王五");
            show(m);
            // 3、根据键 删除 键值对,没有此键 返回 null
            m.remove(1);
            print(m);
            // 4、判断集合是否包含指定的键、值
            System.out.println(m.containsKey(1));
            System.out.println(m.containsValue("李四"));
        }
    }
    

    运行结果:

    1 — 张三
    2 — 李四
    3 — 王五
    2 — 李四
    3 — 王五
    false
    true


HashMap 和 TreeMap
  • TreeMap<K,V> : 对应 TreeSet 两种排序,可参考 自然排序 和 无参排序

哈希值

  • 概述:是 JDK 根据对象的地址 或者 字符串 或者 数字 算出来的 int 类型的数值。

  • Object 类中有一个方法可以获取对象的哈希值

    方法作用
    public int hashCode()返回对象的哈希值
  • 特点:

    • 默认情况下,不同对象的哈希值是不相同的(Object)

    • 通过方法重写,可以实现不同对象的哈希值是相同的(重写 hashCode() 方法)

    • String 字符串重写了 hashCode 方法,所以不同内容的哈希值相同

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/296070.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SSH 密钥身份验证和管理

安全外壳协议&#xff08;Security Shell Protocol&#xff09;是一种应用于计算机网络的安全通信协议&#xff0c;其提供的服务可用于保护网络上的连接和数据传输安全性&#xff0c;其核心思想是为网络上的两台计算机之间搭建一个安全的外壳&#xff0c;以保护数据传输的安全性…

企业微信开发:自建应用:接收消息(企业内部服务器)/回调配置

概述 在企业微信的自建应用中&#xff0c;用户触发了某些行为&#xff08;发送消息、进行菜单操作或者外部联系人变更等&#xff09;&#xff0c;要发送相关信息给企业内部服务器。 备注&#xff1a;接收消息 和 回调&#xff0c;在本文中指代相同的行为&#xff0c;即企业微信…

多内层神经网络具有先天的不可解释性

多层神经网络的不可解释性是指其内部的决策过程很难被人类理解和解释。这主要是因为多层神经网络具有大量的神经元和多个层次的连接&#xff0c;使得网络的决策过程变得非常复杂。 具体而言&#xff0c;多层神经网络中每一层的神经元会根据输入的特征进行加权组合和非线性变换&…

【管理篇 / 恢复】❀ 08. 文件权限对macOS下用命令刷新固件的影响 ❀ FortiGate 防火墙

【简介】虽然上篇文章中成功的在macOS下刷新了固件&#xff0c;但是很多小伙伴在实际操作中碰到了无法成功的状况&#xff0c;我们来看看最常见的一种。 在/private/tftpboot目录拷贝另一个版本的固件文件&#xff0c;具体拷贝过程不再详述。 打开终端&#xff0c;输入命令 sud…

Java内存泄漏问题分析

内存泄漏也是一个老八股文了&#xff0c;下面来看看实际项目中内存泄漏的场景分析 时间回到9月某一天 分析阶段一 现象&#xff1a;在当时各种请求在那段时间响应很慢&#xff0c;特别是 kafka异步消费线程 不足点&#xff1a;当时主业务基本不可用&#xff0c;有点急&#…

线性代数 --- 为什么LU分解中L矩阵的行列式一定等于(+-)1?

以下是关于下三角矩阵L的行列式一定等于-1的一些说明 证明&#xff1a;在LU分解中&#xff0c;下三角矩阵L的行列式一定是. 在证明之前&#xff0c;我这里先补充几条关于行列式的性质&#xff1a; 性质1&#xff1a;对于三角矩阵而言&#xff0c;不论是上三角矩阵还是下三角矩…

分布式之任务调度学习一

1 任务调度 1.1 什么时候需要任务调度&#xff1f; 1.1.1 任务调度的背景 在业务系统中有很多这样的场景&#xff1a; 1、账单日或者还款日上午 10 点&#xff0c;给每个信用卡客户发送账单通知&#xff0c;还款通知。如何判断客户的账单日、还款日&#xff0c;完成通知的发…

【数据库系统概论】数据库并发控制机制——并发操作带来的数据不一致性问题有哪些

系统文章目录 数据库的四个基本概念&#xff1a;数据、数据库、数据库管理系统和数据库系统 数据库系统的三级模式和二级映射 数据库系统外部的体系结构 数据模型 关系数据库中的关系操作 SQL是什么&#xff1f;它有什么特点&#xff1f; 数据定义之基本表的定义/创建、修改和…

扩展 apiserver 连接认证 ip, apiserver证书更新

本文来自我的博客地址 文章目录 问题场景:问题分析:问题解决:查看 apiserver 证书支持的 ip 或 host使用 openssl 生成证书:再次查看 apiserver 证书支持的 ip 或 host 再次尝试将 master 加点加入参考 问题场景: k8s 1.28.1 集群后期新增 vip apiserver 证书不支持 vip 引入…

[NSSRound#3 Team]This1sMysql

[NSSRound#3 Team]This1sMysql 源码 <?php show_source(__FILE__); include("class.php"); $conn new mysqli();if(isset($_POST[config]) && is_array($_POST[config])){foreach($_POST[config] as $key > $val){$value is_numeric($var)?(int)$…

Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models

ABSTRACT 现代大规模视觉-语言模型&#xff08;LVLMs&#xff09;采用了相同的视觉词汇-CLIP&#xff0c;可以涵盖大多数常见的视觉任务。然而&#xff0c;对于一些需要密集和细粒度视觉感知的特殊视觉任务&#xff0c;例如文档级OCR或图表理解&#xff0c;尤其是在非英语环境…

PHP运行环境之宝塔软件安装及Web站点部署流程

PHP运行环境之宝塔软件安装及Web站点部署流程 1.1安装宝塔软件 官网&#xff1a;https://www.bt.cn/new/index.html 自行注册账号&#xff0c;稍后有用 下载安装页面&#xff1a;宝塔面板下载&#xff0c;免费全能的服务器运维软件 1.1.1Linux 安装 如图所示&#xff0c;宝…

ubuntu18.04+realsenseD455制作TUM数据集

教程目录 一、本机环境二、安装RealSense SDK三、录制rosbag四、制作数据集四、安装ROS-RealSense五、测试数据集一、本机环境 Ubuntu系统ROS系统RealSense18.04melodicD455二、安装RealSense SDK 1、首先注册服务器的公钥 sudo apt-key adv --keyserver keyserver.ubuntu.co…

Protobuf 安装与使用

Protobuf 安装与使用 1 环境2 安装 [apt安装]2 安装 [源码安装]1 依赖2 下载 protobuf3 解压4 编译安装5 配置环境 2 命令查看版本卸载 3 使用书写 .proto 文件编译 .proto 文件生成 cpp 文件编写 cpp 文件编译运行 参考 1 环境 ubuntn 20.04 protobuf v3.6.1 2 安装 [apt安装…

使用STM32的定时器和PWM实现LCD1602的背光控制

使用STM32的定时器和PWM功能来控制LCD1602的背光是一种常见的方法&#xff0c;它可以实现背光的亮度调节和闪烁效果。在本文中&#xff0c;我们将讨论如何利用STM32的定时器和PWM来实现LCD1602的背光控制&#xff0c;并提供相应的代码示例。 1. 硬件连接和初始化 首先&#x…

Jupyter Lab | 在指定文件夹的 jupyter 中使用 conda 虚拟环境

Hi&#xff0c;大家好&#xff0c;我是源于花海。本文主要了解如何在指定文件夹的 jupyter 中使用 conda 虚拟环境&#xff0c;即在 conda 里面创建虚拟环境、将虚拟环境添加至 jupyter lab/notebook、安装软件包。 目录 一、创建虚拟环境 二、激活并进入虚拟环境 三、安装 …

C语言编译器(C语言编程软件)完全攻略(第二十九部分:Linux GCC简明教程(使用GCC编写C语言程序))

介绍常用C语言编译器的安装、配置和使用。 二十九、Linux GCC简明教程&#xff08;使用GCC编写C语言程序&#xff09; 市面上常见的 Linux 都是发行版本&#xff0c;典型的 Linux 发行版包含了 Linux 内核、桌面环境&#xff08;例如 GNOME、KDE、Unity 等&#xff09;和各种…

关于“Python”的核心知识点整理大全61

目录 注意 20.1.4 使用 jumbotron 设置主页的样式 index.html 20.1.5 设置登录页面的样式 login.html 20.1.6 设置 new_topic 页面的样式 new_topic.html 20.1.7 设置 topics 页面的样式 topics.html 元素&#xff0c;让它们在页面上显得大些&#xff08;见2&#xf…

上传自己的依赖到maven仓库 -- 保姆级复盘

上传自己的依赖到maven仓库 -- 保姆级复盘 1、准备工作1.1、安装Git1.2、将需要上传的代码先上传到Gitee中1.2.1、上传步骤1.2.2、如果出现以下错误&#xff08;主要原因是gitee中README.md文件和本地不一致&#xff0c;或者不在本地代码目录中&#xff09; 2、sonatype注册登录…

Unity组件开发--传送点

本组件仅实现A传送点到B传送的功能&#xff0c;是可以双向传送的&#xff0c;如果只要单向传送&#xff0c;可以另外改脚本实现&#xff1b; 先看效果&#xff1a; unity组件传送点演示 1.传送组件shader是怎么写的&#xff1a;这种效果的实现方案 shader编辑器是这样的&#…