List集合特点
添加的元素是有序、可重复、有索引 ArrayLsit、LinkedList Set集合特点
添加的元素是无序、不重复、无索引
HashSet:无序、不重复、无索引 LinkedHashSet:有序、不重复、无索引 TreeSet:按照大小默认升序排序、不重复、无索引 Collection集合常用方法
ArrayList、LinkedList、HashSet、LinkedHashSet、TreeSet集合都可以调用下面的方法 Collection集合遍历方式
迭代器
增强For forEach
Collection < String > c = new ArrayList < > ( ) ;
c. add ( "赵敏" ) ;
c. add ( "小昭" ) ;
c. add ( "素素" ) ;
c. add ( "灭绝" ) ;
c. forEach ( new Consumer < String > {
@Override
public void accept ( String s) {
System . out. println ( s) ;
}
} ) ;
c. forEach ( s-> System . out. println ( s) ) ;
List集合常用方法
List集合是有索引的,所以有针对索引的方法 List集合遍历方法
普通for循环(因为有索引) 迭代器 增强for Lambda表达式
List < String > list = new ArrayList < > ( ) ;
list. add ( "蜘蛛精" ) ;
list. add ( "至尊宝" ) ;
list. add ( "糖宝宝" ) ;
for ( int i = 0 ; i< list. size ( ) ; i++ ) {
String e = list. get ( i) ;
System . out. println ( e) ;
}
for ( String s : list) {
System . out. println ( s) ;
}
Iterator < String > it = list. iterator ( ) ;
while ( it. hasNext ( ) ) {
String s = it. next ( ) ;
System . out. println ( s) ;
}
list. forEach ( s-> System . out. println ( s) ) ;
重点:ArrayList底层的原理
ArrayList集合底层是基于数组结构实现的,也就是说当你往集合容器中存储元素时,底层本质上是往数组中存储元素。 数组的特点:查询快,增删慢
查询快:根据索引查询快 删除效率低:后面的数据要前移 添加效率低:后面的数据要后移,可能要进行数组扩容 ArrayList底层扩容原理
数组扩容,并不是在原数组上扩容(原数组是不可以扩容的),底层是创建一个新数组,然后把原数组中的元素全部复制到新数组中去。 重点:LinkedList底层原理
LinkedList底层是基于双向链表实现的 链表的特点:查询慢,增删快
查询慢:无论从哪个数据都要从头开始找 增删快:链表增删相对块,只需要重新指向新的节点地址就行了 双向链表特点:针对头尾增删特别快 新增了一些针对头尾进行操作的方法
ArrayList 和 LinkedList 查询 增删 底层剖析
ArrayList查询:头 中 尾 都很快,按值查找–时间复杂度O(n) ArrayList插入:尾部非常快,头部,中间很慢
尾部很快是因为直接插入数组[length++] 头部中间慢是因为要进行数组移动 LinkedList查询:头尾快,中间慢
底层调用node()方法,把index和mid会进行一次判断,是从头遍历还是尾遍历,所以越靠近中间越慢 LinkedList插入
头部插入调用add方法,add方法里面判断是linklast还是linkBefore,这个根据node()来判断 尾部linkLast(E e)方法,可以看出,在尾部插入的时候,并不需要从头开始遍历整个链表,因为已经事先保存了尾结点,所以可以直接在尾结点后面插入元素。 LinkedList的应用场景 LinkedList实现队列
LinkedList < String > queue = new LinkedList < > ( ) ;
queue. addLast ( "第1号人" ) ;
queue. addLast ( "第2号人" ) ;
queue. addLast ( "第3号人" ) ;
queue. addLast ( "第4号人" ) ;
System . out. println ( queue) ;
System . out. println ( queue. removeFirst ( ) ) ;
System . out. println ( queue. removeFirst ( ) ) ;
System . out. println ( queue. removeFirst ( ) ) ;
System . out. println ( queue. removeFirst ( ) ) ;
1 2 3 4
< -- -- --
LinkedList实现栈
LinkedList < String > stack = new ArrayList < > ( ) ;
stack. push ( "第1颗子弹" ) ;
stack. push ( "第2颗子弹" ) ;
stack. push ( "第3颗子弹" ) ;
stack. push ( "第4颗子弹" ) ;
System . out. println ( stack) ;
System . out. println ( statck. pop ( ) ) ;
System . out. println ( statck. pop ( ) ) ;
System . out. println ( statck. pop ( ) ) ;
System . out. println ( statck. pop ( ) ) ;
System . out. println ( list) ;
4 3 2 1
-- -- -- 》
3 2 1
2 1
1
关于Java异常 分类:编译异常和运行异常 NumberFormatException 是 RuntimeException 的子类 catch顺序是顺序执行 异常的体系 关于try–catch–finally 要么try catch 要么 try finally 可以有多个catch 关于遍历删除list元素的问题 遍历删除list元素时候,应该从后往前遍历
for ( int i = list. size ( ) - 1 ; i >= 0 ; i-- ) {
if ( "java" . equals ( list. get ( i) ) ) {
list. remove ( i) ;
}
}
如果我们从前往后遍历
for ( int i = 0 ; i < list. size ( ) ; i++ ) {
if ( "java" . equals ( list. get ( i) ) ) {
list. remove ( i) ;
}
}
这就会导致索引改变了,我们刚删除一个,list的数组就改变了,整体前移
关于ConcurrentModificationException异常 如果我们在用迭代器遍历一个list时候,去修改它,会破坏迭代器的一致性,就会抛出这个异常