Java:集合框架

news2024/12/25 0:17:23

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); //添加元素null
         System.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.coloradmin.cn/o/1810044.html

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

相关文章

面试官:Spring如何解析配置类

你好&#xff0c;我是柳岸花开。 大家好&#xff0c;今天我们来深入探讨一下Spring框架中的配置类解析与扫描过程的源码。Spring作为Java开发中最为广泛使用的框架之一&#xff0c;其核心机制一直是开发者关注的焦点。本文将带领大家从源码角度&#xff0c;详细剖析Spring配置类…

构建高效的数据存储系统:Python dbm 模块的应用与实践

&#x1f340; 前言 博客地址&#xff1a; CSDN&#xff1a;https://blog.csdn.net/powerbiubiu &#x1f44b; 简介 dbm&#xff08;Database Manager&#xff09;是Python中的一个模块&#xff0c;用于创建和管理简单的键值对数据库。它提供了一种简单而有效的方式来存储和…

HTML静态网页成品作业(HTML+CSS)—— 环保主题介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

hadoop未授权访问命令执行漏洞复现-vulfocus

1 介绍 Hadoop YARN&#xff08;Yet Another Resource Negotiator&#xff09;的ResourceManager是集群资源管理的核心组件&#xff0c;负责分配和管理集群资源以及调度作业。如果ResourceManager出现未授权访问漏洞&#xff0c;可能允许未经认证的用户访问或操作集群资源&…

二叉树顺序结构——堆的结构与实现

二叉树顺序结构——堆的结构与实现 一、二叉树的顺序结构二、堆的概念及结构三、堆的实现堆向下调整算法堆的创建建堆时间复杂度堆的插入(堆向上调整算法)堆的删除堆的代码实现(使用VS2022的C语言)初始化、销毁构建、插入、删除返回堆顶元素、判空、返回有效元素个数 四、完整 …

Python深度学习之PyTorch基础教程

⛄前言 PyTorch是一个基于Torch的Python开源机器学习(深度学习)框架&#xff0c;由Facebook的人工智能研究院开发&#xff0c;不仅能够实现强大的GPU加速&#xff0c;还支持动态神经网络&#xff0c;使得研究人员和开发人员能够轻松构建和训练复杂的深度学习模型。与TensorFlo…

贪心算法 -- 组合一组数字获得最大数

贪心算法 – 组合一组数字获得最大数 文章目录 贪心算法 -- 组合一组数字获得最大数题目重现读懂题目贪心场景代码示例 题目重现 题目链接&#xff1a;最大数 - 力扣 给定一组非负整数 nums&#xff0c;重新排列每个数的顺序&#xff08;每个数不可拆分&#xff09;使之组成一…

error 12154 received logging on to the standby报错处理

错误 处理方法 该参数不是主库的servicename &#xff08;低级错误&#xff09; SQL> alter system set log_archive_dest_2 SERVICEstandby ASYNC VALID_FOR(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAMEstandby; System altered. 观察主库日志: 备库日志: 该问题会影…

Python集合的基本概念和使用方法

目录 集合&#xff08;Set&#xff09; 基本概念 基本特性 基本操作 集合运算 成员测试 高级操作 集合推导式 总结 集合&#xff08;Set&#xff09; Python集合&#xff08;Set&#xff09;是Python语言中一个非常实用且强大的数据结构&#xff0c;它用于存储多个不…

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

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

爬虫工具yt-dlp

yt-dlp是youtube-dlp的一个fork&#xff0c;youtube-dlp曾经也较为活跃&#xff0c;但后来被众多网站屏蔽&#xff0c;于是大家转而在其基础上开发yt-dlp。yt-dlp的github项目地址为&#xff1a;GitHub - yt-dlp/yt-dlp: A feature-rich command-line audio/video downloaderA …

Java学习【深入探索包装类和泛型】

Java学习【深入探索包装类和泛型】 &#x1f680;包装类获取包装类对象的方式使用valueOf()创建直接赋值 Integer成员方法 &#x1f680;泛型引出泛型泛型类泛型方法泛型接口泛型的继承和通配符泛型的上界 在Java的学习中&#xff0c;包装类和泛型是两个重要的概念&#xff0c;…

分布式事务AP控制方案(上)

分布式事务控制方案 本篇文章给出一种要求高可用性&#xff08;AP思想&#xff09;的分布式事务控制方案 下篇新鲜出炉&#xff1a;点我查看 分布式事务控制方案1、业务背景2、本地消息表的设计3、对消息表的操作4、任务调度5、任务流程控制的抽象类6、课程发布的实现类7、总…

我的创作纪念日--我和CSDN一起走过的1825天

机缘 第一次在CSDN写文章&#xff0c;是自己在记录学习Java8新特性中Lambda表达式的内容过程中收获的学习心得。之前也有记录工作和生活中的心得体会、难点的解决办法、bug的排查处理过程等等。一直都用的有道笔记&#xff0c;没有去和大家区分享的想法&#xff0c;是一起的朋…

《Brave New Words 》2.4 与历史对话

Part II: Giving Voice to the Social Sciences 第二部分&#xff1a;为社会科学发声 Conversing with History 与历史对话 Good history and civics teachers make the past interesting. Great history and civics teachers make the past come alive. When history and civi…

作业07 递推算法2

作业&#xff1a; #include <iostream> using namespace std; int main(){int a[110][110]{0},b[110][110]{0},n;cin>>n;for(int i1;i<n;i){for(int j1;j<i;j){cin>>a[i][j];}}for(int in-1;i>1;i--){for(int j1;j<i;j){a[i][j]a[i][j]max(a[i1]…

离散数学--连通性和矩阵

目录 0.关系的运算和性质 1.通路和回路 2.连通关系 3.割点&#xff08;边&#xff09;和点&#xff08;边&#xff09;割集 4.强&#xff08;弱&#xff09;连通&单向连通 0.关系的运算和性质 &#xff08;1&#xff09;这个运算包括了矩阵的运算&#xff0c;包括这个…

汽车数据应用构想(三)

上期说的&#xff0c;用数据去拟合停车信息的应用&#xff0c;那么类似的POI信息相关的场景其实都可以实现。今天讲讲用户使用频率也很高的加油/充电场景。 实际应用中&#xff0c;在加油场景中用户关心的通常还是价格。无论是导航还是各种加油APP/小程序&#xff0c;都已经很…

了解常用智能指针

智能指针 1、概念 C中引入智能指针的主要目的是为了解决内存管理的问题&#xff0c;传统的指针&#xff08;裸指针&#xff09;在使用时需要手动分配和释放内存&#xff0c;容易出现内存泄漏和悬挂指针等问题。智能指针通过封装裸指针&#xff0c;并提供自动内存管理功能&…