Collection属于最上层的几口其中包含了许多子接口共有的方法 因此主要学习Collection接口中的方法
增:add() addAll()
删:remove() removeAll()
改: 没有
查: contains(Object) containsAll(Object)
其它 size() isEmpty() iterator() toArray() (转成Object类型数组) toArray(T[]) (转成指定类型数组) clear() equals() hashCode() retainAll()
没写的一般用不到
public class Test1 {
Collection<String> list = new ArrayList<String>();
Collection<String> list1 = new ArrayList<String>();
@Before
public void test1(){
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list1.add("C");
list1.add("D");
list1.add("E");
list1.add("F");
}
@Test
public void test2(){
list.addAll(list1);
System.out.println(list);
//移除list1中所有的,且包括list中存在的和list1中相同的
list.removeAll(list1);
System.out.println(list);
}
@Test
public void test3(){
list.addAll(list1);
//只移除第一个
list.remove("C");
System.out.println(list);
}
@Test
public void test4(){
boolean c = list.contains("C");
System.out.println(c);
boolean b = list.containsAll(list1);
System.out.println(b);
}
@Test
public void test5(){
boolean c = list.equals(list1);
System.out.println(c);
boolean b = list.retainAll(list1);
list.size();
list.isEmpty();
list.toArray();
list.toArray(new String[]{});
list.clear();
list.hashCode();
}
}
@Test
public void test5(){
Collection c1 = new ArrayList();
c1.add("张三");
c1.add("李四");
/*Collection c2 = new ArrayList();
c2.add("王五");*/
Collection c3 = new ArrayList();
c3.add("李四");
//求交集
// c1.retainAll(c2);
System.out.println("c1 = " + c1);
c1.retainAll(c3);
System.out.println("c1 = " + c1);
}
retainAll()返回值是一个布尔类型,但是 集合A.retainAll(集合B)会对集合A做修改,做完操作之后集合A中存在的是AB中共有的元素,如果没有交集,集合A就是空集合
遍历的两种方式
1> 增强for循环(本质也算是迭代器)
2> 迭代器遍历
Collection<String> c1 = new ArrayList<>();
c1.add("张三");
c1.add("李四");
for (String s : c1) {
System.out.println("s = " + s);
}
ArrayList<String> c1 = new ArrayList<>();
c1.add("张三");
c1.add("李四");
c1.add("王五");
c1.add("赵六");
c1.add("陈一");
Iterator<String> iterator = c1.iterator();
while (iterator.hasNext()){
String ele = iterator.next();
if(ele.equals("李四")){
//迭代器删除数据
iterator.remove();
}
}
自定义类实现迭代器遍历,需要实现Iterable接口,并重写iterator()方法
public class IteratorTest implements Iterable{
@Override
public Iterator iterator() {
return null;
}
}
class Test{
public static void main(String[] args) {
IteratorTest iteratorTest = new IteratorTest();
Iterator iterator = iteratorTest.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}
快速失败机制
当使用foreach或Iterator迭代器遍历集合时,同时调用迭代器自身以外的方法修改了集合的结构,例如调用集合的add和remove方法时,就会报ConcurrentModificationException。
这样设计是因为,迭代器代表集合中某个元素的位置,内部会存储某些能够代表该位置的信息。当集合发生改变时,该信息的含义可能会发生变化,这时操作迭代器就可能会造成不可预料的事情。因此,果断抛异常阻止,是最好的方法。这就是Iterator迭代器的快速失败(fail-fast)机制。
@Test
public void test02() {
ArrayList<String> c1 = new ArrayList<>();
c1.add("张三");
c1.add("李四");
c1.add("王五");
c1.add("赵六");
c1.add("陈一");
Iterator<String> iterator = c1.iterator();
while (iterator.hasNext()){
String ele = iterator.next();
if(ele.equals("李四")){
//迭代器删除数据
// iterator.remove();
c1.remove("李四");
}
}
System.out.println("----------------------------");
for (String s : c1) {
System.out.println("s = " + s);
}
}
@Test
public void test01(){
ArrayList<String> c1 = new ArrayList<>();
c1.add("张三");
c1.add("李四");
c1.add("王五");
c1.add("赵六");
c1.add("陈一");
//modcount = 5
Iterator<String> iterator = c1.iterator();
while (iterator.hasNext()){
String ele = iterator.next();
if(ele.equals("李四")){
c1.remove(ele);
}
}
System.out.println(c1);
ConcurrentModificationException:并发修改异常
在集合遍历时 不能删除集合元素可以在遍历时使用迭代器中的remove() 进行删除
modCount:代表对集合结构改变的次数
删除或者新增的次数
expectedModCount: 期待的modCount 5
源码分析
(debug调试)
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void fastRemove(int index) {
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
}
Iterator接口中的三个方法
hasNext() 判断当前元素是否存在
next() 返回当前元素 并将指针指向下一个元素
练习1
添加100以内的质数到Collection的某个集合中
使用foreach遍历
使用Iterator遍历,并删除个位数是3个质数
删除11
查看最后剩下几个元素
添加10个100以内的随机整数到另一个Collection的集合中
求它们的交集
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
public class Test {
public static void main(String[] args) {
//获取100以内的质数
ArrayList list = prime();
//foreach遍历
System.out.print("100以内的质数: ");
for (Object o : list) {
System.out.print(o + " ");
}
System.out.println();
//iterator遍历并删除各位是3的质数
System.out.print("100以内的质数: ");
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Integer num = (Integer)iterator.next();
if (num % 10 == 3 || num == 11){
iterator.remove();
}else {
System.out.print(num + " ");
}
}
System.out.println();
//查看元素还剩下
System.out.println("元素还剩下" + list.size());
//生成100以内的随机整数
Random random = new Random();
ArrayList<Integer> list1 = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list1.add(random.nextInt(100));
}
System.out.println(list1);
list.retainAll(list1);
System.out.println("交集为: " + list);
}
public static ArrayList prime(){
ArrayList<Integer> list = new ArrayList<>();
//获取100以内的质数
int count = 0;
l:
for (int i = 2; i < 100; i++) {
boolean flag = true;
for (int j = 2; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
flag = false;
continue l;
}
}
if (flag){
list.add(i);
}
}
return list;
}
}