A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李皓321 初级黑马   /  2018-4-14 23:54  /  723 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

day05 API(Object, System, 日期, 包装类, 正则)
Object的toString()方法:
        object类:
                 1, 是类层次结构的根类(上帝)。
                 2,所有类都直接或者间接继承了object类。
         成员方法:
                 string tostring(): 返回对象的字符串表示方法,如:
                                                  com.itheima,Student@1200d083
                            1,实现方式:
return  getClass().getName() + "@"+Integer.toHexString( hashCode());
                            2,代码解释:
                                    getClass():获取class 对象,即字节码对象。
                                    getName():获取类的全名(包名,类名 )
                                    Integer.toHexString():将int整形数字转换为十六进制字
                                                                     符串
                                   hashCode():获取hash值(通过内部地址转换成一个整数
                                                             再转换为十六进制数)
         重写toSting()方法:
                     1,作用:任何类可以重写toString()方法来自定义输出内容,
                                              开发调试时经常用。
                     2,Eclipse快捷键:Alt+Shift+s>Generate toString()。。。
获取字节码对象的3种方式
        获取字节码对象的3种方式:
                     1,Object类的 Class  getClass()方法
                             示例:Class  class = student.getClass();
                     2,类名.class属性:
                             示例:Class  class = Student.class;
                             扩展:实际上.class是一种特殊形式。称为类字面常量,
                                        class是关键字不能作为属性名且Object类中并没有定
                                        义这个属性。
                     3,Class类的静态方法  forName(String className)
                              示例:Class  class  =  Class .
                                                              forName("com.itheima.Student")
                              注意:因为该方法使用字符串来寻找类,有可能并没有该字
                                         符串对应的类 ,所以会抛出
                                         ClassNotFoundException 类无法找到的异常。

注意:
                     1,同一个类的字节码对象只有一个,地址值是相同的,无论创建
                           了多少个对象。
                     2,Class和class区别?:
                                Class是一个类,表示字节码文件的类
                                class是一个关键字,用于定义一个类
                     3,为什么变量名写clazz?:
                                 因为class是用于定义类的关键字,不能做变量名,所以改
                                 变几个字母来表示,也可以写别的代替。
                     4,获取类的全类名快捷键:
                                  光标移到类名,鼠标右键,点击Copy Qualified Name
Object类的equals方法:
       Object类:
                        boolean equals(Object obj) : 比较两个对象是否"相等"。
       String类和Object类的 boolean equals(Object obj) 区别:
                        String类的equals:比较字符串内容是否相同,重写了Object类
                                                       的equals方法。
                        Object类的equals:使用==来比较,基本数据类型比较值,引
                                                       用数据类型比较对象的地址值。
        快捷键:
                   快速进入类的快捷键:
                                  1,Ctrl + Shift + t , 输入类名
                                  2,如果显示 Source not found , 是找不到源码, 因为使
                                         用的是JRE环境没有源码
                                         2,1:点击 Attach Source > 选择 External File > 选               
                                                 择JDK安装目录下的 src.zip
                   查看一个类的方法树形图快捷键:
                                  1,Ctrl + o
                                  2,输入方法名称后回车可以快速跳转到方法的定义位 置
                   生成equals方法:
                                  Alt + Shift + s >  Generate hashCode() and equals()...
