Java:集合框架

1.Collection接口

        collection接口是Java最基本的集合接口,它定义了一组允许重复的对象。它虽然不能直接创建实例,但是它派生了两个字接口List和Set,可以使用子接口的实现类创建实例。Collection 接口是抽取List接口和Set接口共同的存储特点和操作方法进行的重构设计。Collection接口提供了操作集合以及集合中元素的方法。Collection接口的常用方法如下表:

方法声明功能描述
boolean add(Object obj)向集合中添加一个元素
boolean addAll(Collection c)将指定集合中所有元素添加到当前集合中
void clear()清空集合中的所有元素
boolean contains(Object obj)判断集合中是否包括某个元素
boolean containsAll(Collection c)判断集合中是否包含指定集合中的所有元素
Iterator iterator()返回在Collection的元素上进行迭代的迭代器
boolean remove(Object o)删除集合中的指定元素
boolean removeAll(Object o)删除指定集合中所有元素
boolean retainAll(Collection c)仅保留当前Collection中那些也包含在指定Collection的元素
Object[] toArray()返回包含Collection中所有元素的数组
boolean isEmpty()如果集合为空,则返回true
int size()返回集合中元素个数

        图示方法是集合的共性方法,这些方法即可以操作List集合,又可以操作Set集合。

2.List接口

        List接口是单列集合的一个重要分支,一般将实现了List接口的对象称为List集合。List集合中的元素是有序且可重复的,相当于数学里面的数列,有序、可重复。List集合的List接口记录元素的先后添加顺序,使用此接口能够精确地控制每个元素插入的位置,用户也可以通过索引来访问集合中的指定元素。

        List接口作为Collection接口的子接口,不但继承了Collection的所有方法,而且增加了一些操作List集合的特有方法,如下表:

方法声明功能描述

void add(int index,Object element)

在index位置插入element元素
Object get(int index)得到index出的元素
Object set(int index ,Object element)用element替换index位置的元素
Object remove(int index)移除index位置的元素,并返回元素
int indexOf(Object o)返回集合中第一次出现o的索引,若集合中不包含该元素,则返回-1
int lastIndex(Object o)返回集合中最后一次出现o的索引,若集合中不包含该元素,返回-1

上表列出了List接口的常用方法,所有List实现类都可以通过调用这些方法对集合元素进行操作。

创建一个List对象的语法格式如下:

List 变量 =new 实现类();

3.1ArrayList类

        ArrayList类是动态数组,用MSDN中的说法,就是数组的复杂版本,它提供了动态增加和减少元素的方法,继承AbstractList类,实现了List接口,提供了相关的添加、删除、修改、遍历等功能,具有灵活地设置数组大小的优点ArrayList实现了长度可变的数组,在内存中分配连续的空间,允许不同类型的元素共存。ArrayList类能够根据索引位置快速地访问集合中的元素,因此,ArrayList集合遍历元素随机访问元素的效率比较高。

        ArrayList类中大部分方法都是从List接口继承过来的。

        ArrayList的底层使用数组来保存元素的,用自动扩容机制实现动态增加容量。因为它的底层是用数组实现的,所以插入和删除操作的效率不佳,不建议用ArrayList做大量的增删操作。但是由于它有索引,所以查询效率很高,适合用来做大量查询操作

3.2LinkedList类

     为克服ArrayList集合查询速度快,增删速度慢的问题,可以使用LinkedList实现类。

        LinkedList底层的数据结构是基于双向链表的,它的底层实际上是由若干个相连的Node节点组成的,每个Node节点都包含该节点的数据、前一个结点、后一个节点。LinkedList集合添加元素如图①,LinkedList集合添加元素如图②。

        和ArrayList使用数据结构不同的是,链表结构的优势在于大量数据的添加和删除,但并不擅长依赖索引 的查询,因此,LinkedList在执行像插入或者删除这样的操作时,效率是很高的,但是随机访问方面就弱了很多。

        如图示,LinkedList类的方法大多是围绕头尾进行操作的,所以他对首尾元素的操作效率高。 

4.集合的迭代操作

4.1Iterator接口 

         Java提供了一个专门用于遍历集合的接口--Iterator,它是用来迭代访问Colllection中元素的,因此也称为迭代器。通过Collection接口中的iterator()方法可以得到集合的迭代器对象,只要拿到这个对象,使用迭代器就可以遍历集合。

