Java集合框架

一、集合概述

1、什么是集合?

通俗来讲,集合就是把具有同一性质的一类东西汇聚成一个整体。从字面意思理解,集合就是把具有相同性质的一类东西汇聚成一个整体。在面向对象中,对事物都是以对象的形式体现。为了方便对多个对象的操作,需要存储多个对象的容器,而集合就是存储多个对象最常用的一种方式。

集合框架:用于存储数据的容器。

集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。
任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。

集合的主要操作:
1、将对象添加到集合
2、从集合中删除对象
3、从集合中查找到对象
4、从集合中修改对象

2、集合和数组的区别

1、数组是固定长度的;集合可变长度的。

2、数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。

3、数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。

数组 集合
容器
大小 一旦创建,它的大小是固定的 集合大小是一直可变的
数据 基本类型 、引用类型
类型 数组中存储的数据类型是相同的 集合可以存储任意类型的对象

3、集合框架的好处

  1. 容量自增长;
  2. 提供了高性能的数据结构和算法,使编码更轻松,提高了程序速度和质量;
  3. 允许不同 API 之间的互操作,API之间可以来回传递集合;
  4. 可以方便地扩展或改写集合,提高代码复用性和可操作性。
  5. 通过使用JDK自带的集合类,可以降低代码维护和学习新API成本。

4、集合框架

在这里插入图片描述


(1) Java集合框架的接口

接口 特点
Collection 集合的根接口,没有实现类,用于引用子接口的对象,Collection是一组对象的集合
List 元素之间是有序的,元素可以重复。
通过索引来访问元素,允许在指定位置插入元素
Set 元素之间是无序的,元素不可重复
Map 存储Key/Value对的集合
key值不允许重复,每个key最多只能映射到一个值。Map是一组Key/Value对的集合。

(2)Java集合框架的实现类

接口 实现类 特点
LIst ArrayList 底层使用数组实现,长度默认是10。如果集合元素的个数超出当前数组大小,则创建新的扩容60%的数组,并将原来的元素拷贝过来。由于数组是按内存位置依次序存放,因此查找快,但是增删元素涉及到后面的元素移动,因此增删元素慢
LinkedList 底层使用链表实现。增删元素时,链表只需增加或删除一个结点,这样的增删效率较高,但查询时需要一个一个的遍历,所以查询速率较低。
Vector 和ArrayList原理相同,Vector是线程安全的,所以效率略低。
Set HashSet 底层是以哈希表实现的,所有元素是按hashCode的值存放的,HashSet是线程不安全的,存取速度快
TreeSet 底层使用红-黑树的数据结构实现。
要求元素实现Compareable接口,默认树元素进行自然排序(String)。
LinkedHashSet 底层使用链表技术实现,但是结合了哈希值实现存储。LinkedHashSet的增删效率高,查询效率低
LIst ArrayList 底层使用数组实现,长度默认是10。如果集合元素的个数超出当前数组大小,则创建新的扩容60%的数组,并将原来的元素拷贝过来。由于数组是按内存位置依次序存放,因此查找快,但是增删元素涉及到后面的元素移动,因此增删元素慢
LinkedList 底层使用链表实现。增删元素时,链表只需增加或删除一个结点,这样的增删效率较高,但查询时需要一个一个的遍历,所以查询速率较低。
Vector 和ArrayList原理相同,Vector是线程安全的,所以效率略低。
Map HashMap 底层是哈希表存储。
HashMap没有对key排序,可以存入null键、null值。
HashMap是线程不安全的。
TreeMap 底层是哈希表存储。
TreeMap 对key进行排序,要求key实现Compareable接口
HashTable 底层是哈希表数据结构。
HashTable是线程安全的,不可以存入null键和null值。
HashTable效率较低,已被Hash Map替代
LinkedHashMap 底层使用链表技术实现,但是结合了哈希值实现存储。
LinkedHashMap的增删效率高,查询效率低。

(3)应用场景
为什么有这么多集合?因为每一个容器对数据的存储方式不同,为各种存储方式提供了多样化的选择

Collection 这是一个纯粹的接口,用于引用List、Set的实现对象
List 如果需要保留存储顺序,并且允许保留重复的元素,使用List接口的实现类。
如果查询较多,使用ArrayList。
如果存取较多,使用LinkedList
如果需要线程安全,使用Vector
Set 如果不需要保留存储顺序,并且需要去掉重复的元素,使用Set接口的实现类
如果需要将元素排序,使用TreeSet
如果不需要排序,使用HashSet比使用TreeSet效率高
如果我们需要保留储存顺序,又要过滤重复元素,使用LinkedHashSet
Map 如果需要保留key/value形式数据,使用Map接口的实现类
如果我们需要将元素排序,使用TreeMap
如果不排序,HashMap的效率高于TreeMap

