目录
1,Java集合概要
- Collection是一个接口,Collection下面主要有三个接口分支,List,Set,Queue。
- 为了方便,我们抽象出了AbstractCollection抽象类,它实现了Collection中的绝大部分函数;这样,在Collection的实现类中,我们就可以通过继承AbstractCollection省去重复编码。AbstractList和AbstractSet都继承于AbstractCollection,具体的List实现类继承于AbstractList,而Set的实现类则继承于AbstractSet。
-
Collection中有一个iterator()函数,它的作用是返回一个Iterator接口。通常,我们通过Iterator迭代器来遍历集合。ListIterator是List接口所特有的,在List接口中,通过ListIterator()返回一个ListIterator对象,其实Java中的LinkedList底层是基于双向链表的实现。
-
Java中的集合框架大类可分为Collection和Map
-
两者的区别:
-
Collection是单列集合;Map是双列集合。
-
Collection中只有Set系列要求元素唯一;Map中键需要唯一,值可以重复。
-
Collection的数据结构是针对元素的;Map的数据结构是针对键的。
-
-
-
Collection集合体系:
- Collection是一个接口,Collection下面主要有三个接口分支,List,Set,Queue
-
而Set是数学概念中的集合,Set中没有重复元素,元素存取无序。(存取无序,元素无索引,元素不可重复)
-
无下标 Set集合下面有:
HashSet,LinkedHashSet,TreeSet。
-
HashSet:
存储无序,元素无索引,元素不可以重复.底层是哈希表.-
那哈希表是怎么来保证元素的唯一性的呢,哈希表是通过hashCode和equals方法来共同保证的。
-
哈希表的存储数据过程(哈希表底层也维护了一个数组):根据存储的元素计算出hashCode值,然后根据计算得出的hashCode值和数组的长度进行计算出存储的下标;如果下标的位置无元素,那么直接存储;如果有元素,那么使用要存入的元素和该元素进行equals方法,如果结果为真,则已经有相同的元素了,所以直接不存;如果结果假,那么进行存储,以链表的形式存储。
-
在向HashSet集合中存储自定义对象时,为了保证set集合的唯一性,那么必须重写hashCode和equals方法。
-
-
LinkedHashSet:
是基于链表和哈希表共同实现的,所以具有存取有序,元素唯一不可重复。 -
TreeSet:基于二叉排序树
-
存取无序,元素唯一不可重复,可以进行排序(排序是在添加的时候进行排序)。
-
TreeSet是基于二叉树的数据结构,一个节点下不能多余两个节点。
-
二叉树的存储过程:如果是第一个元素,那么直接存入,作为根节点,下一个元素进来是会跟节点比较,如果大于节点放右边的,小于节点放左边;等于节点就不存储。后面的元素进来会依次比较,直到有位置存储为止。
-
TreeSet保证元素的唯一性是有两种方式:
-
(自然排序)自定义对象实现Comparable接口,重写comparaTo方法,该方法返回0表示相等,小于0表示准备存入的元素比被比较的元素小,否则大于0;
-
(比较器排序)在创建TreeSet的时候向构造器中传入比较器Comparator接口实现类对象,实现Comparator接口重写compare方法。
-
如果向TreeSet存入自定义对象时,自定义类没有实现Comparable接口,或者没有传入Comparator比较器时,会出现ClassCastException异常。
-
-
-
-
List:List和Set都是接口,它们继承于Collection。List是有序的序列,List中可以有重复的元素,可以根据元素的索引进行取值;(存取有序,元素有索引,可重复)
-
List接口的具体实现类有:ArrayList,LinkedList,Vector
(已过时)。 -
ArrayList: 底层是使用数组实现,所以查询速度快,增删速度慢。
-
LinkedList:是基于双向链表结构实现的,所以查询速度慢,增删速度快,提供了特殊的方法,对头尾的元素操作(进行增删查),线程不安全,效率高。
-
Vector:因为已经过时,被ArrayList取代了;它还有一种迭代器通过vector.elements()获取,判断是否有元素和取元素的方法为:
hasMoreElements(),nextElement()
。数组结构,查询快,增删慢,线程不安全,效率高。
-
-
- Collection是一个接口,Collection下面主要有三个接口分支,List,Set,Queue
-
Map集合体系:Map的特点:是存取无序,键不可重复
-
Map是一个双列集合,其中保存的是键值对,键要求保持唯一性,值可以重复。
-
键值是一一对应的,一个键只能对应一个值。
-
Map在存储的时候,将键值传入Entry,然后存储Entry对象。
-
其中下面有
HashMap,LinkedHashMap和TreeMap
-
HashMap:
-
是基于哈希表结构实现的,所以存储自定义对象作为键时,必须重写hasCode和equals方法。存取无序的。
-
-
LinkedHashMap:
-
用法跟HashMap基本一致,它是基于链表和哈希表结构的,所以具有存取有序,键不重复的特性。
-
-
TreeMap:
-
给TreeMap集合中保存自定义对象,自定义对象作为TreeMap集合的key值。由于TreeMap底层使用的二叉树,其中存放进去的所有数据都需要排序,要排序,就要求对象具备比较功能。对象所属的类需要实现Comparable接口。或者给TreeMap集合传递一个Comparator接口对象。
-
-
-
2,Collection接口的介绍
- Collection集合总体布局:
在package java.util包中Collection的定义如下:
public interface Collection<E> extends Iterable<E> {}
- 特点
- 它是一个接口,是高度抽象出来的集合,它包含了集合的基本操作:添加、删除、清空、遍历(读取)、是否为空、获取大小、是否保护某元素等等。
- Collection接口的所有子类(直接子类和间接子类)都必须实现2种构造函数:不带参数的构造函数 和 参数为Collection的构造函数。带参数的构造函数,可以用来转换Collection的类型。
- Collection接口的方法
//返回集合中元素的个数
int size();
//如果集合中没有包含元素就返回true
boolean isEmpty();
//判断集合中是否包含某一个对象
boolean contains(Object o);
//返回某一个集合的迭代器
Iterator<E> iterator();
//把集合转换为一个数组,包含集合中的所有元素
Object[] toArray();
<T> T[] toArray(T[] a);
//向集合中添加一个元素
boolean add(E e);
//删除集合中的某一个元素
boolean remove(Object o);
//判断当前的集合是否包含某一个集合中的所有元素
boolean containsAll(Collection<?> c);
//把指定集合的所有元素添加到当前的集合中
boolean addAll(Collection<? extends E> c);
//如果指定集合中的元素存在于当前的集合,就全部删除
boolean removeAll(Collection<?> c);
//删除集合中所有满足条件的元素,1.8之后的方法
default boolean removeIf(Predicate<? super E> filter) ;
//求两个集合的交集,也就是保留指定集合中的元素在当前的集合中
boolean retainAll(Collection<?> c);
//清除集合中的所有元素
void clear();
boolean equals(Object o);
//返回集合的哈希码
int hashCode();
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
//1.8之后的方法
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
//1.8之后的方法
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
3,List接口介绍
在package java.util包下List接口的定义如下:
public interface List<E> extends Collection<E> {}
- 特点:
- List是一个继承于Collection的接口,即List是集合中的一种。List是有序的序列,List中的每一个元素都有一个索引;第一个元素的索引值是0,往后的元素的索引值依次+1。和Set不同,List中允许有重复的元素,其中List的具体实现类有两种,ArrayList底层是基于数组的实现,而LinkedList底层是基于双向链表的实现,他们都有各子的优点和使用情形。
- 关于API方面。既然List是继承于Collection接口,它自然就包含了Collection中的全部函数接口;由于List是有序序列,它也额外的有自己的API接口。主要有“添加、删除、获取、修改指定位置的元素”、“获取List中的子队列”等。
- List接口方法
// Collection的API
abstract boolean add(E object)
abstract boolean addAll(Collection<? extends E> collection)
abstract void clear()
abstract boolean contains(Object object)
abstract boolean containsAll(Collection<?> collection)
abstract boolean equals(Object object)
abstract int hashCode()
abstract boolean isEmpty()
abstract Iterator<E> iterator()
abstract boolean remove(Object object)
abstract boolean removeAll(Collection<?> collection)
abstract boolean retainAll(Collection<?> collection)
abstract int size()
abstract <T> T[] toArray(T[] array)
abstract Object[] toArray()
// 相比与Collection,List新增的API:
//根据位置添加一个元素
abstract void add(int location, E object)
//将一个集合中所有元素添加到给定集合的位置
abstract boolean addAll(int location, Collection<? extends E> collection)
//获取给定位置的集合
abstract E get(int location)
//返回与指定元素相等的元素在列表中第一次出现的位置,如果没有这样的元素就返回-1
abstract int indexOf(Object object)
//返回与指定元素相等的元素在列表中最后一次出现的位置,如果没有这样的元素就返回-1
abstract int lastIndexOf(Object object)
//返回一个列表迭代器,用来访问列表中的元素,第一次调用这个迭代器的next会返回给定索引的元素
abstract ListIterator<E> listIterator(int location)
//返回一个迭代器
abstract ListIterator<E> listIterator()
//删除指定位置的元素
abstract E remove(int location)
//用一个新的元素替换给定位置的元素,并且返回原来的那个元素
abstract E set(int location, E object)
//截取列表子集
abstract List<E> subList(int start, int end)
4,Set集接口介绍
在package java.util包下Set集的定义如下:
public interface Set<E> extends Collection<E> {}
- 特点:
- Set是一个继承于Collection的接口,即Set也是集合中的一种。Set集的特点是没有重复元素的集合。
- 关于Set接口的api,和Collection基本一样。
- Set接口的方法
// Query Operations 查询集合操作
//返回集中元素的个数
int size();
//判断集是否是空
boolean isEmpty();
//判断集中是否包含某一个对象
boolean contains(Object o);
//返回集的迭代器用于遍历操作
Iterator<E> iterator();
//以数组的形式返回集中的所有元素,返回的是object数组
Object[] toArray();
//将集合中的元素转化为我们需要的类型返回,注意这里返回的是我们需要的类型,与上一个转换区分开
<T> T[] toArray(T[] a);
// Modification Operations 修改集合操作
//向集合中添加一个元素
boolean add(E e);
//从集合中删除元素操作
boolean remove(Object o);
// Bulk Operations 批量处理操作
//判断当前集合是否包含指定集合的所有元素
boolean containsAll(Collection<?> c);
//把指定集合中的元素添加到当前的集合中
boolean addAll(Collection<? extends E> c);
//从当前集合中删除所有不包含在指定集合中的元素
boolean retainAll(Collection<?> c);
//从当前集合中删除所有包含在指定集合中的元素
boolean removeAll(Collection<?> c);
//清除集合中的所有元素
void clear();
// Comparison and hashing 比较和散列操作
boolean equals(Object o);
int hashCode();
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.DISTINCT);
}
5,AbstractCollection抽象类介绍
在package java.util包下AbstractCollection的定义如下:
public abstract class AbstractCollection<E> implements Collection<E> {}
- 特点
- AbstractCollection是一个抽象类,它实现了Collection中除iterator()和size()之外的函数。
- AbstractCollection的主要作用:它实现了Collection接口中的大部分函数。从而方便其它类实现Collection,比如ArrayList、LinkedList等,它们这些类想要实现Collection接口,通过继承AbstractCollection就已经实现了大部分接口的方法了,不需全部重新把方法实现一遍。
- AbstractCollection的集成关系图
6,AbstractList抽象类介绍
在package java.util包下AbstractList的定义如下:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
- 特点
- AbstractList是一个继承于AbstractCollection,并且实现List接口的抽象类。它实现了List中除size()、get(int location)之外的函数。
- AbstractList的主要作用:它实现了List接口中的大部分函数。从而方便其它类继承List,另外,和AbstractCollection相比,AbstractList抽象类中,实现了iterator()接口。
- AbstractList的继承关系图
7,AbstractSet抽象集介绍
在package java.util包下AbstractSet抽象类的定义如下:
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {}
- 特点
- AbstractSet是一个继承于AbstractCollection,并且实现Set接口的抽象类。由于Set接口和Collection接口中的API完全一样,Set也就没有自己单独的API。AbstractSet类实现了equals(),hashcode(),removeAll()方法,其余的方法全部是继承于AbstractCollection类。
- AbstractSet的主要作用:它实现了Set接口中的大部分函数。从而方便其它类实现Set接口。
- AbstractSet的继承关系图
8,Iterator迭代器接口介绍
在package java.util包下Iterator的定义如下:
public interface Iterator<E> {}
- 特点
- Iterator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。Iterator提供的API接口,包括:是否存在下一个元素、获取下一个元素、删除当前元素。
- 注意:Iterator遍历Collection时,是fail-fast机制的。即,当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。
- Iterator接口的API
//判断集合中是否还有下一个元素
boolean hasNext();
//返回集合中的下一个元素,注意此方法要和hasNext()搭配使用
E next();
//删除上次调用next()方法返回时的元素
default void remove() {
throw new UnsupportedOperationException("remove");
}
//for-each遍历操作,1.8之后
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
注意:在做遍历的时候,我们可以认为迭代器是位于两个元素之间的,当调用next()方法的时候,迭代器就越过下一个元素,返回刚刚越过的那个元素的引用。
9,ListIterator子接口介绍
在package java.util包下ListIterator接口的定义如下:
public interface ListIterator<E> extends Iterator<E>{}
- 特点
- ListIterator是一个继承于Iterator的接口的子接口,它是队列迭代器。专门用于便利List,能提供向前/向后遍历。相比于Iterator,它新增了添加、是否存在上一个元素、获取上一个元素等等API接口。
- ListIterator接口的方法
// Query Operations
//判断集合中是否有下一个元素
boolean hasNext();
//前进一个位置,并且返回跳过元素的索引
E next();
//用于反向遍历时判断是否有前一个元素
boolean hasPrevious();
//向前移动一个元素并且返回上一个元素的索引
E previous();
//返回下一个元素的索引下标
int nextIndex();
//返回前一个元素的索引下标
int previousIndex();
// Modification Operations
//删除上次调用next()方法返回的那个元素
void remove();
//重新设置上次调用next()方法时返回的那个元素的值
void set(E e);
//在迭代器前面的位置添加一个元素
void add(E e);
参考资料:
[1] https://www.cnblogs.com/skywang12345/p/3308513.html