这一块的内容主要是有关Connection集合、iterator迭代器,以及List集合的内容。
集合
集合的概述
我们为什么要用集合:
一直从创建大数据进阶这个专栏到现在,写入的知识,有关容器的只有两个,一个是数组,一个是StringBuffer,而我们所学的Java,是一门面向对象的语言,面向对象是基于描述现实事物而存在的,一旦我们所用的数据多了起来,我们就必须要对这些对象进行存储,我们存储之后,就不能是定义一个遍历了,我们需要一个类似于数组这样的容器来进行存储。 到现在为止,已经记录了数组、StringBuffer。但都有一些弊端,StringBuffer的结果是一个字符串,我们在显示业务中,大多数都是以对象的形式进行存储,这样的话,StringBuffer就不满足了,只能选择数组,而数组存储的是对象引用,这样的对象称之为对象数组。 对象数组也不能满足我们一些业务需求的变化,因为数组的长度唯一,这时,为了适应变化,Java提供了一个技术来解决这样的问题,也就是:集合。
数组和集合的区别
- 长度:
数组的长度唯一 集合的长度不唯一、可变、弹性 - 内容不同:
数组存储的元素类型是一致的、统一的 集合可以存储不同类型的元素 - 元素的数据类型:
数组可以存储基本数据类型,也可以存储引用数据类型 集合只能存储引用数据类型
有关集合的一个小图
我们可以看到Collection、List都是接口,下面的Arraylist、LinkedList才是实现类
Connection集合
是所有集合的顶层接口,存在着一些可以重复元素的集合,一些不可以重复元素的集合,有些有序,有些无须
添加功能
- boolean add(E e) 确保此集合包含指定的元素(可选操作)。
- boolean addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合(可选操作)
boolean add(E e) :
Collection c = new ArrayList();
c.add("hello");
c.add("world");
System.out.println(c);
boolean addAll(Collection<? extends E> c)
Collection c = new ArrayList();
c.add("hello");
c.add("world");
System.out.println(c);
Collection c1 = new ArrayList();
c1.addAll(c);
System.out.println(c1);
删除功能
void clear() 从此集合中删除所有元素(可选操作)。 boolean remove(Object o) 从该集合中删除指定元素的单个实例(如果存在)(可选操作)。 boolean removeAll(Collection<?> c) 删除指定集合中包含的所有此集合的元素(可选操作)。
void clear()
Collection c = new ArrayList();
c.add("hello");
c.add("world");
System.out.println(c);
c.clear();
System.out.println(c);
boolean remove(Object o)
Collection c = new ArrayList();
c.add("hello");
c.add("world");
System.out.println(c);
c.remove("hello");
System.out.println(c);
boolean removeAll(Collection<?> c) 只删除包含该集合的元素: c中只删除了c1中和它重复的元素
public static void main(String[] args) {
Collection c = new ArrayList();
Collection c1 = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
System.out.println(c);
System.out.println("**********删除之后*************");
c1.add("hello");
c.removeAll(c1);
System.out.println(c);
}
}
判断功能
- boolean contains(Object o) 如果此集合包含指定的元素,则返回 true 。
- boolean containsAll(Collection<?> c) 如果此集合包含指定 集合中的所有元素,则返回true。
- boolean isEmpty() 如果此集合不包含元素,则返回 true 。
boolean contains(Object o)
Collection c = new ArrayList();
Collection c1 = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
System.out.println(c);
System.out.println(c.contains("hello"));
boolean containsAll c中包含了c1
Collection c = new ArrayList();
Collection c1 = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
System.out.println(c);
c1.add("hello");
System.out.println(c.containsAll(c1));
boolean isEmpty()
Collection c = new ArrayList();
Collection c1 = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
System.out.println(c);
System.out.println(c.isEmpty());
c.clear();
System.out.println(c.isEmpty());
集合的遍历
按照顺序一个一个取出元素,Object[] toArray()把集合转化成数组,可以实现集合的遍历 注意:遍历集合中的元素,里面的元素获取到之后需要向下转型
Collection c = new ArrayList<>();
c.add("hello");
c.add("world");
c.add("java");
Object[] objects = c.toArray();
for(int i=0;i<objects.length;i++){
String objects1 = (String) objects[i];
System.out.println(objects1);
}
}
}
使用集合的小案例
用集合存储五个学生对象,并且输出 1、创建学生类 2、创建集合 3、创建五个学生对象并赋值 4、将五个学生对象添加到集合当中 5、遍历集合
Collection c = new ArrayList();
Student1 s1 = new Student1("张三",21);
Student1 s2 = new Student1("李四",22);
Student1 s3 = new Student1("王五",23);
Student1 s4 = new Student1("赵六",24);
c.add(s1);
c.add(s2);
c.add(s3);
c.add(s4);
Object[] objects = c.toArray();
for(int i=0;i<objects.length;i++){
Student1 objects1 = (Student1) objects[i];
System.out.println(objects1.getName()+"---"+objects1.getAge());
}
}
}
有关iterator迭代器
Iterator iterator() 迭代器,集合的专用遍历方式 两个方法:
- boolean hasNext() 如果迭代具有更多的元素,就返回true
- E next() 返回迭代中的下一个元素,获取元素
NoSuchElementException - 如果迭代没有更多的元素,报这个错
迭代器遍历:
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
Iterator iterator = c.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
String next1 = (String) next;
System.out.println(next1);
}
}
}
使用迭代器遍历集合中的元素
Collection c = new ArrayList();
Student1 s1 = new Student1("张三", 21);
Student1 s2 = new Student1("李四", 22);
c.add(s1);
c.add(s2);
Iterator iterator = c.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
Student1 next1 = (Student1) next;
System.out.println(next1.getName()+"---"+next1.getAge());
}
}
}
使用迭代器遍历字符串中的元素
Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
Iterator iterator = c.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
String next1 = (String) next;
System.out.println(next1);
}
}
}
有关使用迭代器的一个小思考
我们可以看到,迭代器是遍历集合的一种方式,那为什么我们不把迭代器直接定义为一个类呢,这样直接用的话不是方便很多吗,为什么迭代器是一个接口呢。
迭代器源码
我们看到这里面,Collection和List一个继承于Iterable,一个继承于Collection,里面都有一个Iterator()方法,该方法时实现了Iterator接口,Iterator接口中有迭代器的hasNext()和next()方法,最后时Arraylist类中的Itr实现了迭代器的两个方法
public interface Iterator{
boolean hasNext();
Object next();
}
public interface Iterable{
Iterator iterator();
}
public interface Collection extends Iterable{
Iterator<T> iterator();
}
public interface List extends Collection{
Iterator iterator();
}
public class ArrayList implements List{
public Iterator iterator() {
return new Itr();
}
private class Itr implements Iterator{
public boolean hasNext(){}
public Object next(){}
}
}
List集合
- 特点:有序集合(存储和取出的顺序一致),可以有重复元素
List集合中字符串的遍历
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
String next1 = (String) next;
System.out.println(next1);
}
}
}
存储自定义对象并遍历
List list = new ArrayList();
Student1 s1 = new Student1("张三", 21);
Student1 s2 = new Student1("李四", 22);
list.add(s1);
list.add(s2);
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
Student1 next1 = (Student1) next;
System.out.println(next1.getName()+"---"+next1.getAge());
}
}
}
List集合添加功能
void add(int index, E element) 将指定的元素插入此列表中的指定位置(可选操作)
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
System.out.println(list);
list.add(1,"hadoop");
System.out.println(list);
List集合获取功能
E get(int index) 返回此列表中指定位置的元素。
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
System.out.println(list);
list.add(1,"hadoop");
System.out.println(list);
System.out.println(list.get(1));
删除功能
E remove(int index) 删除该列表中指定位置的元素(可选操作)。
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
System.out.println(list);
list.add(1,"hadoop");
System.out.println(list);
System.out.println(list.get(1));
System.out.println(list.remove(1));
修改功能
E set(int index, E element) 用指定的元素(可选操作)替换此列表中指定位置的元素
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
System.out.println(list);
list.add(1,"hadoop");
System.out.println(list);
System.out.println(list.get(1));
System.out.println(list.remove(1));
System.out.println(list);
list.set(1,"hadoop");
System.out.println(list);
列表迭代器
ListIterator listIterator() 返回列表中的列表迭代器(按适当的顺序)。 是List特有的迭代器,该迭代器继承了Iterator,所以也有hasNext和next方法 List是继承自Collection,有父类的功能,也有自己的特有功能: E previous() 返回列表中的上一个元素,并向后移动光标位置。 boolean hasPrevious() 返回 true如果遍历反向列表,列表迭代器有多个元素。 注意:如果想要逆序遍历,必须先正序遍历一次,才能逆序遍历,一般情况下无意义,一般不使用
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
ListIterator listIterator = list.listIterator();
while (listIterator.hasNext()){
Object next = listIterator.next();
String next1 = (String) next;
System.out.println(next1);
}
System.out.println("*********************");
while(listIterator.hasPrevious()){
Object previous = listIterator.previous();
String previous1 = (String) previous;
System.out.println(previous1);
}
}
}
特有功能:get、size
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println("********************");
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
System.out.println("********************");
for(int i=0;i<list.size();i++){
Object o = list.get(i);
String o1 = (String) o;
System.out.println(o1);
}
并发修改异常
我们现在有一个问题,我们打算判断集合中有没有“world”这个元素,如果有的话,我们就添加一个"hadoop" ConcurrentModificationException:并发修改异常。当方法里面检测到对象的并发修改的时候但是,这里不允许修改时,就会抛出这种异常 为什么会出现这种异常呢? 迭代器是依赖于集合存在的,在判断成功之后,集合中添加了新的元素,但是迭代器不知道,所以就报错了,这就是并发修改异常。 也就是说,迭代器遍历元素的时候,集合是不能修改元素的
怎么解决呢 1、迭代器遍历元素,迭代器修改元素 添加的元素紧跟在刚刚迭代到的元素后面 2、集合遍历元素,集合修改元素 添加的元素在最后一个
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
String next1 = (String) next;
if("world".equals(next1)){
list.add("hadoop");
}
}
或者这种情况也会出现并发修改异常(正确的代码里面,Iterator it = c.iterator() 应该放到c.add()后面,放到前面的话,就意味着先有了迭代器,之后再去修改数组,也会出现并发修改异常,也就是迭代器和数组不是同时被改变)
public static void main(String[] args) {
Collection c = new ArrayList();
Student1 s1 = new Student1("张三", 21);
Student1 s2 = new Student1("李四", 22);
Student1 s3 = new Student1("王五", 23);
Student1 s4 = new Student1("赵六", 24);
Student1 s5 = new Student1("张三", 28);
Iterator it = c.iterator();
c.add(s2);
c.add(s3);
c.add(s4);
c.add(s5);
while (it.hasNext()) {
Object next = it.next();
Student1 s = (Student1) next;
System.out.println(s.getName() + "---" + s.getAge());
}
}
}
并发修改异常的解决办法
使用集合遍历元素,集合修改元素 使用迭代器遍历元素,迭代器修改元素
List list = new ArrayList();
list.add("hello");
list.add("world");
ListIterator listIterator = list.listIterator();
for(int i=0;i<list.size();i++){
Object o = list.get(i);
String o1 = (String) o;
if("world".equals(o1)){
list.add("hadoop");
}
}
ListIterator listIterator1 = list.listIterator();
while (listIterator1.hasNext()){
Object next = listIterator1.next();
String next1 = (String) next;
System.out.println(next1);
}
感谢阅读,我是啊帅和和,一位大数据专业即将大四学生,祝你快乐。
|