System类概述
       java.lang包下的类,不用导包就可以用
        System类:包含一些有用的类字段和方法,不能被实例化
                 类字段:静态成员
                          1,err:标准错误输出流。
                          2,in :标准输入流。
                          3,out:标准输出流。
                 常用静态方法
                         1, static void arrayCopy
                         (Object src, int srcPos, Object dest, int destPos, int length) :   
                          复制源数组中指定长度个元素到一个新数组中
                                  Object src:源数组(被复制的数组)
                                  int srcPos :源数组索引(从源数组哪个索引开始复制)
                                  Object dest:目标数组(要复制到哪个数组)
                                  int  destPos:目标数组索引(指定目标数组接收元素的
                                                        索引位置 。
                                  int length:长度(要复制的元素个数)
                          2,static  long  currenTimeMillis():返回系统时间的毫秒值     
                                                       从零时区 1970-01-01 00:00:00开始算
                          3,static void exit(int atatus):终止虚拟机的运行,0表示
                                正常退出,非0表示异常退出。         
System类的其他方法:
            static long currentTimeMillis() : 以毫秒值返回当前系统时间, 毫秒值从 0
                                                              时区的1970-01-01 00:00:00 开始计算
                             示例:
                                            1970-01-01 00:00:00.000 = 0
                                            1970-01-01 00:00:00.500 = 500
                                            1970-01-01 00:00:01.000 = 1000
这种时间表示方法也叫作 时间戳 , 按现在的时间计算分为10位和13位的, 10位精确到秒, 13位精确到毫秒。
Date类的概述和构造
              注意:(不要导错包! 有2个包中都有Date类, 一个是 java.sql.Date , 另
                         一个是 java.util.Date , 我们用的是java.util.Date)
              Date类:
                           日期类, 表示特定的瞬间, 可以通过方法来设定所表示的时间,
                           可以表示任意的时间
             构造方法:
                           Date Date() : 创建Date对象, 并表示当前系统时间
                           Date Date(long date) : 创建Date对象, 使用指定的时间
            成员方法:
                           String toLocalString() : 转换为本地时间格式的字符串
           已过时 是什么意思?
                          可能有缺陷, 不推荐使用, 有新的替代方法. 但仍然可以用. 调
                          用已过时的方法, 方法上会有一个删除线
Date类的常用方法
           成员方法
                          void setTime(long time) : 设置Date对象的时间
                          long getTime() : 获取Date对象中保存的时间毫秒值
                                        注意, 无论何时调用, 都是获取Date对象中已经存储的
                                        那一瞬间的时间, 而不是调用方法时的时间
SimpleDateFormat类概述
              SimpleDateFormat类:
                                         专门用于格式化和解析时间   
                       构造方法:
                                 SimpleDateFormat SimpleDateFormat(String pattern) :
                                 创建对象同时指定格式
                       成员方法:
                                1,格式化: Date对象 -> 指定格式的字符串, 如 2017-05-01
                                             12:34:12
                                 String format(Date date) : 格式化Date对象返回字符串
                                2,解析: 字符串 -> Date对象
                                  Date parse(String source) : 将字符串解析为Date对象
                                  该方法抛出 ParseException 解析异常, 因为字符串可能
                                  不匹配指定的格式
SimpleDateFormat功能测试
     构造方法: 2018-04-01 2018年04月01日
                SimpleDateFormat SimpleDateFormat(String pattern) : 创建对象同
                时指定格式
     成员方法
                String format(Date date) : 将Date对象格式化为字符串
                Date parse(String source) : 将字符串解析为Date对象
常用日期模式: 详细可见API文档
                 y : 年
M : 月
m : 分
D : 年中的天
d : 月中的天
H : 小时(24小时制)
K : 小时(12小时制)
S : 毫秒
s : 秒
E : 星期
                示例:  yyyy-MM-dd E HH:mm:ss.SSS , 结果为 2016-04-01 星期五
               17:29:15.868
   注意:
                每个 SimpleDateFormat 对象都有一个对应的模式, 无论 format() 还
                     是 parse() , 都是用该对象的模式操作
                如:  new SimpleDateFormat("yyyy-MM-dd") 和 new  
                    SimpleDateFormat("yyyy年MM月dd日") 两个对象的模式就不一样
Calendar的概述和测试
          Calendar 类:
                      日历类, 也是处理时间和日期的类, 用于替代Date类
          创建对象:
                      静态方法:  static Calendar getInstance()
                            示例:  Calendar c = Calendar.getInstance();
          静态字段: 表示时间的某个部分
static YEAR : 年份
static MONTH : 月份. 注意月份数值是0-11
static DAY_OF_MONTH : 日期
static HOUR : 小时(12小时制)
static HOUR_OF_DAY : 小时(24小时制)
static MINITE : 分钟
static SECOND : 秒
        成员方法:
                     1, int get(int field) : 返回给定日历字段的值
                         例如:
              获取日期:  int day = calendar.get(Calendar.DAY_OF_MONTH);
                   2, void set(int field, int value) : 将给定的日历字段设置为给定值
                         例如:
设置年:  calendar.set(Calendar.YEAR, 2000);
设置月:  calendar.set(Calendar.MONTH, 0);
                  3,void add(int field, int amount) : 为给定的日历字段添加或减去指
                       定的时间量, 如时间字段是天, 增加n天, 时间字段是秒, 增加n秒.
                       减少用负数
                         例如:
当前日期增加一天:  calendar.add(Calendar.DAY_OF_MONTHY, 1);
当前日期减少一天:  calendar.add(Calendar.DAY_OF_MONTHY, -1);
包装类的概述和基本使用
           什么是包装类?
                   包装类是封装了基本数据类型的类, 提供了更多复杂的方法和变量
                   同时将基本类型的使用转换为了类的面向对象方式
          基本数据类型与其包装类的对应关系
byte: Byte
short: Short
char: Character
int: Integer
long: Long
float: Float
double: Double
boolean: Boolean
         Integer
            相关方法
                  构造方法
                        Integer(int value) : int转Integer
                        Integer(String value) : String转Integer
                  成员方法
int intValue() : Integer转int
String toString() : Integer转String
                       static int parseInt(String value) : String转Integer
           整数基本类型和包装类转换
                      int转Integer
                             利用Integer的构造方法:  Integer Integer(int value)
                                      如:  Integer i = new Integer(10);
                     Integer转int
                            利用Integer的成员方法:  int intValue()
                                      如:  int a = i.intValue();
           字符串和整数转换
                     String转int/Integer
                               方式1:  Integer Integer(String s)
                                      如:  Integer i = new Integer("10");
                               方式2:  static int parseInt(String s)
                                      如:  int a = Integer.parseInt("10");
                               方式3:  static Integer valueOf(String s)
                                      如:  int b = Integer.valueOf("10");
                    int/Integer转String
                               方式1:  "" + int值
                                      如:  String a = "" + 10;
                               方式2:  String toString()
                                      如:  String a = i.toString();
                               方式3:  static String toString(int i)
                                      如:  String a = Integer.toString(10);
        扩展: 包装类有什么用?
                      1,常用一些转换方法
     2,包装类默认值是 null , 数字基本数据类型默认值是 0 , 而在实际开发中0也有可能是正常数值, 比如温度,人数等. 有时我们需要判断一个成员变量否进行过初始化, 0可能会被认为是已经初始化的正常数据, 所以用包装类是否为null判断更合适               
包装类的自动装箱和自动拆箱
        箱=包装
        什么是自动装箱?
                  概念: 基本数据类型可以自动转换为包装类
                  示例:  Integer i = 10;
                  原理: 相当于执行 Integer i = new Integer(10);
                           或 Integer i = Integer.valueOf(10);
       什么是自动拆箱?
                  概念: 包装类可以自动转换为基本数据类型
                  示例:  Integer i = 10; int a = i;
                  原理: 相当于执行 int a = i.intValue();
       自动拆装箱的应用场景
                  集合只能存储引用数据类型, 但有了自动拆装箱, 基本类型也可以转
                  换为包装类存入集合中
list.add(1) : 1自动装箱
int i = list.get(0); : i自动拆箱                     
正则表达式概述
   什么是正则表达式?
是一种用于匹配字符串的规则
可用于判断字符串是否符合某种规则, 比如是否是邮箱, 是否是手机
       号等等
   Pattern 类:
创建正则表达式模板, 内有正则表达式规则
   常用规则: 具体查看API文档的Pattern类
字符:
x : 一个字符x a b c "abc" "aab"
\\ : 表示 \ 反斜杠.
     为什么有2个? 第一个 \ 是转义的作用
[abc] : a或b或c, 即中括号字母中的其中一个 [abc]{2} "aa"
[^abc] : 除a, b, c之外的任何字符.
           ^ 表示否定
[a-zA-Z] : 小写英文a到z, 以及大写英文A到Z.
              - 表示范围
  预定义字符
     . : 任何字符(对于行结束符, 可能匹配, 也可能不匹配)
\d : 数字0-9. 相当于 [0-9]
     d是digital的缩写
\D : 非数字. 相当于 [^0-9]
\s : 空白字符. 相当于 [ \t\n\x0b\f\r] , 包括空格(第一个空就是
       空格) s是space的缩写
\S : 非空白字符. 相当于 [^\s]
\w : 单词字符. 相当于 [a-zA-Z_0-9]
      w是word的缩写
\W : 非单词字符. 相当于 [^\w]
Greedy数量词
X? : X这个字符出现一次或零次
X* : X这个字符出现零次或多次, 包括一次
X+ : X这个字符出现一次或多次
X{n} : X这个字符恰好出现n次
X{n, } : X这个字符至少出现n次
X{n, m} : X这个字符至少出现n次, 但不超过m次
什么叫转义?
就是转换含义. 因为正则中有一些特殊字符, 如 + ,  - ,  * ,  \ 等都有特殊意义, 所以在作为普通字符使用时必须转义, 如:
用 \\ 转义: 因为 \x 可能表示某种符号, 如 \t 所以要用2个反斜
                杠
+ 表示一个或多个,  \\+ 表示加号字符
- 表示范围,  \\- 表示减号字符
* 表示零个或多个,  \\* 表示星号字符
用 \ 转义:
\ 要结合某些字符进行匹配,  \\ 表示斜杠字符
切割字符串
          String类
String[] split(String regex) : 按照正则表达式切分当前字符串为多个部分, 返回每个部分组成的字符串数组, 其中不包含分隔符。
今日扩展
使用包装类比较数值时的注意事项
1,==在比较引用数据类型时, 默认比较的是地址值
2,包装类也是引用类型, 对象使用==比较, 比较的是地址值, 所以最终还是比较对象地址值是否相同
3,而包装类在使用自动装箱时, 创建的包装类对象实际是这样执行的:
Integer x1 = 128; , 实际上是调用 包装类.valueOf() 方法, 相当于 Integer x1 =
Integer.valueOf(128); , 返回的是一个Integer对象
4,所以包装类用==比较是否相等, 实际比较的是 包装类.valueOf() 方法返回的对象地址值是否相等
      1,除了Short, Integer和Long包装类, 其他包装类的 valueOf() 方
           法, 内部都是 new 包装类(值); , 相当于创建了一个新的对象,
           所以两个对象地址值肯定不同
2,而Short, Integer和Long包装类的 valueOf() 方法, 内部提前对
      -128~127 范围的数创建了Short,
Integer或Long对象, 并存入了数组中进行了缓存, 所以每次调用 valueOf() 方法, 实际上是从缓存
数组中拿出相同的包装类对象, 所以在 -128~127 范围的Short, Integer, Long包装类的两个对象地址
值是相同的
那超出-128~127如何比较值是否相等呢?
可以使用equals()方法比较, 包装类对equals()方法都进行了重写, 调用equals()方法时, 是使用自动
拆箱获取基本类型的值进行比较的
总结:
-128~127范围内, 所有数值的包装类使用==比较数值是否相等是可以的, 也可以使用equals()方法比较
超出-128~127范围, 建议使用包装类的equals()方法比较
为了省事, 都使用equals()方法比较, 这更为面向对象

day06 集合(Collection, 迭代器, 增强for, 泛型,List子集)
1.集合的体系结构



     集合:
            是一个统称, 包含很多集合的实现类. 根据不同数据结构, 提供了不同的集合类
     数据结构:
            数据的组织和存储方式
     体系结构:
            将不同的集合实现类的共性向上抽取出父类, 从而形成一种体系
     如何学习一种体系结构:
            从顶层开始学习共性
            从底层使用具体实现
2.Collection接口中常用的功能
     Collection 接口
            是单列集合体系的顶层
     如何创建Collection对象?
            本身是接口, 实际使用的是子类对象. 使用多态,  Collection c = new ArrayList<>();
     常用方法:
           增: boolean add(E e) : 向集合中添加元素, 添加成功返回true, 添加失败返回
                   false. 永远能够添加成功。            
             删:boolean remove(Object o) : 删除元素中的指定元素, 删除成功返回true, 删除   
                   失败返回false
                   void clear() : 清空集合中的元素
            判断:boolean contains(Object o) : 判断集合中是否包含指定元素, 包含返回true,
                    否则false。
                      boolean isEmpty() : 判断集合是否为空集合, 即没有元素. 没有元素返回
                     true, 否则false。
            获取个数:int size() : 获取集合中元素的个数
            转换:Object[] toArray() : 将集合转换为Object[]

迭代器的概述和测试
      Iterator 接口:
      迭代器
                 集合中把这种取元素的方式描述在Iterator接口中
      作用:
                  提供遍历集合的安全方式
      获取迭代器:
                 使用集合对象调用 Interator<E> iterator() 方法
      成员方法:
                  boolean hasNext() : 是否有下一个元素
                  E next() : 返回下一个元素
                  void remove() : 从迭代器指向的 collection 中移除迭代器返回的最后一个元素

并发修改异常
    并发修改异常:
                   ConcurrentModificationException
          并发:
                   并行发生, 即同时发生
          修改:
                  指的是会改变集合长度的操作:
                            1 增加元素
                            2.删除元素
                            3.清空元素
                            4 list的 set(int index, Object o) 方法可以修改集合中某个索引处的元素
                             值, 但并不会改变集合的长度, 所以不会发生并发修改异常。
          发生原因:
                    迭代器依赖于集合, 相当于集合的一个副本, 当迭代器在操作时, 如果发现迭
                   代器的副本和集合不一样, 则抛出并发修改异常
          如何避免:
                   方式1: 不使用迭代器
                   方式2: 在使用迭代器遍历时, 使用迭代器的方法修改
          添加元素:
                   List接口中的 ListIterator listIterator() 获取用于List的迭代器, 然后调用
                   ListIterator的add()方法
          删除元素:
                   remove()
List接口:
           列表, 是Collection的子接口
           特点:
                    元素存取有序, 元素可以重复, 有索引

泛型的概述和体现
泛型
          Generic type, 广泛的通用的类型, 具体什么类型由开发者定义
    1.为什么出现泛型?
          由于集合可以存储任意类型的对象, 所以可以按照Object类型存入, 如果我们向集合            
          中存储不同类型的对象后再遍历出来元素, 都是Object类型, 若要使用该类型的方
          法, 必须进行类型转换, 有可能发生类型转换错误
    2.例如:
         集合中存储了Student对象和String对象, 迭代出元素后并不知道具体是什么, 强转或
         调用方法时可能出错
    3.好处:
          避免类型转换问题
          减少警告
          简化代码书写
     4.作用:
          用于明确数据类型
          将运行时才发生的类型转换问题, 提前到了编译时期
     5.如何使用:
          出现 <某个字母> 的地方, 就可以使用具体的数据类型替代这个字母
     6.补充: 小问题
     7.为什么泛型写为 <E> ?
           只是在集合相关的泛型中会使用E, E是Element的缩写, 表示元素, 说明这个泛型的
           类型表示的是集合中元素的数据类型,
           在其他地方有可能还会出现 <T> 等其他字母, T是Type的缩写, 说明这个泛型表示
           的是数据类型
           英文字母并不一定对应单词的缩写, 只是为了见名知义. 写成任意的 <A> ,  <B> ...
           都可以


foreach的概述(也叫增强for循环)
foreach:
                增强for循环
         作用:
                遍历数组和集合
         格式:
                for (元素类型 变量名: 数组或集合对象)


         注意:
               增强for循环中不能修改集合(改变集合长度), 会发生 并发修改异常
         原因:
               因为增强for循环内部使用的是迭代器进行迭代
         增强for的优缺点:
               优点: 简单快捷的拿到每一个元素
               缺点:循环过程中不能修改集合不能像普通for循环那样使用索引

常见数据结构: 数组
数组的特点:
                长度一旦确定则不可改变
                元素有整数索引
                只能存储同一类型的元素
                既可以存储基本数据类型, 也可存储引用数据类型
     数组的增删改查:
               增加/插入元素:
                           1 创建一个新数组, 长度为原数组长度+1
                           2.遍历原数组, 将原数组的元素复制到新数组的相同索引位置, 直到遇到
                              要增加元素的索引位置
                           3.将要增加的元素值赋值到索引位置
                           4.继续复制剩余元素
                           5.删除元素:
                           6.创建一个新数组, 长度为原数组长度-1
                           7.遍历原数组, 将原数组的元素复制到新数组的相同索引位置, 直到遇到
                              要删除元素的索引位置
                           8.跳过要删除的元素, 继续将剩余元素复制到后续索引位置
              修改元素:  arr[0] = 10;
              获取元素:  int i = arr[0];
       通过以上增删改查的操作, 总结出数组的特点:
                            增删慢
                            查询快
常见数据结构: 链表
       什么是链表:
                        链接列表, 好比通过链子链接起来的一些结点
       什么是结点:
                       由 本结点地址值 ,  值 ,  下一个结点的地址值 这三部分组成
       链表的增删改查
                       增加元素:
                                 修改下一个结点的地址值
                       删除元素:
                                 将要删除结点的前一个结点中保存的下一个结点地址值, 修改为要删
                                 除结点的下一个结点的地址值(也就是说, 直接跳过要删除的元素)
                      修改元素:
                                从第一个结点根据其下一个结点地址值不断去寻找, 然后修改值
                     获取元素:
                                 从第一个结点根据其下一个结点地址值不断去寻找
     从以上增删改查操作中总结出链接的特点
                          增删快
                          查询慢
      扩展:  数组和链表在存储上的区别
                         数组中元素的内存地址值是连续的, 在查找时只要找到索引0位置的元素
                          的地址值, 后面按地址值往后找即可,好比课桌上的学号, 我找到0号在哪,
                          再找5号往后数就行了, 因为座位肯定是挨着的
                链表中元素的内存地址值可以不连续:
                           好比RPG游戏做找人任务, 找到第一个人, 才知道第二个人在哪里, 他们
                           不在一起
      链表还分双向链表和单向链表
                        1. 双向链表中一个结点会同时保存上一个结点和下一个结点的地址, 可以从
                         前往后找, 也可以从后往前找
                        2.单向列表只能保存上一个结点或下一个结点之一, 只能往一个方向找
常见数据结构: 栈, 队列
    栈(stack)
             特点:
                    先进后出(FILO, First In Last Out). 或后进先出(LIFO, Last In First Out)
            便于理解:
                   像手枪子弹匣, 入口和出口是一起的
   队列(queue)
             特点:
                    先进先出(FIFO, First In First Out).
            便于理解:
                    像管道, 一头入口, 另一头出口

List的特点和特有功能
    List 接口
             继承自 Collection 接口. 在 java.util 包下
    特点
             元素有序(存入和取出的顺序一样)
             有整数的索引.
             元素可以重复.
    特有功能 (都是按索引进行操作的)
              void add(int index, E element) : 添加元素
              E remove(int index) : 删除元素
              E set(int index, E element) : 修改元素
              E get(int index) : 获取元素

List的子类概述, LinkedList特有功能
    List的子类
          ArrayList :
                         底层数组结构. 查询快, 增删慢(常用方法之前学过)。
         LinkedList :
                         底层链表结构. 查询慢, 增删快
                特有方法 (用于处理开头和结尾的元素):
                         void addFirst(E e) : 将元素添加到开头
                         void addLast(E e) : 将元素添加到末尾
                         E getFirst() : 获取开头的元素
                         E getLast() : 获取结尾的元素
                         E removeFirst() : 删除第一个元素, 并返回删除的元素
                         E removeLast() : 删除最后一个元素, 并返回删除的元素

如何自定义泛型
泛型出现的目的:
             如果没有泛型, 我们想让一个方法能够传入不同类型的参数, 有以下几种方式:
                     1.定义不同参数类型的重载方法.
                               缺点: 定义方法太多
                      2.使用所有类的共同父类Object依靠多态接收.
                               缺点: 不能使用子类特有方法, 强转也有风险
             有没有办法既能向方法传入任何类型的对象, 又能使用该类特有的方法?
                       JDK1.5引入的泛型, 就可以实现这一点
                               优点: 只需要定义一个方法, 我们指定泛型为String, 那么就可以使用
                                       String特有方法; 如果指定为Integer, 就能使用Integer特有的方法
泛型的类型擦除
             1.泛型只是一种安全检测机制, 只在编译时期有效
             2.当源代码编译为class字节码文件后, 代码中是不存在泛型的, 这称为泛型的类型
                  擦除
             3.所以, 集合本质能够存储Object类型是没有因为添加了泛型而发生改变的
泛型的定义位置
             类:  class Student<T>
            接口:  interface USB<T>
      方法:
         成员方法: 成员方法既能使用自己定义的泛型, 也能使用该方法所在类上定义的泛型
                       1. 使用方法自己的泛型:
                                  public <C> void eat(C c) {}
                                  public <C> C eat(C c) {} // 返回泛型对象
                      2.使用类的泛型:
                                 public void eat(T t)
         静态方法: 静态方法只能使用自己定义的泛型, 不能使用该方法所在类上定义的泛型
                      1.方法自己的泛型:
                                 public <C> void eat(C c) {}
                      2. 类的泛型: 不能用
    泛型的边界:
                    主要解决, 当传入参数为 List<各种类型> 的问题,如果参数要求为
                        List<Object> , 那么传入 List<Dog> 是不对的, 因为 Java认为Dog不是
                        Object! 怎么办?
                    1. <?> : 通配符泛型
                              1. 表示不知道是什么类型
                               2.如:  List<?> , 注意这种情况编译器会给泛型随便起一个类型名字,
                                    如capture#1 , 我们没有任何类型可以匹配到, 所以这种集合只能存
                                   入 null这种集合没什么用途。
                     2.<? extends T> : 上界通配符
                                1.传入对象可以使用E类型及其子类对象
                                 2. 如:  List<? extends Animal> , 表示可以存入Animal及其子类对象
                     3.<? super T> : 下界通配符
                                 1.传入的对象可以使用E类型及其父类对象
                                 2.如:  List<? super Dog> , 表示可以存入Dog及其父类对象
<?> 和 <T> 的异同:
                 相同点:
                            都表示不确定的类型
                 不同点:
                           <T>
                                  用于声明泛型
                                 是自定义泛型
                                 表示具体的某一种类型
                                 可以作为类型使用:  T t = itertator.next();
                           <?>
                                用于作为泛型使用
                                是通配符泛型
                                泛指所有类型
                               不可作为类型使用
                               不能使用与泛型相关的方法, 如 add(E e) 等. 因为?不知道是什么类型

使用LinkedList实现栈和队列
                 栈: 先进后出
                           进: 元素添加到末尾,  addLast(E e)
                           出: 删除末尾的元素,  removeLast(E e)
                 队列: 先进先出
                           进: 元素添加到末尾,  addLast(E e)
                           出: 删除开头的元素,  E removeFirst()

今日总结
      集合:
               包含了不同的实现类, 向上抽取出了很多共性的接口, 形成了一个体系结构
      数据结构
                数据的组织和存储方式
      迭代器
                作用: 遍历集合
                并发修改异常:
                原因: 迭代集合时改变了集合的长度
       解决:
               不使用迭代器
               使用迭代器对象中的修改方法
      泛型:
               作用:
                      约束集合中元素的数据类型
                      将运行时发生的类型转换异常提前到了编译时期
      遍历集合的3种方式:
                      普通for循环
                      迭代器
                      增强for循环(优点):
                               优点: 快速简便的遍历集合元素
                               缺点: 不能在遍历过程中修改集合, 也没有索引可以使用
常见的数据结构
       数组
              特点:
                    长度一旦确定则不可改变
                    有整数索引
                    只能存储同一个数据类型的元素
                    既能存储基本数据类型, 又能存储引用数据类型
                    增删慢, 查询快
      链表
             特点:
                     增删快, 查询慢
     栈
             特点:
                     先进后出, FILO
     队列
             特点:
                     先进先出, FIFO
// 增强for循环格式
for (元素的数据类型 变量名 : 数组或集合对象) {
// 遍历出来的变量可以直接使用
}


Collection接口(单列集合体系的顶层)
     | * boolean add(E e): 添加元素, 添加成功返回true, 否则false
     | * void clear(): 清空集合中的元素
     | * boolean contains(Object o): 判断集合中是否包含指定的对象
     | * boolean isEmpty(): 判断集合中是否没有元素. 与null区分
     | * boolean remove(Object o): 从集合中删除一个元素, 删除成功返回true, 否则false
     | * int size(): 获取集合的长度(元素的数量)
     | * Object[] toArray(): 将集合转换为Object[]数组
     | * Iterator<E> iterator(): 获取集合的迭代器对象
     |- List接口(有序, 可重复, 有索引)
              | * void add(int index, E e): 添加元素到指定索引上
              | * E remove(int index): 删除索引上的元素, 并返回
              | * E set(int index, E e): 修改指定索引上的元素, 并返回被替换的元素
              | * E get(int index): 获取指定索引上的元素
              | * ListIterator listIterator(): 获取List特有的迭代器对象
              |- ArrayList类(底层是数组, 查询快, 增删慢)
              |- LinkedList类(底层是链表, 查询慢, 增删快)
                      * void addFirst(E e): 添加元素到集合的开头
                      * void addLast(E e): 添加元素到集合的末尾
                      * E getFirst(): 获取集合开头的元素
                      * E getLast(): 获取集合末尾的元素
                      * E removeFirst(): 删除开头的元素, 并返回
                      * E removeLast(): 删除末尾的元素, 并返回
Iterator接口·

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马