集合-及其各种特征详解

集合

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

  • 集合关系图

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

单列集合

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;@Overridepublic 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;}@Overridepublic 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;}@Overridepublic String toString() {return "Student{" +"age=" + age +", name='" + name + '\'' +'}';}@Overridepublic 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>() {@Overridepublic 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;}@Overridepublic 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>() {@Overridepublic 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、根据键 删除 键值对,没有此键 返回 nullm.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 方法,所以不同内容的哈希值相同

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring模块(一)DI依赖注入

一、介绍&#xff1a;Dependency Injection&#xff0c;组件之间依赖关系由容器在运行期决定&#xff0c;形象的说&#xff0c;即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能&#xff0c;而是为了提升组件重用的频率&#xff0c;并为…

【策】策略

为应对未来激烈的竞争&#xff0c;需要具备以下要素&#xff1a; 主动选择。每个人都有主动选择的权利&#xff0c;既然做出选择&#xff0c;应对其产生的结果而负责。反逆向思维。梳理过程&#xff0c;分析因果&#xff0c;优化决策。

How to implement anti-crawler strategies to protect site data

How to implement anti-crawler strategies to protect site data 信息校验型反爬虫User-Agent反爬虫Cookie反爬虫签名验证反爬虫WebSocket握手验证反爬虫WebSocket消息校验反爬虫WebSocket Ping反爬虫 动态渲染反爬虫文本混淆反爬虫图片伪装反爬虫CSS偏移反爬虫SVG映射反爬虫字…

VM与欧姆龙PLC通讯设置

1、欧姆龙PLC 进行网口通讯&#xff0c;协议用的Fins tcp&#xff0c;也可以用Fins UDP。 2、主要步骤如下&#xff1b; step1&#xff1a;设置IP地址、端口号默认是9600&#xff0c;根据需要设置寄存器首地址和寄存器数量 step2&#xff1a;鼠标移动到某个地址下&#xff0c…

Python入门-函数

1.函数的定义及调用 函数&#xff1a;函数是将一段实现功能的完整代码&#xff0c;使用函数名称进行封装&#xff0c;通过函数名称进行调用。 以此达到一次编写&#xff0c;多次调用的目的 def get_sum(num): #num叫形式参数s0for i in range(1,num1):siprint(f1到{num}之…

数字后端设计实现 | 数字后端PR工具Innovus中如何创建不同高度的row?

吾爱IC社区星球学员问题&#xff1a;Innovus后端实现时两种种不同高度的site能做在一个pr里面吗&#xff1f; 答案是可以的。 Innovus支持在同一个设计中中使用不同的row&#xff0c;但需要给各自子模块创建power domain。这里所说的不同高度的row&#xff0c;有两种情况。 1…

Docker一键极速安装Nacos,并配置数据库!

1 部署方式 1.1 DockerHub javaedgeJavaEdgedeMac-mini ~ % docker run --name nacos \ -e MODEstandalone \ -e JVM_XMS128m \ -e JVM_XMX128m \ -e JVM_XMN64m \ -e JVM_MS64m \ -e JVM_MMS64m \ -p 8848:8848 \ -d nacos/nacos-server:v2.2.3 a624c64a1a25ad2d15908a67316d…

指针大礼包6

第6题 &#xff08;10.0分&#xff09; 题号:5 难度:中 第8章 /*------------------------------------------------------- 【程序改错】 --------------------------------------------------------- 题目&#xff1a;下列给定程序中函数fun的功能是…

代码随想录刷题第三十九天| 62.不同路径 ● 63. 不同路径 II

代码随想录刷题第三十九天 不同路径 (LC 62) 题目思路&#xff1a; 代码实现&#xff1a; class Solution:def uniquePaths(self, m: int, n: int) -> int:dp [[0 for _ in range(n1)] for _ in range(m1)]dp[0][1] 1for i in range(1,m1):for j in range(1, n1):dp[i]…

使用IDEA官方docker插件构建镜像

此方法同样适用于jetbrains系列的其他开发软件 在IDEA中&#xff0c;如果是maven项目&#xff0c;可以使用插件 <plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.2.2</version> &…

Linux入门攻坚——11、Linux网络属性配置相关知识1

网络基础知识&#xff1a; 局域网&#xff1a;以太网&#xff0c;令牌环网&#xff0c; Ethernet&#xff1a;CSMA/CD 冲突域 广播域 MAC&#xff1a;Media Access Control&#xff0c;共48bit&#xff0c;前24bit需要机构分配&#xff0c;后24bit自己…

WPF 如何知道当前有多少个 DispatcherTimer 在运行

在 WPF 调试中&#xff0c;对于 DispatcherTimer 定时器的执行&#xff0c;没有直观的调试方法。本文来告诉大家如何在 WPF 中调试当前主线程有多少个 DispatcherTimer 在运行 在 WPF 中&#xff0c;如果有 DispatcherTimer 定时器在执行&#xff0c;将会影响到主线程的执行&a…

Qt6入门教程 2:Qt6下载与安装

Qt6不提供离线安装包&#xff0c;下载和安装实际上是一体的了。 关于Qt简介&#xff0c;详见&#xff1a;Qt6入门教程1&#xff1a;Qt简介 一.下载在线安装器 Qt官网 地址&#xff1a;https://download.qt.io/ 在线下载器地址&#xff1a;https://download.qt.io/archive/on…

Unity | NGO网络框架

目录 一、相关属性及变量 1.ServerRpc属性 2.ClientRpc属性 3.NetworkVariable变量 二、相关组件 1.NetworkManager 2.Unity Transport 3.Network Object 4.NetworkBehaviour&#xff1a; 5.NetworkTransform Syncing(Synchronizing) Thresholds Interpolation 三…

Linux下Redis6下载、安装和配置教程-2024年1月5日

Linux下Redis6下载、安装和配置教程-2024年1月5日 一、下载二、安装三、启动四、设置开机自启五、Redis的客户端1.Redis命令行客户端2.windows上的图形化桌面客户端 一、下载 1.Redis的官方下载&#xff1a;https://redis.io/download/ 2.网盘下载&#xff1a; 链接&#xff…

Docker overlay2文件busy,容器不能删除问题解决

文章目录 在删除docker容器的时候报错,说设备正忙通过 docker ps -a 查看有两个状态的dead的容器解决方法&#xff1a;1.查看所有挂载的设备2.截取设备的进程id3.清理进程(kill掉即可) 在删除docker容器的时候报错,说设备正忙 Error response from daemon: Driver overlay2 fai…

Linux的ping命令、wget命令、curl命令

一、ping命令 通过ping命令&#xff0c;可以检查指定的网络服务器是否是可联通状态 形式&#xff1a;ping [-c num] ip或主机名 -c&#xff1a;检查的次数&#xff0c;不使用-c&#xff0c;将无限次数持续检查 ip或主机名&#xff1a;被检查的服务器的ip地址或主机名地址 …

AOP(面向切面编程)基于XML方式配置

概念解释&#xff1a;&#xff08;理解基本概念方可快速入手&#xff09; 连接点&#xff08;joinpoint&#xff09; 被拦截到的点&#xff0c;因为Spring只支持方法类型的连接点&#xff0c;所以在Spring中连接点指的就是被拦截到的方法。 切入点&#xff08;pointcut&#x…

系列一、如何正确的获取Spring Cloud Alibaba Spring Cloud Spring Boot之间的版本对应关系

一、正确的获取Spring Cloud Alibaba & Spring Cloud & Spring Boot之间的版本对应关系 1.1、概述 Java发展日新月异&#xff0c;Spring Cloud Alibaba 、 Spring Cloud 、 Spring Boot在GitHub上的迭代也是异常的频繁&#xff0c;这也说明其社区很活跃&#xff0c;通…

【持续学习系列(六)】《iCaRL》

一、论文信息 1 标题 iCaRL: Incremental Classifier and Representation Learning 2 作者 Sylvestre-Alvise Rebuffi, Alexander Kolesnikov, Georg Sperl, Christoph H. Lampert 3 研究机构 University of Oxford/IST Austria 二、主要内容 论文主要探讨了如何开发能…