二、Collection

Collection是一个集合接口,为集合对象提供了最大化的统一操作方式。集合类都是在java.util包中,因此Collection接口就是java.util.Collection。
Collection没有实现类,通常用于对实现子接口的对象引用。

		Collection coll=new ArrayList();	

1.基本操作

add(Object o) 向集合添加元素。成功返回true,失败返回false
remove(Object o) 删除指定元素。成功返回true,失败返回false
size() 获取集合中元素的个数
clear() 清空集合中的所有元素
isEmpty() 判断集合是否为空
contains(Object o) 判断集合是否包含指定对象
注意:contains内部依赖equals方法进行比较

2.迭代器

java实现了迭代器iterator对象,它提供了一些方法实现了对集合中元素的遍历》Collection接口中定义了获取迭代器的方法(iterator() ),所有的Collection类型的集合都可以通过这个方法获取自身的迭代器
(1) Iterator接口
该接口就是迭代器接口,定义了常见的迭代方法:

boolean hasNext() 判断集合中是否有下一个元素,如果有元素就返回true,没有返回true
E next() 返回集合中的下一个元素,注意:如果没有下一个元素时,调用next()方法会抛出NoSuchElementException异常
void remove() 从集合中移除迭代器返回的最后一个元素(可选操作)

(1)迭代器遍历相关操作
while循环
最常见的iterator遍历方式

Collection<String> list=new ArrayList<String>();
        list.add("str1");
        list.add("str2");
        list.add("str3");

        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            String str = iterator.next();
            System.out.println(str);
        }

for循环
一般不使用

Collection<String> list=new ArrayList<String>();
        list.add("str1");
        list.add("str2");
        list.add("str3");


        for (Iterator<String> it= list.iterator(); it.hasNext();){
            String str = it.next();
            System.out.println(str);
        }

使用迭代器清空集合

Collection<String> list=new ArrayList<String>();
        list.add("str1");
        list.add("str2");
        list.add("str3");


        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            iterator.next();
            iterator.remove();
        }

注意:
1、如果迭代器已经指向集合的末尾,如果再调用next()返回NoSuchElementException 异常。

2、在使用remove()之前必须使用next()方法

