集合
概论
- 定义:集合与数组类似,只不过集合中的数据量可以动态的变化
- 分类
- Collection(接口) 单列
- List(接口)集合:存放的数据可以重复,并且有序
- Set(接口)集合:存放的数据无序且不可重复
- Map (接口)多列:双列,存放数据无序,key不可重复,value可重复
- Collection(接口) 单列
Collection集合的概述和使用
Collection概述
- Collection是单列集合层次结构中的根界面,是单列集合的顶层接口
- Collection表示一组对象,这些对象也称为Collection的元素
- JDK不提供此接口的任何直接实现,它提供更具体的子接口(List、Set)实现
创建Collection集合的对象
- 多态的方式
- 具体的实现类 ArrayList
//创建Collection集合的对象的方式:多态
public class Demo01 {
public static void main(String[] args) {
//创建Collection集合的对象
Collection<String> collection=new ArrayList();
//添加元素
collection.add("张三");
collection.add("李四");
collection.add("王五");
//输出集合对象
System.out.println(collection);//[张三, 李四, 王五]
}
}
Collection集合的常用方法
//移除指定元素
collection.remove("张三");
System.out.println(collection);//[李四, 王五]
//判断集合中是否包含某个元素
System.out.println(collection.contains("李四"));//true
//判断集合是否为空
System.out.println(collection.isEmpty());//fasle
//集合的长度
int size = collection.size();
System.out.println(size);//2
//清空集合
collection.clear();
System.out.println(collection);//[]
Collection集合的遍历
- Iterator:迭代器,集合的专用遍历方式
- Iterator iterator():返回集合中元素的迭代器,通过集合的iterator()方法得到,它依赖于集合存在
- hashNext():如果迭代器中有更多元素返回true,用来作为判断条件
- next():返回迭代器中的下一个元素,用来获取集合中的元素
public class Demo03 {
public static void main(String[] args) {
Student student1=new Student(1,"张三",18);
Student student2=new Student(2,"李四",19);
Student student3=new Student(3,"王五",20);
Collection<Student> collection=new ArrayList<>();
collection.add(student1);
collection.add(student2);
collection.add(student3);
Iterator<Student> iterator = collection.iterator();
/*
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
...
}
*/
while (iterator.hasNext()){
System.out.println(iterator.next());//Student{id=1, name='张三', age=18}
//Student{id=2, name='李四', age=19}
//Student{id=3, name='王五', age=20}
}
}
}
List
List集合的概述
- List集合是有序集合,也被称为序列,具有索引
- 用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
- 特点:
- 有序:存储和取出元素的顺序一致
- 可重复:存储的元素可以重复
List集合特有的方法
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("王五");
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());//张三 李四 王五 王五
}
//在集合的指定位置插入元素
list.add(4,"world");
System.out.println(list);//[张三, 李四, 王五, 王五, world]
//通过下标获取List集合中指定位置的元素
String s = list.get(1);
System.out.println(s);//李四
//修改指定索引处的元素
list.set(1,"hello");
System.out.println(list);//[张三, hello, 王五, 王五, world]
//删除指定索引处的元素
list.remove(3);
System.out.println(list);//[张三, hello, 王五, world]
}
List并发修改异常
- 产生原因:迭代器遍历过程中,通过集合对象修改了集合中元素的长度,造成了迭代器获取元素中判断预期修改值和实际修改值不一致
- 解决方案:foe循环遍历,然后对集合对象做对应的操作即可获在while循环中加入break语句
//测试List并发修改异常
public class ListDemo03 {
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("Hello");
list.add("world");
list.add("!");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String s=iterator.next();
if(s.equals("Hello")){
list.add("zs");//java.util.ConcurrentModificationException
break;
//解决方案:方案一:通过list的for循环
//方案二:加break;
/**
* 1、public void add(int index, E element) {
* rangeCheckForAdd(index);
*
* ensureCapacityInternal(size + 1); // Increments modCount!!
* System.arraycopy(elementData, index, elementData, index + 1,
* size - index);
* elementData[index] = element;
* size++;
* }
* 2、public Iterator<E> iterator() {
* return new Itr();
* }
* 3、 private class Itr implements Iterator<E> {
* int cursor; // index of next element to return
* int lastRet = -1; // index of last element returned; -1 if no such
* int expectedModCount = modCount;
* // modCount:实际修改集合的次数
* //expectedModCount:预期修改集合的次数
* @SuppressWarnings("unchecked")
* 3、1 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];
* }
* 3、2 final void checkForComodification() {
* if (modCount != expectedModCount)
* throw new ConcurrentModificationException();
* }
* }
*/
}
}
System.out.println(list);
}
}
ListIterator列表迭代器
- 通过List集合的listIterator()方法得到,是List集合特有的迭代器
- 用于允许程序员沿任意方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
- 特有方法
- hasPrevious()+previous()实现逆向遍历集合元素
- add(E e):添加指定元素到集合中,可解决List并发修改异常
//ListIterator
public static void main(String[] args) {
List<String> list=new ArrayList<>();
list.add("zs");
list.add("ls");
list.add("ww");
//获取ListIterator
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()){
System.out.print(listIterator.next()+"\t");//zs ls ww
}
System.out.println("======");
//通过ListIterator逆向遍历元素
while (listIterator.hasPrevious()){
System.out.print(listIterator.previous()+"\t");//ww ls zs
}
//listIterator.add()方法可解决之前的List并发修改异常
while(listIterator.hasNext()){
if(listIterator.next().equals("ls"))
// list.add("李四");会报java.util.ConcurrentModificationException
listIterator.add("李四");
/**
* 1、public ListIterator<E> listIterator() {
* return new ListItr(0);
* }
* 2、 private class ListItr extends Itr implements ListIterator<E> {
* public void add(E e) {
* checkForComodification();
*
* try {
* int i = cursor;
* ArrayList.this.add(i, e);
* cursor = i + 1;
* lastRet = -1;
* expectedModCount = modCount;
*
* //预期修改集合的次数=实际修改集合的次数,所有不会发生List并发修改异常
*
* } catch (IndexOutOfBoundsException ex) {
* throw new ConcurrentModificationException();
* }
* }
* }
*/
}
System.out.println(list);//[zs, ls, 李四, ww]
}
增强for循环
- 目的:简化数组和Collection集合的遍历
- 原理:一个Iterator迭代器
- 格式:for(元素数据类型 变量名:数组或Collection集合){
//在此处使用变量即可,该变量就是元素
}
//增强for循环
public class ListDemo05 {
public static void main(String[] args) {
int[] arr={1,2,3,9,8,7};
//数组增强for循环
for(int i:arr){
System.out.print(i+"\t");//1 2 3 9 8 7
}
List<String> list=new ArrayList<>();
list.add("zs");
list.add("ls");
list.add("ww");
list.add("bb");
//集合的增强for循环
for(String data:list){
System.out.print(data+"\t");//zs ls ww bb
}
System.out.println();
//验证其内部原理为iterator迭代器
for(String data:list){
if(data.equals("ls"))
list.add("小李");//java.util.ConcurrentModificationException
}
}
}
List集合子类特点
- ArrayList(常用):底层数据结构是数组,查询快、增删慢
- LinkList:底层数据结构是双向链表,增删快、查询慢
//List子类练习
public static void main(String[] args) {
//ArrayList
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("Hello");
arrayList.add("World");
arrayList.add(",");
arrayList.add("ArrayList");
for (String str : arrayList) {
System.out.print(str); //HelloWorld,ArrayList
}
System.out.println();
//LinkedList
LinkedList<String> linkedList=new LinkedList();
linkedList.add("Hello");
linkedList.add("World");
linkedList.add(",");
linkedList.add("LinkedList");
ListIterator<String> listIterator = linkedList.listIterator();
while (listIterator.hasNext()){
System.out.print(listIterator.next());//HelloWorld,LinkedList
}
}
LinkedList特有功能
//LinkedList集合的特有功能
public static void main(String[] args) {
LinkedList<String> linkedList=new LinkedList();
linkedList.add("Hello");
linkedList.add("World");
linkedList.add("LinkedList");
//获得集合第一个元素
String first = linkedList.getFirst();
System.out.println(first);//Hello
//获得集合最后一个元素
String last = linkedList.getLast();
System.out.println(last);//LinkedList
//在集合开头插入指定元素
linkedList.addFirst("你好");
//在集合结尾插入指定元素
linkedList.addLast("世界!");
System.out.println(linkedList);//[你好, Hello, World, LinkedList, 世界!]
//从集合中删除并返回第一个元素
String removeFirst = linkedList.removeFirst();
System.out.println(removeFirst);//你好
System.out.println(linkedList);//[Hello, World, LinkedList, 世界!]
//从集合中删除并返回最后一个元素
String removeLast = linkedList.removeLast();
System.out.println(removeLast);//世界!
System.out.println(linkedList);//[Hello, World, LinkedList]
}