本帖最后由 blovedr 于 2018-11-15 10:36 编辑
2018.11.11 10:10 就业day02 集合和数组区别:(李) 集合:长度可变, 只能存储引用数据类型 数组:长度固定, 既可以存储基本类型也可以存储引用数据类型 Vector集合 ArrayList集合 LinkedList集合 TreeSet集合(无序集合) HashSet集合(无序集合) LinkedHashSet集合
学习集合目标: 1. 会使用集合存储数据 2. 会遍历集合, 把数据取出来 3. 掌握每种集合的特性 List接口 继承子类共性形成父类(接口) 1. 有序的集合 2. 允许重复元素 3. 有索引, 可用for循环遍历 Set接口 1. 不允许存储重复元素 2. 没有索引(不能使用普通for循环遍历) 共性: Collection接口 定义的是所有单列集合中共性的方法 所有单列集合都可以使用共性的方法 没有带索引的方法 集合框架学习方法: 1. 学习顶层: 学习顶层接口/抽象类共性的方法, 所有子类都可以使用 2. 使用底层;底层不是接口就是抽象类, 无法创建对象使用, 使用底层子类创建对象使用 集合的体系结构(李): 集合类有很多, 不断的抽取共性, 则形成了体系结构 Collection 1---List:有序(存和取的顺序不打乱),有索引, 允许重复 --- ArrayList --- LinkedList --- Vector(维克多)
1---Set: 无序(不保证存和取的顺序一致), 无索引, 不允许重复 --- HashSet ---LinkedHashSet --- TreeSet Collection 中常用功能:(李) boolean add(E e) 添加指定元素, 返回是否添加功能 boolean isEmpty() 判断集合是否为空(元素个数是否为0) booleanremove(Object o) 删除指定元素第一次出现的那个, 返回是否删除成功(当元素不存在删除失败) T[] toArray(T[] arr) 将集合转为指定数组 (对于ArrayList, 永远添加成功, 因为长度可变, 而且允许元素重复) 一般向下转型, 父类引用, 转为子类类型来接收, 但是Object[] String[],可以将其中某一个元素强转 只要是Collection的实现类,则一定拥有Collection的功能 Iterator: 迭代器接口:(李)
Iterator<E> Iterator() 返回一个迭代器对象
工作原理: 1. 默认迭代器对象指向集合的第一个元素, 2. 我们通过HasNext判断是否有指向位置的元素, 3. 如果有元素,可以通过next取出 Collection<String> c = newArrayList<>(); c.add(“****”); Iterator<String>it = c.iterator(); While (it.hasNext()) { // 通过HasNext判断是否有指向位置的元素 Sout(it.next()); }
注意事项: 1.NoSuchElenentException 没有指定元素异常 解释: 当迭代器遍历集合的末尾没有元素可以遍历了, 如果还调用next方法获取元素, 则跑出异常。 2、ConcurrentModificationException 当我们在使用迭代器进行集合元素遍历的时候, 如果此时我们对集合的元素进行了添加或删除, 则会导致遍历结果不确定, 则抛出异常。 记住: 我们使用迭代器的时候, 不要在使用过程中进行元素的添加或删除。 如果想解决这个并发修改异常:(略) 1. 不要使用迭代器来遍历集合, 使用转数组的方式 2. 在需要修改集合的时候, 不要使用集合去操作, 使用迭代器 2.3 增强for循环(foreach) 增强for循环:底层使用也是迭代器, 使用for循环的格式, 简化了迭代器的书写 Collection<E> extends Iterable<E>: 所有的单列集合都可以使用增强for
增强for循环:用来遍历集合或数组 格式: For(集合/数组的数据类型 变量名: 集合名/数组名) { Sout(变量名); } 增强for循环(foreach):(李)(iter) 格式: for(元素类型 变量名: 集合名/数组名) { Sout(变量名); }
工作原理: 每次都会将数组/集合的元素赋值给冒号左边的变量,我们可以通过操作变量从而操作集合中的元素 第三章 泛型 【参考图片】 泛型是一种未知的数据类型, 当我们不知道使用什么数据类型的时候, 可以使用泛型, 泛型也可以看成一个变量, 用来接收数据类型 E e: Element 元素 T t Type 类型 ArrayList集合在定义的时候, 不知道使用什么数据类型的时候, 所以使用泛型 E: 未知的数据类型 Public class ArrayList<E> { Public Boolean add(E e) {} Public E get(int index) {} } 3.2.10_使用泛型好处(李) 1. 限定了集合中存储的数据类型, 减少因为类型转换带来的一些问题(提高安全性) 2. 简化代码的书写, 可以不用向下转型 定义一个学生类,有姓名和年龄 创建四个学生对象,添加到一个ArrayList集合中 求四个学生的平均年龄 要求: 先不要使用泛型 3.3 11泛型定义和使用Generic(李) 泛型是一种未知的数据类型, 当我们不知道使用什么数据类型的时候, 可以使用泛型, 泛型可以接收任意的数据类型,可以使用Integer,String,Student… 创建对象的时候确定泛型的数据类型 // 不写泛型, 默认是Object类型 当我们创建对象的时候, 会给泛型赋值, 你给的是什么类型, 泛型就是什么类型 定义泛型类 在定义类的时候在类名后声明泛型: 当我们创建此类对象的时候,确定泛型具体是什么类型 Class Box<E> { }
定义泛型方法: 应用场景: 如果返回值类型和传递的参数是相关的, 这个时候推荐使用泛型方法。 Public <E> voidgetElement(ArrayList<E> list, int index) { }
需求: 定义方法, 获取集合中指定位置的元素, 并返回 在调用方法的时候确定泛型的数据类型
定义泛型接口 1. 在定义实现类的时候, 直接确定接口中的泛型具体类型 Interface Box<E> { }
Class BoxImpl implements Box<String> { } 2. 在定义实现类的时候不确定泛型的类型, 但在创建实现类对象的时候再去确定其具体类型 Interface Box<E> { }
Class BoxImpl implements Box<String> { } BoxImpl<String> b = new BoxImpl<String> ()
含有泛型的方法:泛型定义在方法的修饰符合返回值之间 格式: 修饰符<泛型> 返回值类型 方法名(参数列表(使用泛型 )){ 方法体; }
含有泛型的方法, 在调用方法的时候确定泛型的数据类型 传递什么类型的参数, 泛型就是什么类型 泛型的接口 含有泛型的接口,第一种使用方式: 定义接口的实现类, 实现接口, 指定接口的泛型(确定接口中的泛型具体类型) public interface Iterator<E> { E next(); }
Scanner类实现了Iterator接口,并指定接口的泛型为String, 所以重写的next方法泛型默认的是String public final class Scanner implements Interator<String> { public String next(){}
} 【参见视频泛型接口day02_13视频】 2018.11.11 16:25
含有泛型的接口第二种使用方式:接口使用什么泛型, 实现类就使用什么泛型, 类跟着接口走, 就相当于定义了一个泛型类, 创建对象的时候确定泛型的类型 泛型的边界:(李) (记下) 1. ? 是一个通配符, 如果泛型定义的类型是?代表可以传递任意类型的数据 2. ? extends Person 代表可以传递Person(该)类型, 以及其子类型 (上限) 3. ? super Person 代表可以传递Person(该)类型, 以及其父类型 (下限) 4.1.斗地主 模拟斗地主发牌 1. 准备牌: 四个花色, 每个花色13张, 大王小王 2. 洗牌: Collections.shuffle(List<?>list) 随机置换 3. 发牌: 发给三个人 i : 1---53 0 % 3 ---0 1 % 3 ---1 2 % 3 ---2 3 % 3 ---0 4 % 3 ---1 5 % 3 ---2
当余数为0的时候发给A 当余数为1的时候发给B 当余数为2的时候发给C
4.看牌: 将三个人得到的三组牌, 打印输出。
|