Java集合

目录

集合概述

集合接口

Collection接口

List接口

Set接口

泛型标记符

集合类

ArrayList

常用方法

LinkedList

HashSet

LinkedHashSet类

TreeSet类

集合遍历

Iterable接口

Iterator接口

ListIterator接口

使用迭代器

增强的for循环

Collections工具类

Collections类里面包括动态、有序、可变大小的一维数组Vector与ArrayList。

遗留的集合类和接口

Vector类


集合概述

(1)集合是存储其他对象的特殊对象。可以将集合当做一个容器。

(2)集合的相关接口和类位于java.util包中

(3)集合中的接口和类是一个整体、一个体系。

        Java中的集合就像一个容器,专门用来存储Java对象(实际上是对象的引用,但习惯称为对象),这些对象可以是任意的数据类型,并且长度可变。其中,这些集合类都位于java.util包中,在使用时一定要注意导包的问题,否则就会出现异常。

        集合按照其存储结构可以分为两大类,即单列集合Collection和双列集合Map,这两种集合的特点具体如下:

        Collection:单列集合的根接口,用于存储一系列符合某种规则的元素。Collection集合有两个重要的子接口,分别是List和Set。其中,List集合的特点是元素有序、可重复;Set集合的特点是元素无序并且不可重复。List接口的主要实现类有ArrayList和LinkedList;Set接口的主要实现类有HashSet和TreeSet。

        Map:双列集合的根接口,用于存储具有键(Key)、值(Values)映射关系的元素。Map集合中每个元素都包含一对键值,并且Key是唯一的,在使用Map集合时可以通过制定的Key找到对应的Value。例如根据一个学生的学号就可以找到对应的学生。Map接口的主要实现类有HashMap和TreeMap。

集合体系核心结构

虚线框里都是接口类型,实线框里填写的都是具体的实现类。

集合接口

接口定义了一组抽象方法,实现该接口的类需要实现这些抽象方法,从而实现接口的类就具备了接口所规定的行为(功能)。

集合框架定义了一些接口,它们决定了集合类的本质特性。具体的集合类只是提供了标准接口的不同实现。

接  口

描  述

Collection

允许操作一组对象,它位于集合层次结构的顶部

List

扩展Collection,以处理序列(对象列表)

Set

扩展Collection,以处理组,组中的元素必须唯一

注意:

Set类型的集合(实现Set接口的类)称为集,有些资料称为组,其特点是组中的元素必须唯一。

Java集合类主要由两个根接口Collection和Map派生出来的。

Collection派生出了三个子接口:

1)List

List代表了有序可重复集合,可直接根据元素的索引来访问

2)Set

Set代表无序不可重复集合,只能根据元素本身来访问

3)Queue

Queue是队列集合

Map接口派生:

Map代表的是存储key-value对的集合,可根据元素的key来访问value。

因此Java集合大致也可分成List、Set、Queue、Map四种接口体系。

Collection接口

Collection接口是构建集合框架的基础,Collection是泛型接口,其声明如下:

interface Collection,

其中,E指定了集合将存储的对象类型。

提示:

集合中只能存储对象,不能存基本类型。

使用泛型的优点是在编译时可以检查元素的类型,从而更加安全。

Collection接口扩展了Iterable接口。这意味着所有集合都可以使用for-each风格的for循环进行遍历。

方  法

描  述

boolean add(E obj)

将obj添加到调用集合。

boolean addAll(Collection c)

将c中的所有元素添加到调用集合中。

boolean remove(Object obj)

从调用集合中删除obj的一个实例。

boolean removeAll(Collection c)

从调用集合中删除c的所有元素。

void clear()

删除调用集合中的所有元素

boolean contains(Object obj)

如果obj是调用集合的元素,则返回true。

boolean isEmpty()

如果调用集合为空,则返回true。

int size()

返回调用集合中元素的数量

Iterator iterator()

返回调用集合的一个迭代器

containAll(Collection c)

提示:

1、Collection接口中没有提供修改元素的方法。

2、Collection接口的父接口是Iterable接口,实现了Iterable接口的类是可以迭代的。

List接口

List接口扩展了Collection,并且声明了存储一连串元素的集合的行为。在列表中,可以使用从0开始的索引,通过它们的位置插入或访问元素。列表可以包含重复的元素。其声明如下:

interface List

方  法

描  述

void add(int index, E obj)

将obj插入到index所指定的位置。

boolean addAll

(int index, Collection c)

将c的所有元素插入到index所指定的位置。

E remove(int index)

删除index位置的元素

E set(int index, E obj)

将index所指定位置的元素设置为obj

E get(int index)

返回指定索引处存储的对象

int indexOf(Object obj)

返回第一个obj实例的索引。

int lastIndexOf(Object obj)

返回列表中最后一个obj实例的索引

