集合是存放多个类型的数据
(1)集合是Java API所提供的一系列类,可以用于动态存放多个对象,集合只能存对象;
(2)集合与数组的不同在于集合是大小可变的序列,而且元素类型可以不受限制,只要是引用类型。(集合中不能存放基本数据类型,但可以存放基本数据类型的包装类);
(3)集合全部支持泛型,是一种数据安全的用法。
数组:一旦初始化,长度不可改变,只能存放声明数组时指定的类型,可以存放基本数据类型。
集合:大小可变的序列,元素类型可以不受限制,不可以存基本数据类型,可以存基本数据类型的包装类。
红颜色的是类,其余都是接口。
该接口定义了一些基本的增删改查的功能。
List接口:
继承关系:extends Collection
特点:元素有序且可重复
Set接口:
继承关系:extends Collection
特点:元素无序且不可重复
**注意:**如何理解有序和无序
有序:存入顺序和取出顺序是一致的
无序:存入顺序和取出顺序是不一致的
注:无序不代表随机
该接口定义了一些基本的增删改查的功能。
以键值对(Key - Value)
Collection:只能存单个值;可以遍历(可以获取迭代器);
Map:可以存两个值(Key - Value);不可以直接遍历(不可以获取迭代器);
遍历集合。
迭代器是接口。
Map没有获取迭代器的功能(Map不能直接遍历)。
public abstract class AbstractList<E>{
//操作数:只要操作了集合都会++
//被transient修饰的变量不参与序列化和反序列化。
protected transient int modCount = 0;//7
}
public ArrayList extends AbstractList<E> implements List{
//长度
private int size;//6
//存储数据的容器
private Object[] elementData = new Object[10];
public void add(E e){
elementData[size++] = e;
modCount++;
}
//获取迭代器的方法
public Iterator<E> iterator() {
return new Itr();
}
//实现类的对象指向接口的引用,就是多态
//成员内部类里可以调用外部类的所有属性
//静态内部类只能调用外部类的静态属性
private class Itr implements Iterator<E> {
int cursor;//0 游标
int lastRet = -1;
int expectedModCount = modCount;//7 modCount相当于ArrayList.this.modCount
//判断是否可以迭代
public boolean hasNext() {
return cursor != size;
}
@SupperessWarnings("unchecked")//注解:抑制警告小黄线
public E next() {
checkForComodification();//在这个方法里判断操作数是否等于迭代器操作数
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
final void checkForComodification() {
if (modCount != expectedModCount)
//手动抛出异常
throw new ConcurrentModificationException();
}
//迭代器中的删除元素的方法
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
//依赖于list的删除元素的方法
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
}
//看源码:找场景
迭代器分为:Interator 和 ListInterator
Interator:
Collection家族下都可以获取到此迭代器的对象
可以遍历集合
删除元素
ListInterator:
只有List家族下才可以都获取此迭代器的对象
可以遍历集合
删除元素
添加元素
替换元素
指定下标遍历
倒叙遍历
注意:
(1).在迭代器中利用list删除元素会报错。报错的原因是list中的modCount与迭代器中的expecteModCount不一致就会报错。
(2).如何不报错?
答:利用迭代器中删除元素的方法。 it.remove();
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
list.add("fff");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String e = it.next();
if(e.equals("ccc")){
//list.remove(e);
it.remove();//利用迭代器中删除元素的方法
}
}
for (String e : list) {
System.out.println(e);
}
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
list.add("fff");
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {
String e = (String) listIterator.next();
if (e.equals("ccc")) {
listIterator.add("宋刚");//添加宋刚
listIterator.remove();//删除ccc
listIterator.set("刘伟民");//替换为刘伟民
}
}
for (String e : list) {
System.out.println(e);
}
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
list.add("fff");
ListIterator<String> listIterator = list.listIterator(2);//从下标为2处开始遍历
while (listIterator.hasNext()) {
String e = (String) listIterator.next();
System.out.println(e);
}
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
list.add("fff");
ListIterator<String> listIterator = list.listIterator(list.size());
//判断是否有可迭代的前一个元素
while (listIterator.hasPrevious()) {
String previous = listIterator.previous();//返回上一个元素
System.out.println(previous);//倒序遍历
}
一种数据安全的做法。当不知道返回类型是什么的时候,可以在泛型中指定,泛型更灵活。
类型<数据类型> 对象名 = new 类名<>();
如:
ArrayList<Object> list = new ArrayList<>();
ArrayList<String> list = new ArrayList<>();
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Character> list = new ArrayList<>();
ArrayList<Object> list = new ArrayList<>();
ArrayList<Object> list = new ArrayList<Object>();
?表示所有(任何)类型
//?表示所有类型
public static ArrayList<?> method01() {
ArrayList<Object> list = new ArrayList<>();
//ArrayList list = new ArrayList<>();
//ArrayList list = new ArrayList<>();
return list;
}
? extends A :?表示类型是A类或其子类
//? extends A :?表示类型是A类或其子类
public static ArrayList<? extends A> method02() {
//ArrayList
//ArrayList list = new ArrayList<>();//子类
ArrayList<A> list = new ArrayList<>();//本身
return list;
}
? super A :?表示类型是A类或其父类
//? super A :?表示类型是A类或其父类
public static ArrayList<? super A> method03() {
//?表示所有类型
ArrayList