Java基础-集合
java集合框架图
如上图可以看出java集合可以分为Collection和Map两大接口
1 | * @see Set |
1 | public interface Collection<E> extends Iterable<E> { |
1 | public interface Map<K,V> { |
常用的实现类有 ArrayList、
LinkedList、
HashSet以及
HashMap
ArrayList
1
2
3
4
5
6
7
8
9public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
ArrayList的初始容量为10;但是它的容量可以动态增长;当添加元素达到容量上限时会自动扩容会原始容量的1.5倍
1 | List arrayList = new ArrayList();无参构造实例化;初始容量值10; |
如上也可以手动初始化容量
常用方法:
方法 | 描述 |
---|---|
boolean add(E e) | 将元素插入到集合的末尾 |
void add(int Index, E element) | 将元素插入到指定索引位置,原先索引位置后面的元素依次向后移动 |
void clear( ) | 清空集合中所有元素 |
boolean contains(Object o) | 判断集合中是否包含此指定元素,一般用于去除重复元素(Set无重复!!!) |
boolean remove(Object o) | 删除指定元素 |
E remove(int index) | 删除指定索引位置的元素 |
E set(int index, E element) | 将元素替换到指定索引位置,和add方法有区别 |
E get(int index); | 获取指定索引位置的元素,比较常用 |
boolean isEmpty( ) | 判断集合是否为空 |
int size(); | 获取集合中元素个数 |
Object[ ] toArray( ) | 获取集合中所有元素组成的对象数组 |
List |
获取集合中起止位置元素所组成的子列表(不包含末尾位置) |
由于ArrayList的抽象父类(AbstractCollection)重写了toString方法,因此可以直接以集合名的方式直观的获取集合中的所有元素
1 | public String toString() { |
可以直观的看出使用了迭代器的方式
2.Iterator
方法 | 描述 |
---|---|
boolean hasNext() | 如果仍有元素可以迭代,则返回 true |
E next() | 返回迭代的下一个元素 |
void remove() | 从迭代器指向的 collection 中移除迭代器返回的最后一个元素 |
迭代器的remover方法还有很大考究门道,过段时间再细究
2020-07-08更新
先贴一段代码:
1 | List<String> list = new ArrayList<>(); |
运行结果:
1 | list-----[烬, 李青, 劫, 盖伦] |
每次调用next()方法,都会得到一个值,那么这个迭代的过程就会相应向后走一步(打个可能不是很恰当的比喻,数一一个队伍,数了一个之后,相应的会向后面移动一步。。。)上面的这段代码可以看成是首先用next();数了 最前面的”烬”, 打印的结果便是 “烬” , 然后调用remove();把这个 “烬” 移除队伍,那么此时队伍就变成了[李青, 劫, 盖伦],接着判断是否还可以数,—->( [李青, 劫, 盖伦] 可以继续数—->)执行,接着数了”李青”并把它放到另一个队伍中去(向后走一步),再判断是否还可以数,—>( [李青, 劫, 盖伦] 可以继续数—->) 执行,此时注意”李青”已经数过了,下一个数的就是”劫”,打印的结果也是劫,接着remove();把这个 “劫” 移除队伍; 这时队伍变成了[李青, 盖伦]再最后数了“盖伦”并同时也将其放到另一个队伍中去,综上队伍已经全部数完(方法不再执行);那么最后原先的队伍就从[烬, 李青, 劫, 盖伦]变成了[李青, 盖伦],相应的另一个队伍里也是[李青, 盖伦]。。。
此处用这个放到另一个队伍的比喻不是很恰当,但目的是为了表明这个next();执行的效果—>迭代的过程会相应向后走一步
千人千面,每个人的理解都各不相同,但是最后的明白的都是同一个道理(多搞两把代码打上断点走一遍)
1 | next();和remove();是相互依存的,调用remove();之前必须先调用next();否则会抛出java.lang.IllegalStateException |
3.LinkedList
ArrayList 类常用方法与 List 接口基本相同,LinkedList 类则比 List 接口多了一些方便操作 头元素和尾元素的方法
常用方法如下:
方法 | 描述 |
---|---|
void addFirst(E e) | 把新元素插入到列表中的最前位置 |
void addLast(E e) | 与上与之相反 |
E getFirst( ) | 获取列表中最前位置的元素 |
E getLast( ) | 与上与之相反 |
E peek( ) | 获取列表中最前位置的元素,但此元素仍保留在列表中 |
E peekFirst( ) | 获取列表中最前位置的元素,但此元素仍保留在列表中 E |
E peekLast( | 与上与之相反 |
E poll( ) | 获取列表中最前位置的元素,同时把此元素从列表中删除 |
E pollFirst( ) | 获取列表中最前位置的元素,同时把此元素从列表中删除 |
E pollLast( | 获取列表中最后位置的元素,同时把此元素从列表中删除 |
void push(E e) | 把指定元素压入到栈顶 |
E pop( ) | 从栈中弹出栈顶元素 |
ArrayList 的内部实现是基于内部数组 Object[],类似于可变长的数组。LinkedList 的内部 实现是基于一组连接的记录,类似于一个链表结构。 在 ArrayList 的前面或中间插入数据时,必须将其后的所有数据相应的后移,花费较多时间,所以,当程序添加元素主要是在后面,并且需要随机地访问其中的元素时,优先使用 ArrayList 会得到比较好的性能;
访问 LinkedList 中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地 去查找,直到找到所需的元素为止,但在添加元素到原有元素中间时效率很高,所以,当程序需要经常在指定位置添加元素,并且按照顺序访问其中的元素时,优先使用 LinkedList(随机访问的效率比较低)
4.HashSet
HashSet 类是将元素存储在散列表中,适合用于不需要有序的元素序列,并能实现快速查 找特定元素。如果想要提高 HashSet 的性能,可以指定 HashSet 中元素的个数;如果大约知道 HashSet 中最终会插入多少元素,可以把元素个数设置为其值的 1.5 倍;如果元素过多,将导 致 HashSet 检索性能下降
HashSet();方法的源码:
1 | public class HashSet<E> |
以上只是无参构造方法HashSet();其后还有一些有参构造方法,无一例外都是通过 new HashMap()的方式得到的
HashSet的常用方法有如下:
方法 | 描述 |
---|---|
boolean add(E e) | 如果指定的元素尚不存在,则将其添加到该集合中 |
boolean contains(Object o) | 如果此集合包含指定的元素,则返回 true,否则返回 false |
boolean isEmpty() | 如果此集合不包含任何元素,则返回 true,否则返回 false |
Iterator |
返回此集合中元素的迭代器 |
boolean remove(Object o) | 从该集合中删除指定的元素 |
int size() | 返回此集合中的元素数量 |
就常用方法而言,Set 接口与 Collection 接口基本一致
HashSet类里并无获取元素的方法,只能通过Set里面的Iterator 获取
所有的Collection都实现了 Iterator
接口