3、在对集合进行迭代过程中,不允许出现对元素的非迭代器操作,因为这样会产生安全隐患。在集合遍历中,使用迭代器操作集合对象时,又使用集合其它API操作集合时,将会抛出并发修改异常(ConcurrentMo dificationException>。

三、List

List是一个有序的集合,它按元素加入到集合中的顺序依次摆放。注意:不是按集合中对象的属性排序,而是按插入位置的顺序

List的特点:
1、元素有序
2、元素有下标
3、元素可重复
4、遍历时存入顺序和取出顺序一致

1、特有方法

增加 void add(int index,E element 指定位置添加元素
boolean addAll(int index,Collection c) 指定位置添加集合
修改 E set(int index,E element) 返回的时需要替换的集合中的元素
删除 E remove(int index) 删除指定位置的元素
获取 E get(int index) 获取指定下标的元素,注意IndexOutOfBoundsException
int indexOf(Object o) 找到该元素第一次出现的下标,找不到返回-1
int lastIndexOf(Object o) 找到该元素最后一次出现的下标,找不到返回-1
List subList(index fromIndex,int toIndex) 求子集和,[fromIndex,toIndex)
迭代 listIterator()

(1) 常用功能

List<String> list=new ArrayList<>();
        list.add("str1");
        list.add("str2");
        list.add("str3");
        list.add("str4");
        list.add(1,"str5");//把元素添加到指定位置
        System.out.println("集合中的元素为"+list);
        String s = list.get(0); //根据索引获取元素
        
        //使用get方法遍历集合
        for (int i = 0; i < list.size(); i++) {
            String s1 = list.get(i);
            System.out.println(s1);
        }
        
        list.set(3, "str333");  //替换指定位置的元素
        
        list.remove(0); //删除指定位置的元素

        int indexOf = list.indexOf("str1"); //元素第一次出现的下标
        
        int index= list.lastIndexOf("str"); //元素最后一次出现的下标

        List<String> subList = list.subList(1, 3);//子集

(2)ListIterator

ListIterator是list集合特有的迭代器,支持在迭代过程添加和修改元素

hasPrevious() 判断是否存在上一个元素
previous() 当前指针先向上移动一个单位,然后取出当前指针指向的元素
next() 先取出当前指针指向的元素,然后指针向下移动一个单位
add(E e) 把元素插入到当前指针指向的位置上
set(E e) 替换迭代器最后依次返回的元素

代码示例:

List<String> list=new ArrayList<>();
        list.add("str1");
        list.add("str2");
        list.add("str3");
        list.add("str4");

        ListIterator<String> iterator = list.listIterator();    //返回的是一个List接口中特有的迭代器

        System.out.println("是否存在上一个元素:"+iterator.hasPrevious());
        iterator.next();
        System.out.println("获取上一个元素:"+iterator.previous());

        iterator.set("ss"); //替换迭代器最后一次返回的元素
        while (iterator.hasNext()){//向后遍历
            String value = iterator.next();
            System.out.println(value);
            iterator.add("s");  //遍历时添加元素
        }
        
        while (iterator.hasPrevious()){//向前遍历
            System.out.println(iterator.previous());
        }

(3)集合遍历

List<String> list=new ArrayList<>();
        list.add("str1");
        list.add("str2");
        list.add("str3");
        list.add("str4");
        
        //get方法遍历
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
        }
        
        //forEach遍历
        for (String value:list
             ) {
            System.out.println(value);
        }
        
        //迭代器遍历
        ListIterator<String> iterator = list.listIterator();    //获取到迭代器
        while (iterator.hasNext()){
            String value = iterator.next();
        }

2、ArrayList

在实际开发中,ArrayList是使用频率最高的一个集合实现类

(1) 原理
ArrayList底层维护了一个Object[ ]数组用于存储对象,默认数组的长度是10。当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来容量的1.5倍。

由于底层使用数组实现,在增加和删除的时候会牵扯到数组的增容和拷贝元素,所以效率比较慢。但是数组可以直接按索引查找元素,所以查找时比较快。

3、LinkedList

(1)原理
由于LinkedList在底层使用链表实现存储结构,需要让上一个元素记住下一个元素,所以每个元素中保存的有下一个元素的位置。虽然LinkedList中也有下标,但是查找的时候需要从头往下找,显然没有数组查找快。但是链表在插入新元素的时候,只需让前一个元素记住新元素,新元素记住下一个元素,所以插入较快
(2)特有方法

addFirst(E e) 增加到集合最前面
addLast(E e) 增加到集合最后面
getFirst() 获得集合中的第一个元素
getLast() 获得集合的最后一个元素
removeFirst() 移除集合中第一个元素,如果没有
removeLast() 移除集合中最后一个元素,如果没有
descendingIteratort() 返回逆序的迭代器对象

4、Vector

Vector是一个线程安全的集合。它和ArrayList特性相似,较少使用
(1) 特有方法

void addElement(E obj) 在集合末尾添加与那苏
E elementAt(int index) 返回指定下标的元素
Enumeration elements() 返回集合中所有的元素,封装到Enumeration对象中

四、set

1、Set

set元素是无序存放的,即元素存入和取出的顺序不一定相同,并且集中中的元素不能重复。其中HashSet是一种常用的Set。

Set的特点
1、Set中的元素无序,但可以排序
2、Set中的元素无下标
3、set中的元素不可重复

(1) 存储原理
Set中的对象不是按元素加入到集合中的先后顺序依次摆放的,因此Set中没有索引,也不能按索引访问集合中的对象。

在Set内部的存储结构使用了散列算法,按对象的散列值决定存放的位置,也按照散列值检索对象。由于散列值的无序特点,因此Set的行为表现为一个无序的集合。
原理总结:
1、HashSet调用对象的hashCode()方法得到对象的hashCode值,并依据hashCode值确定该对象在HashSet中存放的位置
2、HashSet判断两个对象是否相等的依据:两个对象通过equals()方法比较结果为相等,并且两个hashCode()方法得到对象的hashCode值也相等
3、规则:如果相隔对象通过equals()方法比较结果为相等,那么两个对象的hashCode()方法得到的hashCode值也应该相等
(2)重复元素
在java中,重复元素使用Object类中得hashCode和equals判断。在类中重写了hashCode和equals,当两个得hashCode和equals返回相同值并且equals返回true时,两个对象相等。
常见重复元素
1、所有null常量都是重复元素
2、相同对象得不同引用变量是重复元素
3、两个String对象得值相同时,认为这两个对象是重复的

2、HashSet

使用Set 集合都是需要去掉重复元素的。如果在存储的时候逐个equals()比较,效率较低,哈希算法提高了去重复的效率,降低了使用equalst)方法的次数。当HashSet 调用add()方法存储对象的时候,先调用对象的 hashCode()方法得到一个哈希值,然后在集合中查找是否有哈希值相同的对象,如果没有哈希值相同的对象就直接存入集合,如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals(]比较,比较结果为 false就存入,true则不存入。

