一、什么是数组??
1.存储多个同种类型的数据(除了基本数据类型之外,也可以存储引用数据类型的对象)
Student s=new Student();
2.长度是固定的
3.有默认值
二、数组的声明方法
一、动态声明(隐式声明)
int[] arr=new int[];
二、静态声明(显示声明)
int[] arr={1,2,3};
三、集合的定义(Collection)
为什么我们有数组了还要学习集合呢??
因为数组的长度是固定了的,无法更改。一旦存储的数据超过了数组能够容纳的最大限度,那么就会出现错误
为了满足实际开发的需要,就出现了集合类,而集合的长度是可以随意更改的
集合:长度是可以随意更改的,但是集合只能存储对象,而不能存储基本数据类型,且集合没有默认值
四、打开JavaAPI看一下集合的一些信息
首先集合(Collection)是一个接口,它不能创建对象,那么我们需要使用它就必须使用它的子类List和Set
List也是一个接口,同样不能创建对象,那么我们需要使用它就还需要用到它的子类ArrayList和LinkedList
ArrayList终于是一个类,那么我们使用的时候就是使用这个类去创建对象,然后调用方法去完成一些操作
LinkedList同样也是一个类,同样我们使用的时候就是使用这个类去创建对象,然后调用方法去完成一些操作
HashSet同样也是一个类,同样我们使用的时候就是使用这个类去创建对象,然后调用方法去完成一些操作
TreeSet同样也是一个类,同样我们使用的时候就是使用这个类去创建对象,然后调用方法去完成一些操作
五、集合的体系结构
集合和数组一样也是一个用来存储数据的容器(--存数据和取数据)
因为这个容器存在存数据和取数据的方式不同,可以把集合分为一些类别
栈存取数据的过程:后进先出
队列存取数据的过程:先进先出
集合体系结构图:
List集合:1.存取数据都是有序的 2.是有索引标志的 3.允许重复
Set集合:1.存取数据是无序的 2.没有索引标志 3.不允许重复
六、ArrayList类
//重点1.boolean add(Object e) //向集合中添加元素
//2.void clear():清空集合中的元素
//3.boolean contains(object o):判断集合是否包含某个元素
//4.boolean isEmpty():判断集合是否为空
//5.boolean remove(object o):根据元素的内容来删除某个元素
//重点6.int size():获取集合的长度
//重点7:object[] toArray():将集合转换成数组
package com.bianyiit.collection;
import java.util.ArrayList;
import java.util.Collection; //记住:一定要导包
public class ArrayList01 {
public static void main(String[] args) {
Collection_Method(); //Collection中的常用功能
}
private static void Collection_Method() {
//创建集合对象
Collection c=new ArrayList();//多态 父类引用指向子类对象
//ArrayList a1 = new ArrayList();
//重点1.boolean add(Object e) //向集合中添加元素
//集合只能存储对象
c.add(1); //自动装箱
c.add("java");
c.add("world");
c.add("world"); //可以重复添加world
//ArrayList的add()方法允许重复,因为add()的返回值永远为true
System.out.println(c);
//2.void clear():清空集合中的元素
/*c.clear();
System.out.println(c);*/
//3.boolean contains(object o):判断集合是否包含某个元素
System.out.println(c.contains("c#"));
System.out.println(c.contains("java"));
//4.boolean isEmpty():判断集合是否为空
System.out.println(c.isEmpty());
//5.boolean remove(object o):根据元素的内容来删除某个元素
System.out.println("是否成功删除:"+c.remove("world"));
System.out.println(c);//只会删除一个元素
System.out.println("是否成功删除:"+c.remove("world"));
System.out.println(c);//只会删除一个元素
//重点6.int size():获取集合的长度
System.out.println(c.size());
//重点7:object[] toArray():将集合转换成数组
c.add("c#");
System.out.println(c);
//遍历集合的第一种方式:首先把集合通过toArray()转换为数组,然后再遍历数组
Object[] objects = c.toArray();//返回值类型是object的数组
//遍历数组
for (int i = 0; i < objects.length; i++) {
System.out.println(objects[i]);
}
}
}
//输出结果:
[1, java, world, world]
false
true
false
是否成功删除:true
[1, java, world]
是否成功删除:true
[1, java]
2
[1, java, c#]
1
java
c#
六、迭代器(Iterator)
迭代的定义:判断集合中是否有元素,如果有元素就先取一个元素,然后再判断还有没有元素,如果有,继续取,直到取完为止。
//要想实现迭代的效果,需要用到迭代器iterator ---遍历集合用的
七、如何使用迭代器(Iterator)遍历集合
package com.bianyiit.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class ArrayList02 {
public static void main(String[] args) {
/* iterator的三个方法
boolean hasNext() 如果仍有元素可以迭代,则返回 true。
E next() 返回迭代的下一个元素。
void remove() 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。 */
Collection c = new ArrayList(); //多态 父类引用指向子类对象
//往集合中添加元素
c.add("张三");
c.add("李四");
c.add("王五");
System.out.println(c);
//使用迭代器进行遍历集合
//1.先要有一个迭代器对象
Iterator it = c.iterator();
//2.判断集合中是否有元素可取
while(it.hasNext()){ //如果仍有元素可以迭代,则返回 true。
System.out.println(it.next()); //返回迭代的下一个元素。
}
//如果容器中没有元素了,还取元素就会报异常(没有多余元素异常)
System.out.println(it.next());//Exception in thread "main" java.util.NoSuchElementException
}
}
//输出结果:
[张三, 李四, 王五]
张三
李四
王五
八、需求:判断集合中是否包含“王五”,如果有,就添加一个“赵六”
//遍历集合的第一种方式:使用集合的一个方法 boolean contains(object o):判断集合是否包含某个元素
if(c.contains("王五")){
c.add("赵六")
}
//遍历集合的第二种方式:如果只允许使用迭代器去完成
package com.bianyiit.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo_Iterator {
public static void main(String[] args) {
Collection c = new ArrayList(); //多态 父类引用指向子类对象
//往集合中添加元素
c.add("张三");
c.add("李四");
c.add("王五");
System.out.println(c);
//获取迭代器对象
Iterator it = c.iterator();
//迭代集合
while(it.hasNext()){
String s= (String) it.next(); //迭代器返回的类型是object
if(s.equals("王五")){
c.add("赵六");
}
}
}
}
//输出结果:
Exception in thread "main" java.util.ConcurrentModificationException
//这里出现了并发修改的异常
九、为什么会出现并发修改异常
迭代器可以看成是集合的一个副本,迭代器迭代数据的时候会把数据读到迭代器里面,迭代器中的元素要跟集合的元素的个数一致,假如迭代器中的元素中的元素个数跟集合中的元素个数不一致时,迭代器就会跟不上集合的节奏,所以报并发修改异常ConcurrentModificationException
十、如何去解决上述问题呢??
//不要去使用Colleciton中的迭代器,使用List集合的迭代器
package com.bianyiit.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
public class Demo_ListIterator {
public static void main(String[] args) {
//创建集合对象
List c = new ArrayList(); //多态 父类引用指向子类对象
//往集合中添加元素
c.add("张三");
c.add("李四");
c.add("王五");
System.out.println(c);
//获取List的迭代器对象
ListIterator it = c.listIterator();
//迭代集合
while(it.hasNext()){
String s= (String) it.next(); //迭代器返回的类型是object
if(s.equals("王五")){
it.add("赵六"); //这里使用的是List集合的迭代器中的add()
}
}
System.out.println(c);
}
}
//输出结果:
[张三, 李四, 王五]
[张三, 李四, 王五, 赵六]
总结:使用Collection的迭代器,没有add(),所以修改集合时会发生并发修改异常,当使用List集合的迭代器时,有add(),所以修改迭代器不会出现并发修改异常
十一、LinkedList集合
常用方法
void addFirst(E e) :向链表的头部添加元素
void addLast(E e):向链表的尾部添加元素
E getFirst():获取链头的元素,不删除元素
E getLast():获取链尾的元素,不删除元素
E removeFirst():返回链头的元素并删除链头的元素
E removeLast():返回链尾的元素并删除链尾的元素
package collection;
import java.util.LinkedList;
public class Demo_LinkedList {
public static void main(String[] args) {
/*LinkedList底层使用的是链表结构,因此增删快,查询相对ArrayList较慢*/
LinkedList<String> list=new LinkedList<>();
list.addFirst("张三");
list.addLast("李四");
list.addLast("王五");
System.out.println(list);
System.out.println(list.getFirst());
System.out.println(list.getLast());
System.out.println(list.removeFirst());
System.out.println(list.removeLast());
System.out.println(list);
}
}
//输出结果:
[张三, 李四, 王五]
张三
王五
张三
王五
[李四]
十二、增强for(集合遍历的第三种方式)
快捷键iter
格式:for(元素的类型 变量名:集合对象){}
package com.bianyiit.collection;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Demo_ZengQiangFor {
public static void main(String[] args) {
//创建集合对象
List c = new ArrayList(); //多态 父类引用指向子类对象
//往集合中添加元素
c.add("张三");
c.add("李四");
c.add("王五");
System.out.println(c);
//使用增强for遍历集合 快捷键iter
for (Object o : c) {
System.out.println(o);
}
}
}
//输出结果:
[张三, 李四, 王五]
张三
李四
王五
for (Object o : c) {
String s= (String) o;
if(s.equals("李四")){
c.add("赵六");
}
}
//java.util.ConcurrentModificationException 同样如果对集合进行增删工作会报并发修改异常
注意:增强for的实现原理就是Collection的iterator 使用增强for不要对集合进行增和删的工作
十三、泛型< E >:代表全部数据类型
集合本身是可以存储任意类型的数据(object)给定了泛型就是规定了这个集合只能存储规定数据类型的数据
简单来说:泛型就是用来规定集合存储的数据的类型的
添加泛型的好处
如果不添加泛型,得到的元素是object类型的,如果想得到对应的类型,还需要强转,如果添加了泛型,集合在添加元素的时候就只能添加规定的数据类型,得到的集合中的元素也不再需要进行强转
格式要求:
Collection<Integer> c=new ArrayList<Integer>(); //int(基本数据类型)---Integer(引用数据类型)
Collection<String> c=new ArrayList<String>();
//这里用到了三个技术点 1.多态、2.包装类、3.泛型
//同时后面的<>可以省略,但是建议创建集合对象的时候加上泛型
Collection<String> c=new ArrayList();
十四、数组和链表存储数据的方式以及优缺点
数组
数组的特点:1.查找快(可以直接根据索引值查找到该索引对应的值)2.但是增删慢(需要扩充数组长度,然后整体往后移,很麻烦)
特别注意:有顺序的,连续的
链表
链表的特点:1.查找慢 2.但是增删快
特别注意:有顺序的,但是不是连续的
面试题:ArrayList和LinkedList的底层是什么??
ArrayList的底层是数组:查询快,但是增删慢
LinkedList的底层是链表:查询慢,但是增删慢
十五、总结
List的特点:1.有序的 2.有索引 3.允许重复
package com.bianyiit.collection;
import java.util.ArrayList;
import java.util.List;
public class Demo_List {
public static void main(String[] args) {
//创建集合对象
List<String> list = new ArrayList<String>(); //多态 父类引用指向子类对象
list.add("hello");
list.add("world");
list.add("java");
System.out.println(list); //[hello, world, java]
//void add(int index, E element)在列表的指定位置插入指定元素(可选操作)。
list.add(1,"php");
System.out.println(list); //[hello, php, world, java]
//E get(int index) 返回列表中指定位置的元素。
System.out.println(list.get(0)); //hello
//遍历数组
for (int i = 0; i <list.size() ; i++) {
System.out.println(list.get(i));
}
//E remove(int index)移除列表中指定位置的元素(可选操作)。
System.out.println(list.remove(0)); //返回被删除的元素---hello
System.out.println(list); //[php, world, java]
// E set(int index, E element)用指定元素替换列表中指定位置的元素(可选操作)。
System.out.println(list.set(0,"haha")); //返回的是被修改的元素---php
System.out.println(list); //[haha, world, java]
}
}