ListIterator listIterator()

返回一个迭代器,该迭代器从列表的开头开始

ListsubList(int start,int end)

返回一个子列表。

注意:

List接口中操作元素的方法许多都提供了index参数,这是与Collection接口中所提供相关方法的主要区别。

Set接口

Set接口定义了组/集/集合(set)。它扩展了Collection接口,并声明了不允许重复元素的集合的行为。如果为集合添加重复的元素,add()方法会返回false。声明如下:

interface Set

Set接口没有添加自己的方法。

SortedSet接口扩展了Set接口,并且声明了以升序进行排序的集合的行为。

interface SortedSet

SortedSet定义了一些便于进行集合处理的方法。例如,为了获得集合中的第一个对象,可以调用first()方法。为了得到最后一个元素,可以使用last()方法。

NavigableSet接口扩展了SortedSet接口,并且该接口声明了支持基于最接近匹配原则检索元素的集合行为。

注意:

Set相关接口表示的集合没有索引的概念。

泛型标记符

  • E - Element (在集合中使用,因为集合中存放的是元素)
  • T - Type(Java 类)
  • K - Key(键)
  • V - Value(值)
  • N - Number(数值类型)
  • ? - 表示不确定的 java 类型

集合类

描  述

ArrayList

动态数组

LinkedList

链表

ArrayDeque

双端队列 = 队列 + 堆栈

PriorityQueue

支持基于优先级的队列

HashSet

使用哈希表存储元素的组

LinkedHashSet

扩展HashSet类,以允许按照插入的顺序进行迭代

TreeSet

实现存储于树中的集合。

ArrayList

常用方法

方法

作用

返回值类型

add(E e)

将指定的元素添加到此列表的尾部。

boolean

add(int index, E element)

 将指定的元素插入此列表中的指定位置。

void

addAll(Collection c)

按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。

boolean

addAll(int index, Collection c)

从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。

boolean

clear()

移除此列表中的所有元素。

void

get(int index)

返回此列表中指定位置上的元素。

E

indexOf(Object o)

 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。

int

lastIndexOf(Object o)

返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。

int

isEmpty()

如果此列表中没有元素,则返回 true

boolean

remove(int index)

移除此列表中指定位置上的元素。

E

remove(Object o)

移除此列表中首次出现的指定元素(如果存在)。

boolean

removeRange(int fromIndex, int toIndex)  

移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。

protected  void

set(int index, E element)

用指定的元素替代此列表中指定位置上的元素。

E

size()

返回此列表中的元素数。

int

LinkedList

LinkedList类实现了List、Deque以及Queue接口。它提供了(双向)链表数据结构。

LinkedList具有两个构造方法:

LinkedList( )

LinkedList(Collection c)

ArrayList与LinkedList的区别:

1、ArrayList是基于数组结构的集合,有容量的概念;LinkedList是基于链表结构的集合,没有容量的概念

2、对于随机访问(get和set方法),ArrayList优于LinkedList,因为LinkedList要移动指针。

3、对于新增和删除操作(add和remove方法),LinkedList比较占优势,因为ArrayList要移动数据。但是如果只是在末尾追加元素,效率差不多。

4、LinkedList 还实现了Queue接口,该接口比List提供了更多的方法,包括 offer(),peek(),poll()等。

HashSet

HashSet类实现了Set接口。该类在内部使用哈希表存储元素。

哈希表使用称之为散列法(hashing)的机制存储信息。哈希法的优点是add()、contains()、remove()以及size()方法的执行时间保持不变,即使是对于比较大的集合也是如此。

HashSet( )  //默认容量是16

HashSet(int capacity)

HashSet(int capacity, float fillRatio)  //填充率:0.0-1.0之间,默认0.75

HashSet(Collection c)

HashSet中元素不是按有序的顺序存储的,遍历输出HashSet中的元素时精确的输出可能不同。

初始容量 倒是好理解,顾名思义,初始容量只是哈希表在创建时的容量,那么“加载因子”到底是表示什么意思呢?

如果按术语来讲: 加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。如果当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行rehash()操作,从而哈希表将具有大约两倍的桶数。

还不是很懂???

其实说白了加载因子 就是一个比例值。

例子:

比如说向水桶中装水,此时HashMap就是一个桶, 这个桶的容量就是加载容量,而加载因子就是你要控制向这个桶中倒的水不超过水桶容量的比例,比如加载因子是0.75 ,那么在装水的时候这个桶最多能装到3/4 处,超过这个比例时,桶会自动扩容。因此,这个桶最多能装水 = 桶的容量 * 加载因子。

如果桶的容量是16,加载因子是0.75 那么你的桶最多能装16*0.75 = 12的水,如果你装了12的水还想继续装水,那么就该用大一点的桶,调用rehash就是负责增加桶的容量的方法,当然这个rehash这个方法是内部调用的。