3、TreeSet

Treeset是 Sortedset接口的唯一实现类,Treeset可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。
所有加入TreeSet的元素必须实现Comparable接口,否则会抛出异常,在Treeset内部使用comparable接口对元素排序。和 Hashset相比,它的效率较低。

int compareTo(Object o) 大于返回正数,等于返回零,小于返回负数

4、LinkedHashSet

LinkedHashset是具有可预知迭代顺序的set接口的哈希表和链接列表实现。此实现与HashSet的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序。

五、Map

在集合框架中,Map于Collection是并列存在的,相互没有继承关系

Map的特点:
1、采用key/value的形式存储数据
2、Map中key不可重复
3、各个键值对无序
4、各个键值对无下标

1、Map

(1)基本操作
Map是一种按照键(key)存储元素的容器,键(可以)可以是任意类型的对象,所有value按key存储和获取

V put( K key,V vlue) 按key增加value。如果Map中已经有相同的key,则返回以前的对象,并使用value覆盖原来的对象
putAll(Map<? extends K,? extends V> m 将参数m中的所有key/value对加入到集合中
remove(key) 删除key对应的key/value对
value get(key) 按key获取value,如果没有匹配到key则返回null
dear() 清空集合对象
boolean isEmpty() 判断集合中是否有元素,有则返回true,没有返回false
int size() 返回Map中key/value对的个数
boolean containsKey(Object key) 判断集合中是否包含指定的key
boolean containsValue(Object value) 判断集合中是否包含指定的value

(2)遍历操作

Set keySet() 获得所有key组成的Set集合
Collection values() 获取所有values组成的集合
Set<Map.Entry<k,v>> entrySet() 获取所有Map.Entry组成的集合。
Map.ENtry由key、value组成,通过getKey、getValue获取键和值

使用keySet

这是最常用的Map迭代实现方式
将key转成Set集合(keySet()),通过迭代器取出Set集合中的每一个key,再通过key获取对应的value。

代码示例:

Map<String,Integer> map=new HashMap<>();
        map.put("Tom", 18);
        map.put("Jack", 30);
        map.put("Will", 25);

        Set<String> set = map.keySet();
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            String key = iterator.next();
            Integer value = map.get(key);
            System.out.println(key+" "+value);

        }

使用values()

Map<String,Integer> map=new HashMap<>();
        map.put("Tom", 18);
        map.put("Jack", 30);
        map.put("Will", 25);

        Collection<Integer> values = map.values();
        Iterator<Integer> iterator = values.iterator();
        while (iterator.hasNext()){
            Integer value = iterator.next();
            System.out.println(value);
        }

使用Map.Entry对象

Map<String,Integer> map=new HashMap<>();
        map.put("Tom", 18);
        map.put("Jack", 30);
        map.put("Will", 25);

        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Integer> entry = iterator.next();
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+": "+value);
        }

2、HashMap

HashMap是使用最广泛的Map实现,它的底层是哈希表数据结构实现存储,不支持多线程同步,可以存入null键,null值。
        HashMap<String,String> hashMap=new HashMap<>();
        hashMap.put(null, null);
        hashMap.put("张三", "成都");
        hashMap.put("李四", "大理");
        hashMap.put("王二", "兰州");
        System.out.println(hashMap);

3、LinkedHashMap

LinkedHashMap底层使用链表实现

       LinkedHashMap<String,String> hashMap=new LinkedHashMap<>();
        hashMap.put(null, null);
        hashMap.put("张三", "成都");
        hashMap.put("李四", "大理");
        hashMap.put("王二", "兰州");
        System.out.println(hashMap);

4、TreeMap

HashMap中的所有数据都是无序存放的,在TreeMap中按照key进行排序。要求key必须实现Comparable接口,具体要求见TreeSet中的实现要求

六、工具类

1、Collections

Collections不是Collection接口的实现类,它是一个工具类,其中所有方法都是静态的。
(1)List集合操作

功能 方法 描述
二分查找 int binarySearch(list,key) 集合中都是Comparable的实现类且元素都要按升序排列
排序 sort(list) 集合中元素都是Comparable的实现类
顺序反转 reverse(list)
强行逆转 Comparator reverseOrder(Comparator) 按Comparator比较方式逆转
位置交换 swap(list,x,y) 按索引位置交换
元素替换 replaceAll(list,old,new) 如果被替换的元素不存在,那么原集合不变

(2) 其它工具方法

最大值 max(Collection)
max(Collection,comparator)
最小值 min(Collection)
min(Collection,comparator)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340