集合
-
1、容器:存储数据
- 变量–>数组:多态数组(数据类型、长度)–>集合
-
2、特点
- a. 集合的长度是可变的
- b. 集合中存储的必须是对象 10(Integer)
- c. 集合存储数据的类型灵活度,要比数组高
-
3、 分类
- 单列集合 Collection (存储单个数据)
- 双列集合 Map (存储的键值对:key-value)
-
4、 Collection集合的体系结构图
Collection 容器
- 新建容器
-
Collection coll=new ArrayList();//Collection是个接口只能创建子类对象
-
- 增
- add(Object obj); 添加数据
-
coll.add("java");
-
- addAll(Collection coll2);//将coll2中的所有数据添加到coll1中 批量添加
-
Collection coll1=new ArrayList(); Collection coll2=new ArrayList(); coll2.add("java"); coll2.add(12); coll1.addAll(coll2);//将coll2中的所有数据添加到coll1中 批量添加
-
- add(Object obj); 添加数据
- 删
- remove(Object obj) 移除指定对象
-
Collection coll1=new ArrayList(); coll1.add("java"); coll1.add(12); coll1.add(3.5); coll1.add(true); Collection coll2=new ArrayList(); coll2.add("mysql"); coll2.add(12); coll2.add(3.5); coll2.add(false); coll2.add(3.5); coll1.add(coll2); System.out.println(coll1);//[java, 12, 3.5, true, [mysql, 12, 3.5, false, 3.5]] coll2.remove(12); coll1.remove(coll2);//会从coll1中移除整体coll2,如果找不到这个整体就什么操作都不做 System.out.println(coll1);//[java, 12, 3.5, true]
-
- removeAll(Collection coll2);//将coll2中的数据从coll1中移除
-
coll1.add(coll2); System.out.println(coll1);//[java, 12, 3.5, true, [mysql, 12, 3.5, false, 3.5]] coll1.removeAll(coll2);//将coll2中的数据从coll1中移除 System.out.println(coll1);//[java, 12, true]对于每一个数据移除一次
-
- clear() 清空
- remove(Object obj) 移除指定对象
- 改
- 没有提供修改方法
- 查
- coll.isEmpty();//是否为空
- coll.size();//返回对象个数
- coll.contains(Object obj);//判断是否包含指定对象
- containsAll(Collection coll2) 是否包含coll2中所有对象
- 求交集
- retainAll(coll2);//求两个集合的交集
Iterator
-
1、 在当前集合上添加一个迭代器
Iterator iter = coll1.iterator(); -
2、判断下一个位置是否有值
iter.hasNext() -
3、 取出下一个位置的值,并将指针移动一位
iter.next()移除方法:iter.remove(); 移除iter指向的那个数据
-
第一种遍历方式 Iterator(迭代器)
-
while(iter.hasNext()){ Object next = iter.next(); System.out.println(next); }
-
-
第二种遍历方式 foreach(增强for循环) 也能遍历数组
-
语法:for(数据类型 对象名:容器){
} -
案例:循环一次就从coll1中取一个对象赋值给obj,直到coll1中所有值取完为止
-
for(Object obj:coll1){ System.out.println(obj); }
-
-
-
只要实现Iterable这个接口的数据,就可以作为foreach冒号后面的类型,foreach不一定只能操作实现Iterable这个接口的数据
为什么在遍历的过程中不能对集合进行修改(移除、新增)?
- 1、 Iterator iter = coll.iterator();
- Iterator是一个接口 iterator()中 -->return new Itr();
- new Itr() 会初始化Itr的普通属性
-
int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount;//将当前集合的版本进行了 赋值
- 2、 在集合操作过程中,size:集合的对象个数 modCount:标记版本
- 3、 hasNext()
public boolean hasNext() {
return cursor != size; //判断cursor是否已经达到size(cursor在next方法中会自增)
} - 4、next()
-
public E next() { checkForComodification();//检查版本 --> 此方法才是我们在遍历集合时不能够对集合进行修改的原因 int i = cursor;//将当前游标的值赋值给i if (i >= size)//判断当前i是否超出集合的对象个数 throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData;//将集合中的数组进行备份 if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1;//将游标的值进行加1 return (E) elementData[lastRet = i];//返回对象 } PS: 检查版本 此方法才是我们在遍历集合时不能够对集合进行修改的原因 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
- 5、 iter.remove(); 这个为什么可以移除呢? 会对集合的版本进行更新操作
-
public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet);//会执行删除操作 modCount值会改变 cursor = lastRet; lastRet = -1; expectedModCount = modCount;//但是此处会将expectedModCount的值重新赋为新modCount的值 } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
-
- 6、直接remove()
-
private void fastRemove(int index) { //这里修改了modCount,但不能操作expectedModCount, //在Iterator 遍历中会导致版本号不同,无法删除 modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
-
- foreach()的底层也是Iterator ,所以使用foreach()遍历是也不能直接使用对象名删除数据
List接口
- 1、 List
-
a. 特点
- 允许重复
- 有顺序(添加顺序) 意味着存在下标的概念
-
b. List接口中有哪些常用的方法
- 增
- add(Object obj);添加obj对象
- addAll(Collection coll);添加coll集合
- add(int index,Object obj);在集合的指定索引位置插入数据
- addAll(int index,Collection coll);在集合的指定索引位置批量插入数据
- 删
- remove(Object obj)//删除和这个对象相同的所有对象
- remove(int index) 移除指定索引位置的对象 如果删除的数据是int型,需要手动装箱
- removeAll(Collection coll);//删除一个Collection 对象
- clear()//清空
- 改
- set(int index, Object obj) 修改指定索引位置的对象
- 查
- isEmpty()//是否为空
- size()//长度
- contains(Object obj)//是否存在obj
- containsAll(Collection coll)//是否存在coll集合
- get(int index) 返回指定索引位置的对象
- indexOf(Object obj) 返回集合中第一次出现指定对象的索引值
- lastIndexOf(Object obj) 返回集合中最后次出现指定对象的索引值
- 交集
- retainAll(Collecton coll) 去交集
- 增
-
c. List集合的遍历方式
-
1、 Iterator
-
Iterator iter = list.iterator(); while(iter.hasNext()){ System.out.println("++"+iter.next()); }
-
-
2、 foreach
-
for (Object object : list) { System.out.println("--"+object); }
-
-
3、 for循环
-
for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
-
-
4、 ListIterator(了解)
-
-
Set接口
- 1、Set集合的实现类 HashSet TreeSet LinkedHashSet
- 特点:无序(添加顺序)且不可重复
- HashSet: 有自己的排序机制hash值,不允许重复(怎么实现的)
- TreeSet: 有自己的排序机制:大小顺序 (数据类型必须相同)
- 特点:无序(添加顺序)且不可重复
- 2、 Set集合中的常用方法
- 没有独有的方法,全部来自于Collection
- 3、 遍历方式和Collection也是一致的