LinkedHashSet类

LinkedHashSet类扩展了HashSet类,它没有添加它自己的方法。

LinkedHashSet在内部使用一个链表维护元素添加到集合中的顺序,因此可以按照插入顺序迭代集合。

TreeSet类

TreeSet类实现了NavigableSet接口,该类在内部使用树结构存储元素。元素以升序存储,访问和检索相当快。TreeSet适合于存储大量的、必须能够快速查找到的有序信息。

Set与List的区别:

1、Set中的元素无序不能重复,List中的有序元素可以重复。

2、List有索引(下标)的概念,Set没有索引的概念。

3、对于Set表示的集合,通常是遍历操作,没有get()和set()方法。

注意:

TreeSet以升序保存对象,所以TreeSet中保存的对象比较能够比较大小,即TreeSet保存的对象类型必须实现Comparable接口。

注意:

HashSet是无序的,LinkedHashSet和TreeSet是有序的。

集合遍历

Iterable接口

实现了Iterable接口的类是可以遍历的。因为Iterable接口是Collection接口的父接口,而所有集合类都实现了Collection接口,从而也都实现了Iterable接口,所以所有集合类都是可以遍历的。

Iterable接口只定义了一个方法:

Iterator  iterator()  //返回迭代器对象

既然所有集合都实现了Iterable接口,所以所有集合类都重写了iterator()方法以返回一个迭代器对象。

Iterator接口

Iterator接口描述了迭代器的行为,所有迭代器类都必须实现该接口,该接口定义了一下方法:

boolean  hasNext()   如果迭代还有更多的元素则返回true

T  next()            返回下一个元素

void  remove()       删除迭代器返回的元素

提示:

从Iterator接口定义的方法不难看出Iterator只能从前向后进行遍历。

ListIterator接口

Iterator接口有一个子接口ListIterator,ListIterator接口即可以从前向后遍历,也可以从后向前遍历集合。只有实现了List接口的集合类才提供了ListIterator迭代器。

List接口提供以下两个方法用于获取列表集合的列表迭代器:

ListIterator listIterator()  该迭代器从列表的开头开始

ListIterator listIterator(int index)  该迭代器从index所指定的位置开始

ListIterator接口定义了以下常用方法。

boolean  hasNext()

Boolean  hasPrevious()

E  next()

int  nextIndex()

E  previous()

int  previousIndex()

使用迭代器

通常,为了使用迭代器遍历集合的内容,需要以下步骤:

1.通过调用集合的Iterator()方法,获取指向集合开头的迭代器。

2.建立一个hasNext()调用循环。只要hasNext()返回true,就循环迭代。

3.在循环中,通过调用next()获取每个元素。

对于实现了List接口的集合,还可以调用listIterator()获取迭代器。列表迭代器提供了向前和向后两个方向访问集合的能力,并且允许修改元素。

增强的for循环

如果不修改集合的内容,也不以反向获取元素,则使用for-each版的for循环遍历集合通常比使用迭代器更方便。

迭代器与增强的for循环之间的区别:

使用迭代器遍历集合时,可以调用Iterator.remove()方法删除集合中元素,使用增强的for循环遍历集合时,不能删除集合中的元素。

可以使用增强的for循环遍历数组,但是数组不支持迭代器。

使用增强的for循环遍历基本类型的数组时,只能使用数组元素,而不能修改数组元素。

Collections工具类

Collections类里面包括动态、有序、可变大小的一维数组Vector与ArrayList。

Collections提供以下方法对List进行排序操作

void reverse(List list):反转

void shuffle(List list),随机排序

void sort(List list),按自然排序的升序排序

void sort(List list, Comparator c);定制排序,由Comparator控制排序逻辑

void swap(List list, int i , int j),交换两个索引位置的元素

遗留的集合类和接口

在集合之前,Java提供了特定的类,存储和管理对象组,例如Dictionary、Vector、Stack和Properties。

早期版本的java.util包没有包含集合框架。反而,定义了几个类和接口,提供存储对象的专门方法。当添加集合时(由J2SE 1.2添加),对几个原始类进行了重新设计,以支持集合接口。因此,从技术上讲它们现在是集合框架的组成部分。

前面介绍的所有现代集合类都不是同步的,但是所有遗留类都是同步的。

Vector类

现在Vector类实现了动态数组,与ArrayList类似,也实现List接口。但有如下区别:

Vector实现同步,线程安全。ArrayList没有实现线程安全。

Vector性能比ArrayList低。

Vector和ArrayList在更多元素添加进来时会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%.

PS:本文部分内容引用了网络上他人的文章内容,加以自身理解自行整理而成,仅为分享学习经验,如有侵权请私信我,侵权必删。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码来码去(未来可期)

感谢您的打赏,我们一起进步

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值