集合
之前学到的数组就是一种容器,但是数组这种容器增删数组中的元素不是很方便,为了更方便的去操作(增删改查)容器中的元素,给我们提供了另外一个容器,叫做集合。
数组 | 集合 |
---|---|
可以储存基本数据也可以储存引用数据类型 | 储存引用数据类型 |
一但定义长度不可变 | 长度可变 |
之能储存同一种数据类型 | 可储存多种数据类型 |
Collection集合的功能概述
a:基本功能
boolean add(Object obj) | 添加一个元素 |
---|---|
boolean addAll(Collection c) | 添加一个集合的元素 (给一个集合添加进另一个集合中的所有元素) |
b:删除功能
void clear(): | 移除所有元素 |
---|---|
boolean remove(Object o) | 移除一个元素 |
boolean removeAll(Collection c) | 移除一个集合的元素(移除一个以上返回的就是true) 删除的元素是两个集合的交集元素 如果没有交集元素 则删除失败 返回false |
c:判断功能
boolean contains(Object o) | 判断集合中是否包含指定的元素 |
---|---|
boolean containsAll(Collection c) | 判断集合中是否包含指定的集合元素(这个集合 包含 另一个集合中所有的元素才算包含 才返回true) |
boolean isEmpty() | 判断集合是否为空 |
d:获取功能
Iterator iterator()(重点)
e:长度功能
int size():元素的个数
f:交集功能
例如:A集合对B集合取交集,获取到的交集元素在A集合中。返回的布尔值表示的是A集合是否发生变化 boolean
retainAll(Collection c):获取两个集合的交集元素(交集:两个集合都有的元素)
g:把集合转换为数组
Object[] toArray()
集合的遍历之集合转数组遍历
toArray() 把一个集合转成数组
其实就是依次获取集合中的每一个元素。
Collection collection = new ArrayList();
collection.add(s1);
collection.add(s2);
collection.add(s3);
Object[] objects = collection.toArray();
这就将集合collection转化为数组objects
有数组的遍历,就有集合的迭代,这就需要迭代器
迭代器(Iterator)
用来遍历数据结构
例:
public class MyTest {
public static void main(String[] args) {
Collection collection1 = new ArrayList();
collection1.add("一班");
collection1.add("二班");
collection1.add("三班");
collection1.add("六班");
Iterator iterator = collection1.iterator();
Object next = iterator.next();//手动移动
while (iterator.hasNext()){
Object obj= iterator.next();
System.out.println(obj);
}
}
}
Iterator接口的子接口(ListIterator)
ListIterator特有的方法
boolean hasPrevious(): //是否存在前一个元素
E previous(): //返回列表中的前一个元素
注意:以上两个方法可以实现反向遍历 但是注意 要完成反向遍历之前 要先进行正向遍历 这样指针才能移到最后,如果直接反向遍历是没有效果的 因为指针默认位置就在最前面 他前面没有元素。
并发修改异常(ConcurrentModificationException)出现的原因
用Iterator这个迭代器遍历采用hasNext方法和next方法,集合修改集合 会出现并发修改异常.
原因是我们的迭代依赖与集合 当我们往集合中添加好了元素之后 获取迭代器 那么迭代器已经知道了集合的元素个数,这个时候在遍历的时候又突然集合里面加一个元素(用的是集合的add方法) 那迭代器不会识别 就报错了
那么要怎么解决这个问题呢?
用ListIterator迭代器遍历 用迭代器自带的add方法添加元素 那就不会报错了
- 迭代器修改元素(ListIterator的特有功能add)
- 使用for循环遍历,然后增添或者删减
Collection的子接口List
List集合特有的功能
void add(int index,E element) //在指定索引处添加元素
E remove(int index) //移除指定索引处的元素
E get(int index) //获取指定索引处的元素
E set(int index,E element)// 更改指定索引处的元素
List的三个子类
- 三个子类(ArrayList,Vector,LinkedList)之间的区别:
- ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。 - Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。 - LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
- ArrayList特有的方法功能
void forEach(Consumer<? super E> action) :
执行特定动作的每一个元素的Iterable直到所有元素都被处理或操作抛出异常
- Vector特有的方法功能
public void addElement(E obj) //将指定的数据类型添加到此向量的末尾,使其大小增加1.
public E elementAt(int index) //在指定的索引处加入指定的数据类型
public void setElementAt(E obj, int index) //将指定索引处的组件设置为指定的对象
public boolean removeElement(Object obj) //移除索引最小的匹配项
- LinkedList特有的方法功能
public void addLast(E e) //将指定的元素插入集合的末尾
public E getFirst() //返回此集合的第一个元素
public E getLast() //返回此集合的最后一个元素
public E removeFirst() //移除此集合的第一个元素
public E removeLast() //移除此元素的最后一个元素
泛型
- 泛型类
public class 类名<泛型类型1,…>
注意:泛型类型必须是引用类型
- 泛型方法
public <泛型类型> 返回类型 方法名(泛型类型 变量名)
3.泛型接口
public interface 接口名<泛型类型>
4.泛型通配符
- 通配符<?> 任意类型,如果没有明确,那么就是Object以及任意的Java类了
- ? extends E //(向下限定,E及其子类)
- ? super E //(向上限定,E及其父类)
例:
public class MyTest2 {
public static void main(String[] args) {
ArrayList<Dog> objects = new ArrayList<Dog>();
//?泛型统配符
ArrayList<?> objects2 = new ArrayList<Cat>();
//向上限定
ArrayList<? super Animal> objects3 = new ArrayList<Animal>();
ArrayList<? super Animal> objects4 = new ArrayList<Object>();
//向下限定
ArrayList<? extends Animal> objects5 = new ArrayList<Dog>();
ArrayList<? extends Animal> objects6= new ArrayList<Cat>();
ArrayList<? extends Animal> objects7 = new ArrayList<Animal>();
}
}
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{}