TestIterator.java
public class TestIterator{public static void main(String[] args){List catList=new ArrayList();    //创建流浪猫集合Cat catl=new Cat("小哺",'母',"橘猫","收留");Cat cat2=new Cat("小米",'公',"三花","收留");Cat cat3=new Cat("小",'母”,"奶牛,"领养");catList.add(cat1);catList.add(cat2);catList.add(cat3);Iterator iterator=catList.iterator();    //获取Iterator 对象                                 while(iterator.hasNext()){ //判断集合中是否存在下一个元素Cat ele=(Cat)iterator.next(); //输出集合中的元素System.out.println(ele);}}
}

调用ArrayList的iterator()方法获得迭代器的对象,然后使用hasNext()方法判断集合中是否存在下一个元素,若存在,则通过next()方法取出。这里要注意,通过next()方法获取去元素时,必须调用hasNext()方法检测是否存在下一个元素,若元素不存在,会抛出NoSuchElementException异常。Iterator仅用于遍历集合,如果需要创建对象,则必须有一个被迭代的集合。

        在Iterator使用next()方法之前,迭代器游标在第一个元素之前,不知想任何元素,在第一次调用next()方法后,迭代器游标会后移一位,指向第一个元素并返回,依此类推,当hasNext()方法返回false时,则说明达到集合末尾,停止遍历。

4.2foreach遍历集合

        Java还提供了一种很简洁的遍历方法,即使用foreach循环遍历集合,它既能遍历普通数组,也能遍历集合。其语法格式如下:

for(容器中元素类型 临时变量:容器变量){代码块
}

从上述语法格式可以看出,与普通的for循环不同的是,foreach循环不需要获取容器的长度,不需要用索引去访问容器中元素,但是它能自动遍历容器中所有元素。

5.Set接口

        Set接口是单列集合的一个重要分支,一般将实现了Set接口的对象称为Set集合。Set集合中元素是无序的、不可重复的。严格地说,是没有按照元素的插入顺序排列。

        Set集合判断两个元素是否相等用equals()方法,而不是使用“=”运算符。如果两个对象比较就,equals()返回true,则Set集合是不会接受这两个对象的。Set集合可以储存null,但是只能储存一个,即使添加多个也只能储存一个。

        Set接口也继承了Collection接口,但是它没有对Collectionjk的方法进行扩充。Set接口的主要实现类是HashSet和TreeSet。其中,HashSet根据对象的哈希值来确定元素在集合中的存储位置,能高效的查询,可以用来做少量数据的插入操作;TreeSet底层是 用二叉树来实现存储元素的,它可以对集合中的元素进行排序。 

5.1HashSet类   

        HashSet按照Hash算法来确对象在集合中的储存位置。因此,具有很好的存取和查找性能。Set集合和List集合存取元素的方式是一样的。 

 5.2TreeSet类                                                                                    

         TreeSet集合和HashSet集合都可以保证容器内元素的唯一性,但是它们底层实现方式不同,TreeSet底层是用自平衡的排序二叉树实现的,所以它既能保证元素的唯一性,又可以对元素进行排序。TreeSet类还提供一些特有的方法,如下表示:

      

        TreeSet有两种排序方法:自然排序和定制排序。默认情况下,TreeSet采用自然排序。

         1.自然排序

TreeSet类会调用集合元素的comparable(Object obj)方法来比较元素的大小,然后将集合内的元素按升序排序,这是自然排序。

        Java提供了Comparable接口,它里面定义了一个comparableTo(Object obj)实现Comparable接口必须实现该方法,在方法中实现对象大小比较。当该方法被调用时,如obj1.compare To(obj2),若该方法返回0,则说明obj1和obj2相等;若该方法返回一个正数,则说明obj1大于obj2;若该方法返回一个负数,则说明obj1小于obj2.

        如果把一个对象添加到TreeSet集合,则该对象必须实现Comparable接口,否则程序会抛出ClassCastException异常。

        另外,向TreeSet集合中添加的应该是同一个类的对象,否则运行结果也会报ClassCastException异常。

        2.定制排序

