传智播客-Java学习笔记day15时间:2022-12-13 19:15:321.对象数组的内存图解 2.集合概述集合的由来: 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储。 而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识里面,有哪些是容器类型的呢? 数组和StringBuffer。但是呢?StringBuffer的结果是一个字符串,不一定满足我们的要求,所以我们只能选择数组,这就是对象数组。 而对象数组又不能适应变化的需求,因为数组的长度是固定的,这个时候,为了适应变化的需求,Java就提供了集合类供我们使用。 3.数组和集合的区别? A:长度区别 数组的长度固定 集合长度可变 B:内容不同 数组存储的是同一种类型的元素 而集合可以存储不同类型的元素 C:元素的数据类型问题 数组可以存储基本数据类型,也可以存储引用数据类型 集合只能存储引用类型 3.集合的继承体系图解4.CollectionCollection:是集合的顶层接口,它的子体系有重复的,有唯一的,有有序的,有无序的。 Collection的功能概述: 1:添加功能 boolean add(Object obj):添加一个元素 boolean addAll(Collection c):添加一个集合的元素 2:删除功能 void clear():移除所有元素 boolean remove(Object o):移除一个元素 boolean removeAll(Collection c):移除一个集合的元素(是一个还是所有) 3:判断功能 boolean contains(Object o):判断集合中是否包含指定的元素 boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(是一个还是所有) boolean isEmpty():判断集合是否为空 4:获取功能 Iterator<E> iterator()(重点) 5:长度功能 int size():元素的个数 面试题:数组有没有length()方法呢?字符串有没有length()方法呢?集合有没有length()方法呢? 6:交集功能 boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢? 7:把集合转换为数组 Object[] toArray()5.重点注意几个All方法boolean addAll(Collection c):添加一个集合的元素 boolean removeAll(Collection c):移除一个集合的元素(是一个还是所有) boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(只有包含所有的元素,才叫包含) boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢? addAll示例removeAll示例(只要有一个元素被移除了,就返回true)注意boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢? //假设有两个集合A,B。 //A对B做交集,最终的结果保存在A中,B不变。 //返回值表示的是A是否发生过改变。 返回值表示的是A(原集合)是否发生过改变。 6.集合的遍历集合的遍历,其实就是依次获取集合中的每一个元素。Object[] toArray():把集合转成数组,可以实现集合的遍历 // 创建集合对象 Collection c = new ArrayList(); // 添加元素 c.add("hello"); // 这个语句隐含有Object obj = "hello"; 向上转型 c.add("world"); c.add("java"); // 遍历 // Object[] toArray():把集合转成数组,可以实现集合的遍历 Object[] objs = c.toArray(); for (int x = 0; x < objs.length; x++) { // System.out.println(objs[x]); // 我知道元素是字符串,我在获取到元素的的同时,还想知道元素的长度。 // System.out.println(objs[x] + "---" + objs[x].length()); // 上面的实现不了,原因是Object中没有length()方法 // 我们要想使用字符串的方法,就必须把元素还原成字符串 // 向下转型 String s = (String) objs[x]; System.out.println(s + "---" + s.length());7.集合的遍历案例(最原始的遍历方式,以后不常用,用迭代器取代)练习:用集合存储5个学生对象,并把学生对象进行遍历。 * * 分析: * A:创建学生类 * B:创建集合对象 * C:创建学生对象 * D:把学生添加到集合 * E:把集合转成数组 * F:遍历数组 public class StudentDemo { public static void main(String[] args) { // 创建集合对象 Collection c = new ArrayList(); // 创建学生对象 Student s1 = new Student("林青霞", 27); Student s2 = new Student("风清扬", 30); Student s3 = new Student("令狐冲", 33); Student s4 = new Student("武鑫", 25); Student s5 = new Student("刘晓曲", 22); // 把学生添加到集合 c.add(s1); c.add(s2); c.add(s3); c.add(s4); c.add(s5); // 把集合转成数组 Object[] objs = c.toArray(); // 遍历数组 for (int x = 0; x < objs.length; x++) { // System.out.println(objs[x]); Student s = (Student) objs[x]; System.out.println(s.getName() + "---" + s.getAge()); } }}所需的同一个包下的Student类如下 8.Iterator迭代器Iterator iterator():迭代器,集合的专用遍历方式 Object next():获取元素,并移动到下一个位置。 boolean hasNext():如果仍有元素可以迭代,则返回 true。典型写法Collection c = new ArrayList();c.add("hello");c.add("world");c.add("java"); Iterator it = c.iterator(); // 实际返回的肯定是子类对象,这里是多态。 while (it.hasNext()) { // System.out.println(it.next());//这个其实也可以 String s = (String) it.next();//建议向下转型 System.out.println(s); } 9.注意事项 10.迭代器使用图解和原理解析 迭代器的源码 Iterator Iterable Collection都是接口 public interface Iterator { boolean hasNext(); Object next(); } public interface Iterable { Iterator iterator();//这个方法到这里还没有实现} public interface Collection extends Iterable { Iterator iterator();//这个方法到这里还没有实现} public interface List extends Collection { Iterator iterator();//这个方法到这里还没有实现} public class ArrayList implements List { public Iterator iterator() { return new Itr();//这个方法到这里开始实现 } private class Itr implements Iterator { public boolean hasNext() {} public Object next(){} //直到这里上面的接口方法才算真正实现了 }} Collection c = new ArrayList();c.add("hello");c.add("world");c.add("java");Iterator it = c.iterator(); //new Itr();while(it.hasNext()) { String s = (String)it.next(); System.out.println(s);} 11.List接口概述有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,列表通常允许重复的元素。 12.List集合的特有功能: A:添加功能 void add(int index,Object element):在指定位置添加元素 B:获取功能 Object get(int index):获取指定位置的元素 C:列表迭代器 ListIterator listIterator():List集合特有的迭代器 D:删除功能 Object remove(int index):根据索引删除元素,返回被删除的元素 E:修改功能 Object set(int index,Object element):根据索引修改元素,返回被修饰的元素。 13.ListIterator特有功能 public class ListDemo4 { public static void main(String[] args) { List list = new ArrayList(); list.add("hello"); list.add("world"); list.add("java"); ListIterator lit = list.listIterator(); while (lit.hasNext()) { String s = (String) lit.next(); System.out.println(s); } System.out.println("----"); while (lit.hasPrevious()) { String s = (String) lit.previous(); System.out.println(s); } }} 14.一个需要注意的问题问题 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。 按常理做法结果如下 运行有异常 ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。 产生的原因: 迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。 其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。 如何解决呢? A:迭代器迭代元素,迭代器修改元素 元素是跟在刚才迭代的元素后面的。 B:集合遍历元素,集合修改元素(普通for) 元素在最后添加的。附:接口 ListIterator<E>有如下几个方法(迭代器修改元素) 方法1如图 注意javaee被添加的位置元素是跟在刚才迭代的元素后面的 方法2如图 注意javaee被添加的位置元素在最后添加的。 15.数据结构数据结构:数据的组织形式面试题:常见的数据结构的优缺点?(数据结构+算法) 16.List的子类特点List:(面试题List的子类特点) ArrayList: 底层数据结构是数组,查询快,增删慢。 线程不安全,效率高。 Vector: 底层数据结构是数组,查询快,增删慢。 线程安全,效率低。 LinkedList: 底层数据结构是链表,查询慢,增删快。 线程不安全,效率高。 List有三个儿子,我们到底使用谁呢? 看需求(情况)。 要安全吗? 要:Vector(即使要安全,也不用这个,后面有替代的) 不要:ArrayList或者LinkedList 查询多:ArrayList 增删多:LinkedList day15补充集合的继承体系结构? 由于需求不同,Java就提供了不同的集合类。这多个集合类的数据结构不同,但是它们都是要提供存储和遍历功能的, 我们把它们的共性不断的向上提取,最终就形成了集合的继承体系结构图。 Collection |--List |--ArrayList |--Vector |--LinkedList |--Set |--HashSet |--TreeSet