总结
文章目录
认识集合类
集合类最顶层不是抽象类而是接口,因为接口代表的是某个功能,而抽象类是已经快要成形的类型,不同的集合类的底层实现是不相同的,同时一个集合类可能会同时具有两种及以上功能(既能做队列也能做列表),所以采用接口会更加合适,接口只需定义支持的功能即可。
数组与集合
相同之处:
- 它们都是容器,都能够容纳一组元素。
不同之处:
- 数组的大小是固定的,集合的大小是可变的。
- 数组可以存放基本数据类型,但集合只能存放对象。
- 数组存放的类型只能是一种,但集合可以有不同种类的元素。
集合根接口Collection
public class Test {
public static void main(String[] args) {
Collection c = new ArrayList();
//添加元素
c.add("张三");
c.add(19);
System.out.println("c集合的元素个数为:" + c.size());
//删除指定元素
c.remove(19);
System.out.println("c集合的元素个数为:" + c.size());
// 判断是否包含指定字符串
System.out.println("c集合是否包含\"张三\"字符串:"+c.contains("张三"));
c.add("李四");
System.out.println("c集合元素"+c);
Collection books = new HashSet();
books.add("张三");
books.add("王五");
System.out.println("c集合是否完全包含books集合:"+c.containsAll(books));
// 控制books集合里只剩下c集合里也包含的元素
books.retainAll(c);
System.out.println("books集合的元素:" + books);
// 用c集合减去books集合里的元素
c.removeAll(books);
System.out.println("c集合的元素个数为:" + c);
// 删除c集合里所有元素
c.clear();
System.out.println("c集合的元素个数为:" + c);
}
}
结果
Map映射
lambda便利
public class Test {
public static void main(String[] args) {
Collection books = new HashSet();
books.add("a");
books.add("b");
books.add("c");
// 调用forEach()方法便利
books.forEach(o -> System.out.println("迭代集合:"+o));
}
}
结果
Iterator 接口
注意:
1.每次使用完再次使用都要重新获得迭代器
Collection books = new HashSet();
Iterator it = books.iterator();
//···
//迭代内容
//···
it = books.iterator();//重新获得
2.对迭代器的内容修改不要直接对集合修改(中文可能不会报错(但不意味着可以使用))
remove的区别
中文特殊情况
特殊情况:remove最后一个元素不会出错
本质:Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来集合的单链索引表,当原来的集合数量发生变化时,这个索引表的内容不会同步改变,当索引指针往后移动的时候就找不到要迭代的对象,按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的,但可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性
it.remove();//
System.out.println(book.hashCode());
books.remove(book);//
System.out.println(book.hashCode());
import java.util.Iterator;
import java.util.HashSet;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
//创建集合依旧
Collection books = new HashSet<>();
books.add("语文");
books.add("数学");
books.add("英语");
//获取books集合对应的迭代器
Iterator it = books.iterator();
while ((it.hasNext())){
// it.next()方法返回的数据类型是Object类型,因此需要强制类型转换
String book = (String) it.next();
System.out.println(book);
if(book.equals("英语")){
it.remove();
}
}
System.out.println(books);
}
}
3.Iterator中的 FailFast FailSafe
FailFast FailSafe
Iterator 仅用于遍历集合,本身并不提供像集合类那样装对象的能力。Iterator 是个接口,如果需要创建其对象,必须有一个被迭代的集合,没有集合的 Iterator 没有存在的价值。
Iterator 必须依附于 Collection 对象,有一个 Iterator 对象,肯定就有一个与之关联的 Collection 对象