目录
Collections类里面包括动态、有序、可变大小的一维数组Vector与ArrayList。
集合概述
(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:本文部分内容引用了网络上他人的文章内容,加以自身理解自行整理而成,仅为分享学习经验,如有侵权请私信我,侵权必删。
标签:Java,int,元素,List,Collection,接口,集合 From: https://blog.csdn.net/weixin_68489989/article/details/140039669