         TreeSet的自然排序根据集合元素大小,按升序排序,如果需要按特殊规则排序或者元素本身不具备比较性,比如按降序排列,这时候就需要用到定制排序。Comparator接口包含一个int compare(T  t1,T  t2)方法,该方法可以比较t1和t2大小,返回正整数,则说明t1大于t2;若返回0,则说明t1等于t2;若返回负整数,则说明t1小于t2.

        要实现TreeSet的定制排序,只需在创建TreeSet对象时,提供Comparator对象与该集合关联,并在Comparator中编写排序逻辑。

import java.util.*;
public class TestTreeSetSort{public static void main(string[] args){//创建TreeSet集合对象时,提供一个Comparator对象TreeSet tree=new TreeSet(new MyComparator ()); tree.add(new Student(140));tree.add(new Student(15));tree.add(new Student(11));system.out.println(tree);}}Class Student{//定义Student类private Integer age;public Student (Integer age){this.age=age;}public Integer getAge(){return age;}public void setAge (Integer age){this.age=age;}public String toString(){return age+"";}
}
class MyComparator implements Comparator{ //实现Comparator接口//实现一个campare方法, 判断对象是否是特定类的一个实例public int compare (Object o1,0bject o2){if(o1 instanceof Student&o2 instanceof Student){Student s1=(Student)o1; //强制转换为Student类型Students2=(Student) o2;if(s1.getAge()>s2.getAge()){return -1;}elseif(s1.getAge()<s2.getAge()){return 1;}}return 0;}
}

6.Map接口

6.1Map简介 

        Map接口不继承Collection接口,它与Collection接口是并列存在的,用于存储键值对形式的元素,描述了由于不重复的键到值的映射。

        Map中key和value都可以是任何引用类型的的数据。Map中key用Set来存放,不允许重复,及同一个Map对象所对应的类,必须重写hashCode()方法和equals()方法。通常用String类作为Map的key,key和value之间存在一对一的关系,即通过指定的key总能遭到唯一的、确定的value。Map接口的方法如下图示:

 6.2HashMap类

        HashMap类是Map接口中使用频率最高的实现类,允许使用null键和null值,与HashSet集合一样,不保证映射的顺序。HashMap集合判断两个key相等的标准:两个key通过equals()方法返回true,hashCode值也相等。HashMap集合判断两个value相等的标准:两个value通过equals()方法返回true。由于HashMap集合中的键是用Set来储存的,所以不可以重复。 

当键重复时,后添加元素的值,覆盖了先添加的元素的值,简单来说就是键相同,值覆盖。

        遍历Map的方式有两种,第一种是先遍历所有的键,再根据键获得对应的值。第二种遍历方式是先获得集合所有的映射关系,然后再根据映射关系获取键和值

6.3LinkedHashMap类

        LinkedHashMap类是HashMap的子类,LinkedHashMap类可以维护Map的迭代顺序,迭代顺序与键值插入顺序一致。如果需要输出顺序与输入时顺序相同,那么就用LinkedHashMap集合。

6.4Properties类

        Map接口中有一个古老的、线程安全的实现类--Hashtable,与HashMap集合相同的是,他也不能保证其中键值对的顺序,他判断两个键、两个值相等的标准与HashMap集合一样,与HashMap集合不同的是,他不允许使用null作为键和值

        Hashtable类存取元素速度较慢,目前基本被HashMap类代替,但是他有一个子类Properties在实际开发中 很常用,该子类对象处理文件,由于属性文件里的键和值都是字符串类型的,所以Properties类的键和值都是字符串类型的。

 7.1为什么要使用泛型

        为了解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识,表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或者实例化时只要指定好需要的具体类型即可。

        Java泛型可以保证程序在编译时如果没有发出警告,运行时就不会报ClassCastException异常,同时,代码更加简洁、健壮。

7.2泛型的定义

        在定义泛型时,使用“<参数化类型>”的方式指定集合中方法操作的数据类型,具体示例如下。

ArrayList <参数化类型> list =new ArrayList<参数化类型>();

        在创建集合的时候,如果指定了泛型为String类型,该集合只能添加String类型的元素,编译文件时,不再出现类型安全警告,如果向集合中添加非String类型的元素,则会报编译时异常。

7.3通配符

