=============================================================================
=============================================================================
涉及到的知识点有:
1:对象数组的概述和案例(掌握)
(1)对象数组的概述
(2)对象数组的案例
2:集合(Collection接口)(掌握)
(1)集合的由来?
(2)集合和数组的区别?
(3)集合的继承体系结构
(4)Collection接口的概述
(5)Collection接口的成员方法(注意:默认方法前有public abstract修饰)
(6)Collection集合的遍历
(7)迭代器
(8)Collection集合的案例(遍历方式:迭代器方式)(要求:用记事本默写)
A:存储字符串并遍历
B:存储自定义对象并遍历
3:集合(List接口)(掌握)
(1)List是Collection的子接口
(2)List的特有功能(注意:默认方法前有public abstract修饰)
(3)List集合的特有遍历功能
(4)列表迭代器的特有功能(了解)
(5)ConcurrentModificationException 并发修改异常
(6)常见的数据结构以及其优缺点
(7)List的子类特点(面试题)
(8)List集合的案例(遍历方式 迭代器和普通for循环)
=============================================================================
=============================================================================
1:对象数组的概述和案例(掌握)
(1)对象数组的概述
数组既可以存储基本数据类型,也可以存储引用类型。它存储引用类型的时候的数组就叫对象数组。
(2)对象数组的案例
我有5个学生,请把这个5个学生的信息存储到数组中,并遍历学生数组,获取得到每一个学生的信息。
示例代码如下:
1 packagecn.itcast_01;2 3 public classStudent {4 //成员变量5 privateString name;6 private intage;7 8 //构造方法9 publicStudent() {10 super();11 }12 13 public Student(String name, intage) {14 super();15 this.name =name;16 this.age =age;17 }18 19 //成员方法20 //getXxx()/setXxx()21 publicString getName() {22 returnname;23 }24 25 public voidsetName(String name) {26 this.name =name;27 }28 29 public intgetAge() {30 returnage;31 }32 33 public void setAge(intage) {34 this.age =age;35 }36 37 @Override38 publicString toString() {39 return "Student [name=" + name + ", age=" + age + "]";40 }41 }Student.java
1 packagecn.itcast_01;2 3 /*4 * 我有5个学生,请把这个5个学生的信息存储到数组中,并遍历学生数组,获取得到每一个学生的信息。5 * 学生类:Student6 * 成员变量:name,age7 * 构造方法:无参,带参8 * 成员方法:getXxx()/setXxx()9 * 存储学生的数组?自己想想应该是什么样子的?10 * 分析:11 * A:创建学生类。12 * B:创建学生数组(对象数组)。13 * C:创建5个学生对象,并赋值。14 * D:把C步骤的元素,放到学生数组中。15 * E:遍历学生数组。16 */17 public classObjectArrayDemo {18 public static voidmain(String[] args) {19 //创建学生数组(对象数组)。20 Student[] students = new Student[5];21 22 //遍历新创建的学生数组。23 for (int x = 0; x < students.length; x++) {24 System.out.println(students[x]);25 }26 System.out.println("---------------------");27 28 //创建5个学生对象,并赋值。29 Student s1 = new Student("林青霞", 27);30 Student s2 = new Student("风清扬", 30);31 Student s3 = new Student("刘意", 30);32 Student s4 = new Student("赵雅芝", 60);33 Student s5 = newStudent();34 s5.setName("王力宏");35 s5.setAge(27);36 37 //把C步骤的元素,放到学生数组中。38 students[0] =s1;39 students[1] =s2;40 students[2] =s3;41 students[3] =s4;42 students[4] =s5;43 44 //看到很相似,就想用循环改,把C步骤的元素,放到学生数组中。45 //for (int x = 0; x < students.length; x++) {46 //students[x] = s + "" + (x + 1);//拼完之后是一个字符串了。47 //}48 //这个是有问题的。49 50 //遍历赋值后的学生数组,用重写的toString()方法51 for (int x = 0; x < students.length; x++) {52 //重写toString()方法,注意:一个方法写定之后就不要再去改变了。因为改来改去的还不如重新写个方法呢?53 System.out.println(students[x]);54 }55 System.out.println("---------------------");56 57 //遍历赋值后的学生数组,用getXxx()方法58 for (int x = 0; x < students.length; x++) {59 //System.out.println(students[x].getName() + "---" + students[x].getAge());//或者等价于下面60 //因为学生数组的每一个元素都是一个学生。61 Student s =students[x];62 System.out.println(s.getName() + "---" +s.getAge());63 }64 }65 }ObjectArrayDemo.java
-----------------------------------------------------------------------------
2:集合(Collection接口)(掌握)
(1)集合的由来?
我们学习的是Java --> 面向对象 --> 操作很多对象 --> 存储 --> 容器(数组和StringBuffer) --> 数组
而数组的长度是固定的,当添加的元素超过了数组的长度需要对数组重新定义,太麻烦,所以数组不适合做变化的需求,Java内部就给我们提供了集合类供我们使用。
集合类能存储任意对象,长度是可以该变的,即长度能随着元素的增加而增加,随着元素的减少而减少。
(2)集合和数组的区别?
A:长度区别
数组长度固定,不能自动增长。
集合的长度的是可变的,可以根据元素的增加而增长。
B:内容区别
数组只能存储同一种类型。
集合可以存储不同类型(其实集合一般存储的也是同一种类型)。
C:元素的数据类型区别
数组既可以存储基本数据类型,又可以存储引用数据类型;基本数据类型存储的是值,引用数据类型存储的是地址值。
集合只能存储引用数据类型(对象),其实集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象。
---------------------------------------
(3)集合的继承体系结构
刚说过集合是存储多个元素的,但是呢,存储多个元素我们也是有不同需求的:
比如说,我要这多个元素中不能有相同的元素;
再比如说,我要这多个元素按照某种规则排序一下。
针对不同的需求,Java就提供了不同的集合类,这样呢,Java就提供了很多个集合类。
这多个集合类的数据结构不同,数据结构不同不重要的,重要的是你要能够存储东西,并且还要能够使用这些东西,比如说存储、获取、判断等。
既然这样,那么,这多个集合类是有共性的内容的,我们把这些集合类的共性内容不断的向上提取,最终就能形成集合的继承体系结构。
如下图所示:
Collection(单列集合的根接口)
|--List(有序:存和取的顺序一致,有索引,可以存储重复元素)
|--ArrayList(数组实现)
|--Vector(数组实现)
|--LinkedList(链表实现)
|--Set(无序:存和取的顺序不一致,无索引,不可以存储重复元素)
|--HashSet(哈希算法)
|--TreeSet(二叉树算法)
---------------------------------------
(4)Collection接口的概述
Collection接口是集合的顶层接口,它的子体系有重复的,有唯一的,有有序的,有无序的。(后面会慢慢的讲解)
Collection表示一组对象,这些对象也称为collection的元素。
JDK不提供此接口的任何直接实现:它提供更具体的子接口(如 Set 和 List)实现。
(5)Collection接口的成员方法(注意:默认方法前有public abstract修饰)
1:添加功能
boolean add(Object obj) 添加一个元素
boolean addAll(Collection c) 添加一个集合的元素
2:删除功能
void clear() 移除所有元素
boolean remove(Object o) 移除一个元素
boolean removeAll(Collection c) 移除一个集合的元素(只要集合中有一个元素被移除了,就返回true)
3:判断功能
boolean contains(Object o) 判断集合中是否包含指定的元素
boolean containsAll(Collection c) 判断集合中是否包含指定的集合元素(只有集合包含所有的元素,才返回true,才叫包含)
boolean isEmpty() 判断集合是否为空
4:获取功能(重点学)
Iterator iterator() 返回在此集合的元素上进行迭代的迭代器。是集合专用的遍历方式。
5:长度功能
int size() 元素的个数(即集合的长度)
面试题:
数组有没有length()方法呢? 答:没有。特别注意:因为数组求长度是:数组名.length,而不是:数组名.length()
字符串有没有length()方法呢? 答:有。
集合有没有length()方法呢? 答:没有,因为集合求长度的方法是size()。
6:交集功能(了解)
boolean retainAll(Collection c) 两个集合都有的元素?思考:元素去哪了?返回的boolean又是什么意思呢?
// 假设有两个集合A,B。
// A对B做交集,最终的结果保存在集合A中,集合B不变。
// 但是返回值表示的是集合A是否发生过改变。
// 集合A没有发生改变,返回false,即集合B包含集合A;
// 集合A发生改变,返回true。
7:把集合转成对象数组,可以实现集合的遍历(了解)
Object[] toArray()
---------------------------------------
(6)Collection集合的遍历
A:把集合转成对象数组(了解)
练习:用集合存储5个学生对象,并把学生对象进行遍历(遍历方式:把集合转成对象数组,需要用记事本背着写出来)。
示例代码如下:
1 packagecn.itcast_02;2 3 public classStudent {4 //成员变量5 privateString name;6 private intage;7 8 //构造方法9 publicStudent() {10 super();11 }12 13 public Student(String name, intage) {14 super();15 this.name =name;16 this.age =age;17 }18 19 //成员方法20 //getXxx()/setXxx()21 publicString getName() {22 returnname;23 }24 25 public voidsetName(String name) {26 this.name =name;27 }28 29 public intgetAge() {30 returnage;31 }32 33 public void setAge(intage) {34 this.age =age;35 }36 }Student.java
1 packagecn.itcast_02;2 3 importjava.util.ArrayList;4 importjava.util.Collection;5 6 /*7 * 练习:用集合存储5个学生对象,并把学生对象进行遍历(遍历方式:把集合转成对象数组,需要用记事本背着写出来)。8 *9 * 分析:10 * A:创建学生类11 * B:创建集合对象12 * C:创建学生对象13 * D:把学生添加到集合14 * E:把集合转成对象数组15 * F:遍历对象数组16 */17 public classStudentDemo {18 public static voidmain(String[] args) {19 //创建集合对象20 Collection c = newArrayList();21 22 //创建学生对象23 Student s1 = new Student("林青霞", 27);24 Student s2 = new Student("风清扬", 30);25 Student s3 = new Student("令狐冲", 33);26 Student s4 = new Student("武鑫鑫", 25);27 Student s5 = new Student("刘晓曲", 22);28 29 //把学生添加到集合30 c.add(s1);31 c.add(s2);32 c.add(s3);33 c.add(s4);34 c.add(s5);35 36 //把集合转成对象数组,向上转型37 Object[] objs =c.toArray();38 //遍历对象数组39 for (int x = 0; x < objs.length; x++) {40 //System.out.println(objs[x]);//没有重写toString()方法41 42 //向下转型43 Student s =(Student) objs[x];44 System.out.println(s.getName() + "---" +s.getAge());45 }46 }47 }StudentDemo.java
B:迭代器(集合的专用遍历方式)
练习:用集合存储5个学生对象,并把学生对象进行遍历(遍历方式:用迭代器进行遍历)。
示例代码如下:
1 packagecn.itcast_03;2 3 public classStudent {4 //成员变量5 privateString name;6 private intage;7 8 //构造方法9 publicStudent() {10 super();11 }12 13 public Student(String name, intage) {14 super();15 this.name =name;16 this.age =age;17 }18 19 //成员方法20 //getXxx()/setXxx()21 publicString getName() {22 returnname;23 }24 25 public voidsetName(String name) {26 this.name =name;27 }28 29 public intgetAge() {30 returnage;31 }32 33 public void setAge(intage) {34 this.age =age;35 }36 37 @Override38 publicString toString() {39 return "Student [name=" + name + ", age=" + age + "]";40 }41 42 }Student.java
1 packagecn.itcast_03;2 3 importjava.util.ArrayList;4 importjava.util.Collection;5 importjava.util.Iterator;6 7 /*8 * 练习:用集合存储5个学生对象,并把学生对象进行遍历。用迭代器进行遍历。9 *10 * 注意:11 * A:自己的类名不要和我们学习的要使用的API中的类名相同。12 * B:复制代码的时候,很容易把那个类所在的包也导入过来,容易出现不能理解的问题。13 */14 public classIteratorTest {15 public static voidmain(String[] args) {16 //创建集合对象17 Collection c = newArrayList();18 19 //创建学生对象20 Student s1 = new Student("林青霞", 27);21 Student s2 = new Student("风清扬", 30);22 Student s3 = new Student("令狐冲", 33);23 Student s4 = new Student("武鑫鑫", 25);24 Student s5 = new Student("刘晓曲", 22);25 26 //把学生添加到集合中27 c.add(s1);28 c.add(s2);29 c.add(s3);30 c.add(s4);31 c.add(s5);32 33 //遍历34 Iterator it =c.iterator();35 while(it.hasNext()) {36 //System.out.println(it.next());//重写了toString()方法37 Student s = (Student) it.next(); //向下转型38 System.out.println(s.getName() + "---" +s.getAge());39 }40 }41 }IteratorTest.java
迭代器使用出现的2个想问题解释:
问题1:能用while循环写这个程序,我能不能用for循环呢?
答:能。用for循环改写,遍历完成后,it这个对象就变成垃圾了,可以被JVM的垃圾回收器进行回收了,效率高,但是结构不是特别明朗。
问题2:不要多次使用it.next()方法,因为每次使用都去访问一个对象。
//System.out.println(((Student) it.next()).getName() + "---" + ((Student) it.next()).getAge());
//NoSuchElementException 不要多次使用it.next()方法。
---------------------------------------
(7)迭代器
A:迭代器是集合的获取元素的方式。
B:迭代器是依赖于集合而存在的。
因为迭代器是通过集合调用集合的方法而得到的。即必须先有集合,然后才有迭代器。
Collection接口的成员方法
Iterator iterator() 迭代器,集合的专用遍历方式。
Iterator接口的成员方法
boolean hasNext() 判断如果仍有元素可以迭代,则返回 true。
Object next() 获取元素,并移动到下一个位置。
NoSuchElementException 没有这样的元素异常,因为你已经找到最后了。
C:迭代器的原理图解和源码浅析
a:迭代器为什么定义了一个接口而不是实现类?
假如把迭代器定义为一个类,这样我们就可以创建该类的对象,调用该类的方法来实现集合的遍历了。
但是,java中提供了很多的集合类,而这些集合类的数据结构是不同,所以它们的存储方法也是不同的,
进而它们的遍历方法也是不一样的,最终就没有把迭代器定义为一个类了。
(因为定义成一个迭代器类就是一个具体的实现了,既然是具体实现那么它们的遍历方式就是一样的了)
而无论是那种集合,都应该具备获取元素的功能,并且最好辅助以判断的功能,这样在获取前,先判断,就不容易出错。
也就是说,判断和获取功能应该是一个集合遍历所具备的,而每种集合的遍历方式又不太一样,
所以把这两个功能给提取出来,并不提供具体的实现,而这种方式叫做接口。
那么,真正的具体的实现类在哪里呢?
在真正的具体的子类中,是以内部类的方式体现的。
(因为在子类中要包含两个方法)
如下图所示:
b:迭代器的内部类实现源码浅析
1 -----------------------------------------------------------------------------2 public interfaceInteator {3 public abstract boolean hasNext(); //注意:默认方法前有public abstract修饰,是接口中方法的默认修饰符4 public abstract Object next(); //注意:默认方法前有public abstract修饰,是接口中方法的默认修饰符5 }6 7 public interfaceIterable {8 Iterator iterator(); //没有具体实现,注意:默认方法前有public abstract修饰,是接口中方法的默认修饰符9 }10 -----------------------------------------------------------------------------11 public interface Collection extendsIterable {12 Iterator iterator(); //没有具体实现,注意:默认方法前有public abstract修饰,是接口中方法的默认修饰符13 }14 15 public interface List extendsCollection {16 Iterator iterator(); //没有具体实现,注意:默认方法前有public abstract修饰,是接口中方法的默认修饰符17 }18 -----------------------------------------------------------------------------19 public class ArrayList implementsList {20 public Iterator iterator() { //具体实现21 return newItr();22 }23 24 private class Itr implements Iterator { //Itr是Iterator接口的实现类25 public booleanhasNext() {}26 publicObject next(){}27 }28 }29 -----------------------------------------------------------------------------30 Collection c = newArrayList();31 c.add("hello");32 c.add("world");33 c.add("java");34 Iterator it = c.iterator(); //new Itr();35 while(it.hasNext()) {36 String s =(String)it.next();37 System.out.println(s);38 }39 -----------------------------------------------------------------------------迭代器的源码浅析
---------------------------------------
(8)Collection集合的案例(遍历方式:迭代器方式)(要求:用记事本默写)
集合的使用步骤:
A:创建集合对象
B:创建元素对象
C:把元素添加到集合
D:遍历集合
a:通过集合对象获取迭代器对象
b:通过迭代器对象的hasNext()方法判断是否有元素
c:通过迭代器对象的next()方法获取元素并移动到下一个位置
A:存储字符串并遍历
importjava.util.Collection;importjava.util.ArrayList;importjava.util.Iterator;public classCollectionDemo {public static voidmain(String[] args) {//创建集合对象 Collection c = newArrayList();//创建元素对象 String s = new String("hello");//把元素添加到结合c.add(s); c.add("world"); c.add("java");//遍历集合//通过集合对象获取迭代器对象 Iterator it =c.iterator();while(it.hasNext()) { String s1=(String) it.next(); System.out.println(s1); } } }
---------------------------------------
B:存储自定义对象并遍历
public classStudent {privateString name;private intage;publicStudent() {super(); }public Student(String name, intage) {super();this.name =name;this.age =age; }publicString getName() {returnname; }public voidsetName(String name) {this.name =name; }public intgetAge() {returnage; }public void setAge(intage) {this.age =age; } }
importjava.util.Collection;importjava.util.ArrayList;importjava.util.Iterator;public classStudentDemo {public static voidmain(String[] args) {//创建集合对象 Collection c = newArrayList();//创建学生对象 Student s1 = new Student("貂蝉", 25); //含参构造 Student s2 = new Student("小乔", 16); Student s3= new Student("黄月英", 20); Student s4= new Student(); //无参构造 s4.setName("大乔"); s4.setAge(26);//把学生对象添加到集合对象中c.add(s1); c.add(s2); c.add(s3); c.add(s4); c.add(new Student("孙尚香", 18)); //匿名对象//遍历集合 Iterator it =c.iterator();while(it.hasNext()) { Student s=(Student) it.next(); System.out.println(s.getName()+ "---" +s.getAge()); } } }
-----------------------------------------------------------------------------
3:集合(List接口)(掌握)
(1)List是Collection的子接口
特点:有序(存储顺序和取出顺序一致),有索引,可以存储重复元素。
(2)List的特有功能(注意:默认方法前有public abstract修饰)
A:添加功能
void add(int index, Object element) 在指定位置添加元素
B:删除功能
Object remove(int index) 根据索引删除元素,返回被删除的元素
C:获取功能
Object get(int index) 获取指定位置的元素
D:列表迭代器功能
ListIterator listIterator() List集合特有的迭代器
E:修改功能
Object set(int index, Object element) 根据索引修改元素,返回被修该的元素
---------------------------------------
(3)List集合的特有遍历功能
A:由size()和get()结合。
B:代码演示
1 importjava.util.List;2 importjava.util.ArrayList;3 importjava.util.Iterator;4 5 public classListDemo {6 public static voidmain(String[] args) {7 //创建集合对象8 List list = newArrayList();9 10 //创建元素对象,并添加11 list.add("hello");12 list.add("wprld");13 list.add("java");14 15 //通过集合对象获取迭代器对象16 Iterator it =list.iterator();17 //迭代器遍历集合18 while(it.hasNext()) {19 String s =(String) it.next();20 System.out.println(s);21 }22 23 //普通for循环遍历集合24 for (int x = 0; x < list.size(); x++) {25 String s =(String) list.get(x);26 System.out.println(s);27 }28 }29 }
---------------------------------------
(4)列表迭代器的特有功能(了解)
Object previous() 获取上一个元素
boolean hasPrevious() 判断是否有元素
注意:ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,所以一般无意义,不使用。
(5)ConcurrentModificationException 并发修改异常
当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
A:出现的现象
迭代器在遍历集合时,用集合去修改集合元素。
B:产生的原因
迭代器是依赖于集合而存在的,在判断成功后,集合中新添加了元素,集合发生了改变,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
其实这个问题描述的是:迭代器在遍历元素的时候,通过集合是不能修改元素的。
C:解决的方案
a:迭代器迭代元素,用列表迭代器(ListIterator)修改元素
元素是跟在刚才迭代的元素后面的。
注意:Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator列表迭代器。
b:集合遍历元素,用集合修改元素(普通for循环:size()和get())
元素是在最后添加的。(即元素添加在集合的末尾)
---------------------------------------
(6)常见的数据结构以及其优缺点
A:栈 先进后出
B:队列 先进先出
C:数组 查询快,增删慢
D:链表 查询慢,增删快
E:树
F:哈希表
如下图所示:
---------------------------------------
(7)List的子类特点(面试题)
ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
List有三个儿子,我们到底使用谁呢?
看需求(看情况)。
分析:
要安全吗?
要:Vector(即使要,也不使用这个,后面有替代的)
不要:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
什么都不知道,就用ArrayList。
---------------------------------------
(8)List集合的案例(遍历方式:迭代器和普通for循环)
A:存储字符串并遍历
示例代码如下:
1 importjava.util.List;2 importjava.util.ArrayList;3 importjava.util.Iterator;4 5 public classListDemo {6 public static voidmain(String[] args) {7 //创建集合对象8 List list = newArrayList();9 10 //创建元素对象,并添加11 list.add("hello");12 list.add("wprld");13 list.add("java");14 15 //通过集合对象获取迭代器对象16 Iterator it =list.iterator();17 //迭代器遍历集合18 while(it.hasNext()) {19 String s =(String) it.next();20 System.out.println(s);21 }22 23 //普通for循环遍历集合24 for (int x = 0; x < list.size(); x++) {25 String s =(String) list.get(x);26 System.out.println(s);27 }28 }29 }ListDemo.java
B:存储自定义对象并遍历
示例代码如下:
1 packagecn.itcast_03;2 3 public classStudent {4 //成员变量5 privateString name;6 private intage;7 8 //构造方法9 publicStudent() {10 super();11 }12 13 public Student(String name, intage) {14 super();15 this.name =name;16 this.age =age;17 }18 19 //成员方法20 //getXxx()/setXxx()21 publicString getName() {22 returnname;23 }24 25 public voidsetName(String name) {26 this.name =name;27 }28 29 public intgetAge() {30 returnage;31 }32 33 public void setAge(intage) {34 this.age =age;35 }36 }Student.java
1 packagecn.itcast_03;2 3 importjava.util.ArrayList;4 importjava.util.Iterator;5 importjava.util.List;6 7 /*8 * 存储自定义对象并遍历,遍历方式:迭代器和普通for循环。(size()和get()结合)9 */10 public classListDemo3 {11 public static voidmain(String[] args) {12 //创建集合对象13 List list = newArrayList();14 15 //创建学生对象16 Student s1 = new Student("林黛玉", 18);17 Student s2 = new Student("刘姥姥", 88);18 Student s3 = new Student("王熙凤", 38);19 20 //把学生添加到集合中21 list.add(s1);22 list.add(s2);23 list.add(s3);24 25 //遍历26 //迭代器遍历集合27 Iterator it =list.iterator();28 while(it.hasNext()) {29 Student s =(Student) it.next();30 System.out.println(s.getName() + "---" +s.getAge());31 }32 System.out.println("-----------");33 34 //普通for循环遍历集合35 for (int x = 0; x < list.size(); x++) {36 Student s =(Student) list.get(x);37 System.out.println(s.getName() + "---" +s.getAge());38 }39 }40 }ListDemo3.java
=============================================================================我的GitHub地址:https://github.com/heizemingjun
我的博客园地址:http://www.cnblogs.com/chenmingjun
我的蚂蚁笔记博客地址:http://blog.leanote.com/chenmingjun
Copyright ©2018 黑泽明军
【转载文章务必保留出处和署名,谢谢!】