        这里要引入一个通配符的概念,类型通配符用符号“ ?”表示,比如List<?>,它是List<String>、List<Object>等各种泛型的父类。

import java.util.*;
public class TestGeneric2{public static void main(String[] args){//声明泛型类型为“?”List<?> list=null;list=new ArrayList<String>();list=new ArrayList<Integer>(); //编译时报错//list.add(3);list.add(null); //添加元素nullSystem.out.println(list);List<Integer> 11=new ArrayList<Integer>();List<String>l2=new ArrayList<String>();l1.add(1000);12.add("phone");read(ll);read(l2);}static void read(List<?> list){for(0bjecto:list){System.out.println(0);}}}

        先声明List的泛型类型为“ ?”,然后在创建对象实例时,泛型类型设为String或者Integer都不会报错,这体现了泛型的可扩展性,此时向集合中添加元素会报错,因为List的元素类型无法确定,唯一的例外是null,它是所有类型的成员。

        另外,在方法read()的参数声明中,List参数也应用了泛型类型“?”,所以使用此静态方法能接收多种类型。

7.4自定义泛型

        假设要实现一个简单的容器,用于保存某个值,这个容器应该定义两个方法--get()方法和set(),前者用于取值,后者用于存值,如法格式如下:

void    set(参数类型 参数){...}
返回值 参数类型 get(){...}

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

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

相关文章

九种mfc140u.dll丢失的解决方法,全面解决mfc140u.dll文件丢失

mfc140u.dll是 Microsoft Visual C 2015 Redistributable 的一部分&#xff0c;它与 Microsoft 基础类库&#xff08;MFC&#xff09;的 Unicode 版本有关。当您在运行使用 Visual C 2015 开发的应用程序时&#xff0c;可能会碰到关于mfc140u.dll丢失的错误。下面列出了一些解决…

刷机维修进阶教程-----红米k30 nv损坏故障 修复实例教程步骤解析

小米红米系列机型在米8起始就有了串码校验。不得随意更改参数限制。不同于其他机型,可以任意刷入同芯片的基带qcn来修复基带和串码丢失。米系列刷入同芯片基带qcn会提示nv损坏故障。是因为有串码校验。一般在于格机或者全檫除分区后写新参数出现的故障。 这种解决方法通常有两…

Nginx+Tomcat负载均衡,动静分离群集

Nginx反向代理原理 Nginx 反向代理&#xff1a;将Nginx接收到的请求转发给其它应用服务器处理 Nginx 负载均衡&#xff1a;通过反向代理实现&#xff0c;还可以将nginx接收到的请求转发给多个后端应用服务器处理 Nginx 动静分离&#xff1a;静态页面请求&#xff0c;由nginx…

上汽集团25届暑期实习测评校招笔试题库已发(真题)

&#x1f4e3;上汽集团 25届暑期实习测评已发&#xff0c;正在申请的小伙伴看过来哦&#x1f440; ㊙️本次实习项目面向2025届国内外毕业生&#xff0c;开放了新媒体运营、销售策略、市场运营、物流、质量分析等岗位~ ✅测评讲解&#xff1a; &#x1f449;测评自收到起需在…

Linux---防火墙

文章目录 目录 文章目录 前言 一.静态防火墙&#xff1a;iptables iptables五链 iptables 四表 iptables控制类型 iptables命令配置 前言 这儿主要介绍Linux系统本身提供的软件防火墙的功能&#xff0c;即数据包过滤机制。 数据包过滤&#xff0c;也就是分析进入主机的网络数…

cve_2022_0543-redis沙盒漏洞复现 vulfocus

1. 原理 该漏洞的存在是因为Debian/Ubuntu中的Lua库是作为动态库提供的。自动填充了一个package变量&#xff0c;该变量又允许访问任意 Lua 功能。 2.复现 我们可以尝试payload&#xff1a; eval local io_l package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so…

DeepSpeed MoE

MoE概念 模型参数增加很多&#xff1b;计算量没有增加&#xff08;gating小FNN&#xff0c;比以前的大FNN计算量要小&#xff09;&#xff1b;收敛速度变快&#xff1b; 效果&#xff1a;PR-MoE > 普通MoE > DenseTransformer MoE模型&#xff0c;可视为Sparse Model&…

表的设计与查询

目录 一、表的设计 1.第一范式&#xff08;一对一&#xff09; 定义&#xff1a; 示例&#xff1a; 2.第二范式&#xff08;一对多&#xff09; 定义&#xff1a; 要求&#xff1a; 示例&#xff1a; 3.第三范式&#xff08;多对多&#xff09; 定义&#xff1a; 要求…

**《Linux/Unix系统编程手册》读书笔记24章**

D 24章 进程的创建 425 24.1 fork()、exit()、wait()以及execve()的简介 425 . 系统调用fork()允许父进程创建子进程 . 库函数exit(status)终止进程&#xff0c;将进程占用的所有资源归还内核&#xff0c;交其进行再次分配。库函数exit()位于系统调用_exit()之上。在调用fo…

ffmpeg常见命令

一、ffmpeg的安装 ffmpeg的安装 一、ffmpeg常用命令 二、ffprobe

浅解Reids持久化

Reids持久化 RDB redis的存储方式&#xff1a; rdb文件都是二进制&#xff0c;很小&#xff0c;里面存的是数据 实现方式 redis-cli链接到redis服务端 使用save命令 注&#xff1a;不推荐 因为save命令是直接写到磁盘里面&#xff0c;速度特别慢&#xff0c;一般都是redis…

遗传算法笔记:基本工作流程

1 介绍 遗传算法有5个主要任务&#xff0c;直到找到最终的解决方案 2 举例 2.1 问题描述 比如我们有 5 个变量和约束&#xff0c;其中 X1、X2、X3、X4 和 X5 是非负整数且小于 10&#xff08;0、1、2、4、5、6、7、8、9&#xff09;我们希望找到 X1、X2、X3、X4 和 X5 的最…

go语言后端开发学习(三)——基于validator包实现接口校验

前言 在我们开发模块的时候,有一个问题是我们必须要去考虑的&#xff0c;它就是如何进行入参校验&#xff0c;在gin框架的博客中我就介绍过一些常见的参数校验&#xff0c;大家可以参考gin框架学习笔记(四) ——参数绑定与参数验证&#xff0c;而这个其实也不是能够完全应对我…

Android JobService启动系统源码分析

以下就JobService的执行流程,系统层实现进行详解 入口点在JobScheduler.scheduler 系统层JobScheduler是个抽象类,它的实现类是JobScheduler mBinder,一看就知道这里面肯定是跨进程了。它的服务端在JobSchedulerService里面,具体 为什么请看系统服务器启动流程相关文章,…

Python算法于强化学习库之rlax使用详解

概要 在强化学习领域,开发和测试各种算法需要使用高效的工具和库。rlax 是 Google 开发的一个专注于强化学习的库,旨在提供一组用于构建和测试强化学习算法的基础构件。rlax 基于 JAX,利用 JAX 的自动微分和加速计算功能,使得强化学习算法的实现更加高效和简洁。本文将详细…

堡垒机的自动化运维,快速安全提升运维效率

随着信息技术的突飞猛进&#xff0c;企业对于IT系统的依赖程度日益加深&#xff0c;不仅希望可以提高运维效率&#xff0c;也希望能保障IT系统的安全。因此堡垒机与自动化运维技术的结合应运而生&#xff0c;堡垒机的自动化运维&#xff0c;快速安全提升运维效率。今天我们就来…

CTE-6作文

第一段 现象 引出原因 第二段 感受 举例 意义 危害 第三段 建议 展望

2024年数字化经济与智慧金融国际会议(ICDESF 2024)

2024 International Conference on Digital Economy and Smart Finance 【1】大会信息 大会时间&#xff1a;2024-07-22 大会地点&#xff1a;中国成都 截稿时间&#xff1a;2024-07-10(以官网为准&#xff09; 审稿通知&#xff1a;投稿后2-3日内通知 会议官网&#xff1a;h…

day27回溯算法part03| 39. 组合总和 40.组合总和II 131.分割回文串

39. 组合总和 题目链接/文章讲解 | 视频讲解 本题是 集合里元素可以用无数次&#xff0c;那么和组合问题的差别 其实仅在于 startIndex上的控制 class Solution { public:int sum;vector<int> path;vector<vector<int>> result;void backtracking(vector<…

W25Q64简介

W25Q64介绍 本节使用的是&#xff1a;W25Q64&#xff1a; 64Mbit / 8MByte。存储器分为易失性存储器和非易失性存储器&#xff0c;易失性存储器一般是SRAM&#xff0c;DRAM。非易失性存储器一般是E2PROM&#xff0c;Flash等。非易失性存储器&#xff0c;掉电不丢失。 字库存储…