第一周笔记

                                           

一、源代码中重要组成元素

public表示访问说明符,表面该类是一个公共类,可以控制其他对象对类成员的访问。
class 用于声明一个类,其后跟的字符串是类的名称。
static 表示该方法是一个静态方法,允许调用main()方法,无需创建类的实例。
void 表示main()方法没有返回值。
main()方法是所有程序的入口,最先开始执行。
“/””/”之间的内容和以”//”开始的内容为java程序的解释。
二、Java执行流程机制

五、Java标识符

标识符是为方法、变量或其他用户定义项所定义的名称。标识符可以有一个或多个字符。由数字(0~9)和字母(A~Z 和 a~z)、美元符号($)、下划线(_)、人民币符号(¥)以及所有在十六进制 0xc0 前的 ASCII 码组成(各符号之间没有空格)。标识符的第一个符号为字母、下划线和美元符号,后面可以是任何字母、数字、美元符号或下划线。另外,Java 区分大小写,因此 myvar 和 MyVar 是两个不同的标识符。(不能以数字开头)

标识符分为两类,分别为关键字和用户自定义标识符。

注:不能把关键字、保留字作为标识符。 ​

标识符的长度没有限制。 ​

标识符区分大小写。

​1、关键字是有特殊含义的标识符,如 true、false 表示逻辑的真假。

2、用户自定义标识符是由用户按标识符构成规则生成的非保留字的标识符,如 abc 就是一个标识符。(标识符可以包含关键字,但不能与关键字重名。)

3、Java 语言目前定义了 51 个关键字,这些关键字不能作为变量名、类名和方法名来使用。以下对这些关键字进行了分类。

​ **数据类型:**boolean、int、long、short、byte、float、double、char、class、interface。

​ **流程控制:**if、else、do、while、for、switch、case、default、break、continue、return、try、catch、finally。

​ **修饰符:**public、protected、private、final、void、static、strict、abstract、transient、synchronized、volatile、native。

​ **动作:**package、import、throw、throws、extends、implements、this、supper、instanceof、new。

​ **保留字:**true、false、null、goto、const。

六、Java注释

1、单行注释://。

2、多行注释:/*   *    */。

3、文档注释:/**   *   */。

七、Java变量的声明和初始化

Java 语言是强类型语言,强类型包含以下两方面的含义:

所有的变量必须先声明、后使用。

指定类型的变量只能接受类型与之匹配的值。

初始化变量是指为变量指定一个明确的初始值。初始化变量有两种方式:一种是声明时直接赋值,一种是先声明、后赋值。另外,多个同类型的变量可以同时定义或者初始化,但是多个变量中间要使用逗号分隔,声明结束时用分号分隔。

注:变量是类或者结构中的字段,如果没有显式地初始化,默认状态下创建变量并默认初始值为 0。

​ 方法中的变量必须显式地初始化,否则在使用该变量时就会出错。

八、变量赋值

1、初始化变量是指为变量指定一个明确的初始值。初始化变量有两种方式:一种是声明时直接赋值,一种是先声明、后赋值。如下代码分别使用两种方式对变量进行了初始化。

2、另外,多个同类型的变量可以同时定义或者初始化,但是多个变量中间要使用逗号分隔,声明结束时用分号分隔。

3、Java 中初始化变量时需要注意以下事项:

​   (1)变量是类或者结构中的字段,如果没有显式地初始化,默认状态下创建变量并默认初始值为 0。

​ (2)方法中的变量必须显式地初始化,否则在使用该变量时就会出错。

九、成员变量

1、Java 的成员变量有两种,分别是全局变量和静态变量(类变量)。

名称

修饰

访问

生命周期

全局变量(实例变量)

无 static 修饰

对象名.变量名

只要对象被当作引用,实例变量就将存在

静态变量(类变量)

用 static 修饰

类名.变量名或对象名.变量名

其生命周期取决于类的生命周期。类被垃圾回收机制彻底回收时才会被销毁

九、局部变量

局部变量是指在方法或者方法代码块中定义的变量,其作用域是其所在的代码块。可分为以下三种:

​ 1、方法参数变量(形参):在整个方法内有效。

​ 2、方法局部变量(方法内定义): 从定义这个变量开始到方法结束这一段时间内有效。

​ 3、代码块局部变量(代码块内定义):**从定义这个变量开始到代码块结束这一段时间内有效。

​ 4、局部变量在使用前必须被程序员主动初始化值。               十、常量

1、Java 的整型常量值主要有如下 3 种形式。(32)

 ​ 十进制数形式:如 54、-67、0。

 ​ 八进制数形式:Java 中的八进制常数的表示以 0 开头,如 0125 表示十进制数 85,-013 表示十进制数 -11。

 ​ 十六进制数形式:Java 中的十六进制常数的表示以 0x 或 0X 开头,如 0x100 表示十进制数 256,-0x16 表示十进制数 -22。2、Java 的实型常量值主要有如下两种形式。(64)

十进制数形式:由数字和小数点组成,且必须有小数点,如 12.34、-98.0。

科学记数法形式:如 1.75e5 或 32&E3,其中 e 或 E 之前必须有数字,且 e 或 E 之后的数字必须为整数。

3、布尔型常量值

Java 的布尔型常量只有两个值,即 false(假)和 true(真)。

十、Java数据类型

Java 语言支持的数据类型分为两种:基本数据类型和引用数据类型。

型名称

关键字

占用内存

取值范围

字节型

byte

1 字节

-128~127

短整型

short

2 字节

-32768~32767

整型

int

4 字节

-2147483648~2147483647

长整型

long

8 字节

-9223372036854775808L~9223372036854775807L

单精度浮点型

float

4 字节

+/-3.4E+38F(6~7 个有效位)

双精度浮点型

double

8 字节

+/-1.8E+308 (15 个有效位)

字符型

char

2 字节

ISO 单一字符集

布尔型

boolean

1 字节

true 或 false

第二周笔记

1、数据类型的转换可以分为隐式转换(自动类型转换)和显式转换(强制类型转换)两种。

2、隐式转换(自动类型转换)
如果以下 2 个条件都满足,那么将一种类型的数据赋给另外一种类型变量的时,将执行自动类型转换(automatic type conversion)。 ​
(1)两种数据类型彼此兼容 ​
(2)目标类型的取值范围大于源数据类型(低级类型数据转换成高级类型数据)
在运算过程中,由于不同的数据类型会转换成同一种数据类型,所以整型、浮点型以及字符型都可以参与混合运算。自动转换的规则是从低级类型数据转换成高级类型数据。转换规则如下: ​

数值型数据的转换:byte→short→int→long→float→double。 ​
字符型转换为整型:char→int。
以上数据类型的转换遵循从左到右的转换顺序,最终转换成表达式中表示范围最大的变量的数据类型。3、基本数据类型大小排行榜

 byte    1字节

 short   2字节

 char    2字节

 int     4字节

 long    8字节

 float   4字节

 double  8字节

4、小类型数据转为大类型数据(自动转换)

大类型数据转为小类型数据时需要强制转换(类型强转),小类型  变量名  =  (需要转换的类型) 大类型;

注意:大类型数据转为小类型数据有可能会造成数据进度丢失和溢出

5、short类型与char类互相转化需要强制转换

9、二元运算符
Java 语言中算术运算符的功能是进行算术运算,除了经常使用的加(+)、减(-)、乘(*)和除(\)外,还有取模运算(%)。加(+)、减(-)、乘(*)、除(\)和我们平常接触的数学运算具有相同的含义。
一元运算符:
     -:取反
     ++:自增
     --:自减
11、java中赋值运算符:

         =:赋值符号

         +=:如, num += 2;  -----> 本质:num = num + 2;

         -=: 如, num -= 2;  -----> 本质:num = num - 2;

         *=: 如, num *= 2;  -----> 本质:num = num * 2;

         /=: 如, num /= 2;  -----> 本质:num = num / 2;

         %=: 如, num %= 2;  -----> 本质:num = num % 2;

12、java中逻辑运算符:

    与、或、非

   &&(短路与):如:a && b, 如果ab全部为true则结果为true,否则为false

   ||(短路或):如:a || b, a或者b有一个为true,或者ab均为true,则为true,否则为false

  !:a为true,则结果为false,a为false,则结果为true

13、&& 与 & 区别:如果 a 为 false,则不计算 b(因为不论 b 为何值,结果都为 false)

    || 与 | 区别:如果 a 为 true,则不计算 b(因为不论 b 为何值,结果都为 true)

关系运算符:
    ==:对等于
   !=:不等于

  >:大于

  <:小于

  >=:大于等于

<=:小于等

  注意:关系运算符的结果为布尔值类型

equals(obj)方法和 == 的区别:
    equals方法比较的是两个对象的内容是否相等
    == 比较的是两个对象再内存中存放的地址是否为同一个
15、java扫描器:用户从控制台输入数据,后台Java程序接收

//创建扫描器对象

Scanner scan = new Scanner(System.in);

16、next()与nextLine()方法的区别:

     1、当遇到空格或者回车的时候 next()方法停止读取

     2、当遇到回车的时候 nextLine()方法停止读取,读取整行数据

18、直接量的类型
并不是所有的数据类型都可以指定直接量,能指定直接量的通常只有三种类型:基本类型、字符串类型和 null 类型。具体而言,Java 支持如下 8 种类型的直接量。

1)int 类型的直接量

在程序中直接给出的整型数值,可分为二进制、十进制、八进制和十六进制 4 种,其中二进制需要以 0B 或 0b 开头,八进制需要以 0 开头,十六进制需要以 0x 或 0X 开头。例如 123、012(对应十进制的 10)、0x12(对应十进制的 18)等。

2)long 类型的直接量

在整型数值后添加 l 或 L 后就变成了 long 类型的直接量。例如 3L、0x12L(对应十进制的 18L)。

3)float 类型的直接量

在一个浮点数后添加 f 或 F 就变成了 float 类型的直接量,这个浮点数可以是标准小数形式,也可以是科学计数法形式。例如 5.34F、3.14E5f。

4)double 类型的直接量

直接给出一个标准小数形式或者科学计数法形式的浮点数就是 double 类型的直接量。例如 5.34、3.14E5。

5)boolean 类型的直接量

这个类型的直接量只有 true 和 false。

6)char 类型的直接量

char 类型的直接量有三种形式,分别是用单引号括起来的字符、转义字符和 Unicode 值表示的字符。例如‘a’,‘\n’和‘\u0061’。

7)String 类型的直接量

一个用双引号括起来的字符序列就是 String 类型的直接量。

在大多数其他语言中,包括 C/C++,字符串作为字符的数组被实现。然而,在 Java 中并非如此。在 Java 中,字符串实际上是对象类型。在教程后面你将看到,因为 Java 对字符串是作为对象实现的,因此,它有广泛的字符串处理能力,而且功能既强又好用。

8)null 类型的直接量

这个类型的直接量只有一个值,即 null。

在上面的 8 种类型的直接量中,null 类型是一种特殊类型,它只有一个值:null。而且这个直接量可以赋给任何引用类型的变量,用以表示这个引用类型变量中保存的地址为空,即还未指向任何有效对象。

19、关于字符串直接量有一点需要指出,当程序第一次使用某个字符串直接量时,Java 会使用常量池(constant pool)来缓存该字符串直接量,如果程序后面的部分需要用到该字符串直接量时,Java 会直接使用常量池(constantpool)中的字符串直接量。

提示: 由于 String 类是一个典型的不可变类,因此 String 对象创建出来的就不可能改变,因此无需担心共享 String 对象会导致混乱。

 常量池(constant pool)指的是在编译期被确定,并被保存在已编译的 .class 文件中的一些数据,它包括关于类、方法、接口中的常量,也包括字符串直接量。

编译期:是指把源码交给编译器编译成计算机可以执行的文件的过程。在Java中也就是把Java代码编成class文件的过程.编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误。

运行期:是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来,在Java中把磁盘中的代码放到内存中就是类加载过程,类加载是运行期的开始部分。

编译期分配内存并不是说在编译期就把程序所需要的空间在内存中分配好,而是说在编译期生成的代码中产生一些指令,在运行代码时通过这些指令把程序所需的内存分配好。只不过在编译期的时候就知道分配的大小,并且知道这些内存的位置。而运行期分配内存是指只有在运行期才确定内存的大小、存放的位置。

第三周笔记

Java 流程控制语句
一、Java 语句格式
4、复合语句
复合语句又称为语句块,是很多个语句的组合,从而可以将多个语句看作单个语句。

它的执行规则如下: 1、如果语句块是空的,控制转到语句块的结束点。 2、如果语句块不是空的,控制转到语句列表。当控制到达语句列表的结束点时,控制转到语句的结束点。

二、if else 语句
选择结构(也叫分支结构)解决了顺序结构不能判断的缺点,可以根据一个条件判断执行哪些语句块。选择结构适合于带有逻辑或关系比较等条件判断的计算。例如,判断是否到下班时间,判断两个数的大小等。

1、if 结构
if 语句是使用最多的条件分支结构,它属于选择语句,也可以称为条件语句。if 选择结构是根据条件判断之后再做处理的一种语法结构。默认情况下,if 语句控制着下方紧跟的一条语句的执行。

条件表达式:条件表达式可以是任意一种逻辑表达式,最后返回的结果必须是一个布尔值。取值可以是一个单纯的布尔变量或常 量,也可以是使用关系或布尔运算符的表达式。如果条件为真,那么执行语句块;如果条件为假,则语句块将被绕过而不被执行。

语句块:该语句块可以是一条语句也可以是多条语句。如果仅有一条语句,可省略条件语句中的大括号 {}。当从编程规范角度不 要省略大括号,省略大括号会使程序的可读性变差。

2、if-else 结构
单 if 语句仅能在满足条件时使用,而无法执行任何其他操作(停止)。而结合 else 语句的 if 可以定义两个操作,此时的 if…else 语句表示“如果条件正确则执行一个操作,否则执行另一个操作”。

3、多条件 if-else-if 语句
if 语句的主要功能是给程序提供一个分支。然而,有时候程序中仅仅多一个分支是远远不够的,甚至有时候程序的分支会很复杂,这就需要使用多分支的 if…else if 语句。

4、嵌套 if 的使用
if 语句的用法非常灵活,不仅可以单独使用,还可以在 if 语句里嵌套另一个 if 语句。同样,if…else 语句和 if…else if 语句中也可以嵌套另一个 if 结构的语句,以完成更深层次的判断。

三木运算语法:

    条件表达式 ? 表达式1 : 表达式2

    当表达式结果为true,执行表达式1,否则执行表达式2

    条件表达式 ? (条件表达式1 ? 表达式1 : 表达式2) : (条件表达式2 ? 表达式1 : 表达式2)

三、switch case语句
1、switch 语句格式
1.1、switch
表示“开关”,这个开关就是 switch 关键字后面小括号里的值,小括号里要放一个整型变量或字符型变量。表达式必须为 byte,short,int,char类型。

Java7 增强了 switch 语句的功能,允许 switch 语句的控制表达式是 java.lang.String 类型的变量或表达式。只能是 java.lang.String 类型,不能是 StringBuffer 或 StringBuilder 这两种字符串的类型。

1.2、case
表示“情况,情形”,case 标签可以是: 1、类型为 char、byte、 short 或 int 的常量表达式。 2、枚举常量。 3、从 Java SE 7 开始, case 标签还可以是字符串字面量。

注意:重复的 case 值是不允许的。

1.3、default
表示“默认”,即其他情况都不满足。default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。通常,default 块放在末尾,也可以省略不写。

1.4、break
表示“停止”,即跳出当前结构。

2、嵌套 switch 语句
可以将一个 switch 语句作为一个外部 switch 语句的语句序列的一部分,这称为嵌套 switch 语句。因为一个 switch 语句定义了自己的块,外部 switch 语句和内部 switch 语句的 case 常量不会产生冲突。

3、if 语句和 switch 语句的区别
if 和 switch 语句都表示条件语句,可以从使用效率和实用性两方面加以区分。

1. 从使用效率上区分

从使用效率上区分,在对同一个变量的不同值作条件判断时,既可以使用 switch 语句,也可以使用 if 语句。使用 switch 语句的效率更高一些,尤其是判断的分支越多,越明显。

2. 从实用性上区分

从语句的实用性角度区分,switch 语句不如 if 条件语句,if 语句是应用最广泛和最实用的语句。

3. 何时使用 if 语句和 switch 语句

在程序开发的过程中,何时使用 if 语句和 switch 语句,需要根据实际情况而定,应尽量做到物尽其用。不能因为 switch 语句的效率高就一直使用,也不能因为 if 语句常用就不用 switch 语句。需要根据实际情况,具体问题具体分析,使用最适合的条件语句。

一般情况下,对于判断条件较少的,可以使用 if 条件语句,但是在实现一些多条件的判断中,最好使用 switch 语

四、while 和 do while 循环

初始化语句(init statement): 一条或多条语句,这些语句用于完成一些初始化工作,初始化语句在循环开始之前执行。 循环条件(test_expression):这是一个 boolean 表达式,这个表达式能决定是否执行循环体。 循环体(body_statement):这个部分是循环的主体,如果循环条件允许,这个代码块将被重复执行。如果这个代码块只有一 行语句,则这个代码块的花括号是可以省略的。 迭代语句(iteration_statement):这个部分在一次循环体执行结束后,对循环条件求值之前执行,通常用于控制循环条件中 的变量,使得循环在合适的时候结束。

while循环:

*      语法:

*          while (循环条件) {

*              循环体

*          }

*

do.while循环

*      语法:

*          do{

*              循环体

*          } while (循环条件);

while循环与do...while循环的区别:

*      1、while是先判断后执行,do...while循环是先执行然后再判断

*      2、do...while循环至少执行一次

* while循环与do...while的特点:都是循环执行某一语句,循环次数素不固定

五、for循环

for循环:

*      语法:

*              for (表达式1; 表达式2; 表达式3) {

*                  循环体

*              }

*      特点:循环次数固定

循环嵌套

         */

        //如果循环嵌套层数超过三层,那么一定是逻辑出了问题

//      for(){

//        while(){

//        do{

//           for(){

//           }

//        }while

//      }

//    }

八、break 语句
break 用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到 break,系统将完全结束该循环,开始执行循环之后的代码。

在 Java 中,break 语句有 3 种作用,分别是:在 switch 语句中终止一个语句序列、使用 break 语句直接强行退出循环和使用 break 语句实现 goto 的功能。

1、使用 break 语句直接强行退出循环(break 不带标签)
可以使用 break 语句强行退出循环,忽略循环体中的任何其他语句和循环的条件判断。在循环中遇到 break 语句时,循环被终止,在循环后面的语句重新开始。

 foreach语法:

*      for(迭代变量类型 变量的名字 :需要遍历(迭代)的对象){

*          语句块;

*      }

*/

break语句:作用:结束当前循环

*/

定义方法的语法:

 *      修饰符  返回值类型   方法名(参数1,参数2...) { 方法体... }

 */

// 自定义方法输出

// 无返回值。有参数

定义有返回值的方法,但是没有参数

return关键字的作用:1、结束方法的执行。2、将方法的执行结果返回给调用者

 方法(函数)的类型:

 *      1、无参无返回值

 *          修饰符  void  方法名(){ 方法体 }

 *      2、无参有返回值

 *          修饰符   返回值类型   方法名(){ 方法体}

 *      3、有参无返回值

 *          修饰符   void   方法名(参数1, 参数2,....){ 方法体}

 *      4、有参有返回值

 *          修饰符   返回值类型  方法名(参数1, 参数2,....){ 方法体}

 */

/**

 * 比较两个数的大小,将大的值返回回去

 * @param num1

 * @param num2

 * @return 返回最大值

# 二、方法的定义和调用

首先方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

•       **修饰符:**修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。

•       返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。

•       **方法名:**是方法的实际名称。方法名和参数表共同构成方法签名。

•       **参数类型:**参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。

•       **方法体:**方法体包含具体的语句,定义该方法的功能。

方法调用

**方法的作用及特点:**

•       1、封装一段特定的业务逻辑功能

•       2、尽可能独立,一个方法只干一件事

•       3、方法可以被反复多次的调用

•       4、减少代码的重复,有利于代码的维护,有利于团队的协作

 **方法调用:**

•       调用方法:对象名.方法名(实参列表),类名.方法名()。

•       Java支持两种调用方法的方式,根据方法是否有返回值来选择:

*      1、通过 对象.方法名字(参数)

*      2、类名.方法(参数)

*      3、方法(参数)

调用非static关键字修饰的方法,语法:对象.方法(参数)

调用被static修饰的方法,语法:类名.方法(参数)

法重载:

       重载就是在一个类中,有相同的函数名称,但参数列表不相同的方法。

   注意:

       方法重载只与方法名字和参数列表有关,与方法返回值类型无关

   方法签名:方法名字 + 参数列表

   什么是程序?

   答:程序 = 算法 + 数据结构

*/

可变参数的定义, 可变参数最终会被封装成一个数组

可变参数必须位于参数列表的最后一个

    /*public String fun3(long... longs, String str, int num){

        return null;

    }*/

九、continue 语句
continue 语句是跳过循环体中剩余的语句而强制执行下一次循环,其作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。

continue 语句类似于 break 语句,但它只能出现在循环体中。它与 break 语句的区别在于:continue 并不是中断循环语句,而是中止当前迭代的循环,进入下一次的迭代。简单来讲,continue 是忽略循环语句的当次循环。

注意:continue 语句只能用在 while 语句、for 语句或者 foreach 语句的循环体之中,在这之外的任何地方使用它都会引起语法错误。

十、选择结构和循环结构的总结

Java 同样提供了这两种流程控制结构的语法,Java 提供了 if 和 switch 两种分支语句,并提供了 while、do while 和 for 三种循环语句。一般写循环语句时,分以下三步走:

3、定义初始值

4、设置判断条件

5、初始值变化

6、除此之外,JDK5 还提供了一种新的循环:foreach 循环,能以更简单的方式来遍历集合、数组的元素。

Java 还提供了 break、continue 和 return 来控制程序的循环结构,作用如下:

break:表示跳出当前层循环

continue:表示跳出本次循环,进入下一次循环

return:跳出当前方法的循环

当在实现某个功能语句时,如果需要通过某一个条件去判断,则用选择结构。当实现某个功能需要通过循环去实现,则用循环结构。当然循环和选择是可以相互嵌套的。

六、递归讲解
递归算法:

是一种直接或者间接地调用自身的算法。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。

递归算法:在函数或子过程的内部,直接或者间接地调用自己的算法。 递归算法的实质:是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。

递归算法解决问题的特点: (1) 递归就是在过程或函数里调用自身。  (2) 在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口。  (3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。  (4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

递归的两个条件:

1、可以通过递归调用来缩小问题规模,且新问题与原问题有着相同的形式。(自身调用)

2、存在一种简单情境,可以使递归在简单情境下退出。(递归出口)

递归三要素:

1、一定有一种可以退出程序的情况;

2、总是在尝试将一个问题化简到更小的规模

3、父问题与子问题不能有重叠的部分

数组
一、数组以及数组的声明和创建
数组的定义:

相同数据类型元素的集合、是一种数据类型(引用类型)

数组的声明:

首先必须先声明数组变量,然后才能在程序中使用数组,

数组的四个基本特点:

1、 数组一旦被创建,它的大小将不可以在被改变。

2、 数组元素必须是相同类型的,不允许出现混合类型。

3、 数组中的元素可以是任何类型,包括基本类型与引用类型。

4、 数组属于引用类型,数组可以看成是一个对象,数组中的每一个元素相当于该对象的成员变量,因为数组本身就是对象,Java中对象是存放在堆中的,因此数组无论保存原始类型还是其他类型,数组对象本身都是在堆中。

public class Demo01 {

    public static void main(String[] args) {

        /**

         * 数组定义:

         *      用来存放相同类型的一组数据

         *      数组下标从0开始,对数组元素进行操作是通过数组的下标(索引)

         *      数组一旦被创建,则数组的长度不可被修改

         *    语法:

         *          静态创建数组

         *          数据类型[] 数组名 = {值1,值2....}

         *          数据类型 数组名[] = {值1,值2....}

         *          动态创建数组

         *          数据类型[] 数组名 = new 数据类型[数组长度]

         *          数据类型 数组名[] = new 数据类型[数组长度]

          静态创建数组,特点:创建数组的同时给数组元素赋值

            动态创建数组,特点创建数组时指定数组的长度

      

二、数组三种初始化
1.静态初始化

除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

// 静态初始化基本类型数组

int[] a = {1, 2, 3};

2.动态初始化

数组定义与为数组元素分配空间并赋值的操作分开进行

int[] a1 = new int[2];// 动态初始化元素,先分配空间

a1[0] = 1;// 给数组元素赋值

a1[2] = 2;

3.数组的默认初始化

数组是引用类型,他的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化

int a2[] = new int[2];//默认值0,0

boolean[] b = new boolean[2];//默认值 false,false

String[] s = new String[2];//默认值null

三、下标越界异常
数组边界:

数组的下标合法区间为:[0,length-1],如果在这个范围之外将会报错,这种情况称为数组下标越界。例如:

public static void main(String args[]){

       int[]  arr  =  new  int[2];

       // 下列代码将在运行时出现ArrayIndexOutOfBoundsException异常

       System.out.ptintln(arr[2]);

}

注意:

1、 数组是相同数据类型(数据类型可以为任意类型)的有序集合。

2、 数组也是对象,数组元素相当于对象的成员变量。

3、 数组一旦声明,长度就已经确定,不可以再被改变,如果越界,则会报:ArrayIndexOutOfBoundsException异常

四、数组的使用
遍历数组:

遍历数组的意思就是将数组的元素逐个取出来,通常我们使用循环进行遍历。

数组的使用还有很多,例如:查找数组元素中最大的值,数组反序,将数组作为方法的返回值,将数组作为参数等。

第四周笔记

五、二维数组
1、 java中使用 [][] 来定义二维数组,定义数组时也可同时初始化。

两种初始化形式:

(1) 格式1、动态初始化

数据类型 数组名[][] = new 数据类型[m][n]

数据类型[][]  数组名 = new 数据类型[m][n]

数据类型[]   数组名[] = new 数据类型[m][n]

(2) 格式2、 静态初始化

2、

二维数组:

*      数据类型[][] 数组名字 = new 数据类型[m][n]

*

*      本质:数组的元素还是数组

六、Arrays类

Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象类调用(注意是“不用”,而不是“不能”)。

Arrays类具有以下常用的功能:

给数组赋值:通过调用fill方法。

对数组进行排序:通过sort方法。

比较数组:通过equals方法比较数组中元素的值是否相等。

查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。

将数组转为字符串输出:通过toString方法实现。

数组的复制:

*      System.arraycopy(arr, start, dist, index, length)

*   src为原数组,1为复制的起始位置,dest为目的数组,0为目的数组放置的起始位置,6为复制的长度

*    dest为目的数组,src为原数组,clone复制实现数组全部复制。

*注:clone()比较特殊,对于对象而言,它是深拷贝,但是对于数组而言,它是浅拷贝。

数组扩容与缩容的实质:就是创建一个新的数组,新数组的长度比原来的数组(大,扩容,小,缩容)

排序算法
2、算法分类
十种常见排序算法可以分为两大类:

比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。

非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。

3、相关概念
稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。

* Arrays.binarySearch(arr, 96);该方法的返回值为查找到的元素下标

* 注意使用该方法的前提是数组必须要排好序

Arrays.equals(b1, b2)

* 比较数组:通过equals方法比较数组中元素的值是否相等。

4、冒泡排序(Bubble Sort)
冒泡排序是一种简单的排序算法。

6、选择排序(Selection Sort)
选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

8、插入排序(Insertion Sort)
插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

10、排序方法有:冒泡排序(Bubble Sort)、选择排序(Selection Sort)、插入排序(Insertion Sort)、希尔排序、(Shell Sort)、归并排序、(Merge Sort)、快速排序(Quick Sort)、堆排序(Heap Sort)、计数排序(Counting Sort)、桶排序(Bucket Sort)、基数排序(Radix Sort)

八、稀疏数组
稀疏数组介绍:

当一个数组中大部分元素为0时,或者为同一值的数组时,可以使用稀疏数组来保存该数组。

稀疏数组的处理方式是:

1、 记录数组一共有几行几列,有多少个不同的值。

2、 把具体有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。

稀疏数组定义:

稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组。

Java面向对象——OOP
一、什么是面向对象
面向过程的结构化程序设计:

结构化程序设计的弊端:

1、缺乏对数据的封装

2、数据与方法(操作数据)的分离

什么是面向对象:

面向对象的本质就是:以类的方式组织代码,以对象的组织(封装)数据。

什么是抽象的数据类型:

所谓抽象数据类型可以理解为:将不同类型的数据的集合组成一个整体,用来描述一种新的事务。如:对象类型数据

什么是类?什么是对象?

1、现实世界是由很多很多对象组成的

基于对象抽出了类

2、对象:真实存在的单个的个体

类:类型/类别,代表一类个体

3、类中可以包含:

3.1、所有对象所共有的属性/特征------------成员变量

3.2、所有对象所共有的行为-----------------方法

/

4、一个类可以创建多个对象

同一类型所创建的对象,结构相同,数据不同

5、类是对象的模板,对象是类的具体的实例

面向对象的三大特征:

封装、继承、多态

二、面向对象分析产生三种模型

1、对象模型:对用例模型进行分析,把系统分解成互相协作的分析类,通过类图\对象图描述对象\对象的属性\对象间的关系,是系统的静态模型

2、动态模型:描述系统的动态行为,通过时序图/协作图/描述对象的交互,以揭示对象间如何协作来完成每个具体的用例。单个对象的状态变化/动态行为可以通过状态图来表示。

3、功能模型(即用例模型à作为输入)

三、OOA的主要优点

1、加强了对问题域和系统责任的理解。 2、改进与分析有关的各类人员之间的交流 ​ 3、对需求的变化具有较强的适应性 ​ 4、支持软件复用。 ​ 5、贯穿软件声明周期全过程的一致性、 ​ 6、实用性 ​ 7、有利于用户参与

二、类与对象的创建
定义一个类:

定义类的成员变量:

1、类的定义包括“成员变量”的定义和“方法”的定义,其中“成员变量”用于描述对象 共同的数据结构,“方法”则是所有对象共同的行为。

2、Java语言中,类的成员变量的定义可以使用如下的语法:

修饰符 class 类名 { 成员变量类型 变量名; ……… }

3、对象创建后,其成员变量可以按照默认的方式初始化,初始化对象成员变量时,其默认值的规则如下表所示:

成员变量类型

默认初始值

数值类型(byte、short、int、long、float、double)

0

boolean类型

false

char类型

/u0000

引用类型

null

定义类的方法:

类中除了定义成员变量,还可以定义方法,用于描述对象的行为,封装对象的功能,Java语言中,可以按照如下方式定义类中的方法:

class 类名 { 修饰符 返回值类型 方法名(参数列表){ 方法体……… } …………… }

创建对象语法:

 * 数据类型   引用类型变量   指向(引用)  new关键字        对象

 * Student       zs         =      new           Student();

 */

// 案例:创建Person对象

Person per = new Person(); // 实例化对象

// 访问对象的成员变量和方法,语法:对像名.成员变量名字/方法名字, 能点出什么东西全看类有什么东西

// 访问person类的成员变量

/**

 * Exception in thread "main" java.lang.NullPointerException

 * 空指针异常:

 *      造成空指针异常的原因:是因为对象为null,然后访问其对象变量或者方法

 */

// System.out.println(p4.toString());

null和NullPointerException:

1、对于引用类型变量。可以对其赋值为null,null的含义为“空”,表示还没有指向任何对象,例如:

Emp  emp  =  null; //emp为的值null,没有指向任何对象

emp  =  new  Emp(); //emp指向了一个Emp对象

2、当一个引用变量的值为null的时候,如果通过引用访问对象成员变量或者调用方法不符合逻辑时,会产生NullPointerException,例如:

int[]  arr  =  null;

arr.length;

第五周笔记

三、构造器/构造方法

1、构造方法(构造函数):

*      每一个Java类必须包含构造方法,如果程序员没有手动添加构造方法,则编译器会在编译时添加一个默认的

*   无参构造方法,关于构造方法的特点:1、构造方法的方法名字必须与类名完全相同(包括大小写必须相同),2、

*   构造方法没有任何返回值,连void关键字也没有。

*      构造方法的语法:

*              修饰符   类名(参数){

*                 方法体....

*              }

*      构造方法的作用:用于创建类的对象(实例化对象),还可以初始化成员比啊量的初始值

*

*      注意:当我们手动添加构造器(构造方法)之后,编译器将不在为我们添加默认的无参构造器

2、构造方法的重载:

为了使用方便,可以对一个类定义多个构造方法,这些构造方法都有相同的名称,但是方法的参数列表不同,称为构造方法的重载。

一个构造方法可以通过this关键字调用另外一个重载的构造方法

3、通过构造方法初始化成员变量:

构造方法常用于实例化对象和对成员变量进行初始化。

4、

this关键字的使用:

   this关键字用在方法体中,用于指向调用该方法的当前对象,简单来说,那个对象调用方法,this就指的是那个对象,严格来讲在方法中需要通过this关键字指明当前对象。

四、Java内存分析
1、堆、栈、方法区:
堆: new出来的对象(包括实例变量)

栈: 局部变量(包括方法的参数)

方法区: .class字节码文件(包括方法、静态变量)

2、内存区域类型
1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制;

2. 堆:存放所有new出来的对象;

3. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(对象可能在常量池里)(字符串常量对象存放在常量池中。);

4. 静态域:存放静态成员(static定义的);

5. 常量池:存放字符串常量和基本类型常量(public static final)。有时,在嵌入式系统中,常量本身会和其他部分分割离开(由于版权等其他原因),所以在这种情况下,可以选择将其放在ROM中 ;

6. 非RAM存储:硬盘等永久存储空间

3、对于string的特殊解释
1、对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。

2、对于基础类型的变量和常量:变量和引用存储在栈中,常量存储在常量池中。

对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。

形式参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。

成员变量存储在堆中的对象里面,由垃圾回收器负责回收。

4、常量池小结
Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。

所谓静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。

而运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。

三个非常重要的结论:

1、必须要关注编译期的行为,才能更好的理解常量池。

2、运行时常量池中的常量,基本来源于各个class文件中的常量池。

3、程序运行时,除非手动向常量池中添加常量(比如调用intern方法),否则jvm不会自动添加常量到常量池。

6、小结
1.内存管理:由JVM来管理的

1) 堆:

1.1) 存储new出来的对象(包括实例变量)

1.2) 垃圾: 没有任何引用所指向的对象

垃圾回收器(GC)不定时到内存中清理垃圾,

回收过程是透明的(看不到的),不一定一发现垃圾就立刻回收,

调用System.gc()可以建议虚拟机尽快调度GC来回收

1.3) 内存泄漏: 不再使用的内存没有被及时的回收

建议: 对象不再使用时及时将引用设置为null

1.4) 实例变量的生命周期:

在创建对象时存储在堆中,对象被回收时一并被回收

2) 栈:

2.1) 存储正在调用的方法中的所有局部变量(包括方法的参数)

2.2) 调用方法时,会在栈中为该方法分配一块对应的栈帧,

栈帧中存储方法中的局部变量(包括参数),

方法调用结束时,栈帧被清除,局部变量一并被清除

2.3) 局部变量的生命周期:

方法被调用时存储在栈中,方法结束时与栈帧一并被清除

3) 方法区:

3.1) 存储.class字节码文件(包括静态变量、方法)

3.2) 方法只有一份,通过this来区分具体的调用对象

五、对象数组
数组是对象:

1、在Java中,数组属于引用数据类型。

2、数组对象存储在堆中,数组变量属于引用类型,存储数组对象的地址信息,指向数组对象。

3、数组的元素可以看成数组对象的成员变量(只不过类型全部相同)

引用类型数组的声明:

数组的元素可以是任意类型,当然也包括引用类型。

注意:new Cell[4];实际是分配了4个空间用于存放4个Cell类型的引用,并不是分配了4给Cell类型的对象。

引用类型数组的初始化:

1)引用类型数组的默认初始值但是null。

2)如果希望每一个元素都指向具体的对象,需要针对每一个数组元素进行new运算。

六、访问控制修饰符
1、public和private
private修饰的成员变量和方法仅仅只能在本类中访问调用。

public修饰的成员变量和方法可以在任何地方调用,public修饰的内容是对外提供可以被调用的功能,需要相对稳定,private修饰的内容是对类实现的封装,如果“公开”会增加维护的成本。

2、 protected和默认访问控制
1)用protected修饰的成员变量和方法可以被子类及同一个包中的类使用。

2)默认的访问控制即不书写任何访问修饰符,默认访问控制的成员变量和方法可以被同一个包中的类调用。

3、访问控制修饰类
1)对于类的修饰可以使用public和默认的方式,public修饰的类可以被任意一个类使用,默认方法控制的类只能被同包中的类使用。

2)protected和private可以用于修饰内部类

private:私有的

*      特点:凡是被private关键字修饰的属性和方法,只能在本类了当中访问,在其他类当中访问则没有权限

*

* public:关键字

*      特点:任何地方都可以访问

七、封装
封装,简单的说就是该露的露,该藏的藏。我们在设计程序是要追求“高内聚,低耦合”,其中,高内聚指的是类的内部数据操作细节由自己完成,不允许外部干涉。低耦合指的是仅暴露少量的方法给外部调用(使用get/set方法)。

封装(对数据的隐藏),通常来说,应禁止直接访问应该对象中数据的实际表示,而是应该通过操作接口来访问,这种称为信息隐藏。

封装的意义:

1、对外提供可调用的,稳定的功能。

2、封装容易变化的,具体的细节,外界不可访问,这样封装的意义在于:

a. 降低代码出错的可能性,便于维护。

b. 当内部的实现细节改变时,只要保证对外的功能定义不变,其他的模块就不会因此而受到牵连。

封装的核心:属性私有化,行为(方法)公开化

八、继承
1、泛化的过程
2、extends关键字
1、通过extends关键字可以实现类的继承。

2、子类可以继承父类的成员变量及成员方法,同时也可以定义自己的成员变量和成员方法。

3、Java语言不支持多重继承,一个类只能继承一个父类,但是一个父类可以有多个子类。

3、继承中的构造方法
1、子类的构造方法中必须通过super关键字调用父类的构造方法,这样可以妥善的初始化继承自父类的成员变量。

2、如果子类的构造方法中没有调用父类的构造方法,Java编译器会自动的加入对父类的无参构造方法的调用(如果父类没有无参构造方法,则会有编译错误)。

4、父类的引用指向子类的对象
1、一个子类的对象可以向上造型为父类的类型,即,定义父类型的引用可以指向子类型的对象。

2、 父类的引用可以指向子类的对象,但是通过父类的引用只能访问父类所定义的成员,不能访问子类扩展的部分。

九、super关键字
在java里面,对于super关键字通常有两种用法:

1. 用在子类的构造方法里(初始化用),主要是调用父类的默认构造方法,如果父类有不止一个构造方法,可以通过super指定具体的构造函数,比如 super(paras)。

2. 用在子类里调用隐藏或重写的属性或行为,比如 super.onDestroy()等等。

对于第1种需要注意,super表示当前类的父类对象,super()调用的是父类默认的构造方法,即这样可以对父类进行初始化。如果没有对父类进行初始化,当子类调用父类的方法时,便会从逻辑上出现错误,因为没对父类初始化,父类的方法和属性便没有内存空间。

关于super 与 this 关键字的对比(区别):

1. super(参数):调用基类中的某一个构造函数(应该位于子类构造函数中的第一条语句)。

2. this(参数):调用本类中的构造函数(应该位于构造函数中的第一条语句)。

3. super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)。

4. this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)

5、调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。

6、super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它构造方法。

7、super()和this()均需放在构造方法内第一行。

8、尽管可以用this调用一个构造器,但却不能调用两个。

9、this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

10、 this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

11、 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

十、方法重写
方法的重写(Override):

1、发生在父子类中,方法名称相同,参数列表相同,方法体不同

2、重写方法被调用时,看对象的类型

3、遵循"两同两小一大"原则:------------了解

3.1、两同:

3.1.1、方法名称相同

3.1.2、参数列表相同

3.2、两小:

3.2.1、派生类方法的返回值类型小于或等于超类方法的

a、void时,必须相同

b、基本数据类型时,必须相同

c、引用数据类型时,小于或等于

3.2.2、派生类方法抛出的异常小于或等于超类方法的

3.3、一大:

3.3.1、派生类方法的访问权限大于或等于超类方法的

重写与重载的区别:

1、重写(Override):

1.1、发生在父子类中,方法名相同,参数列表相同,方法体不同

1.2、"运行期绑定",看对象的类型绑定方法

2、重载(Overload):

2.1、发生在一个类中,方法名相同,参数列表不同,方法体不同

2.2、"编译期绑定",看参数/引用的类型绑定方法

补充:

编译期:.java源文件,经过编译,生成.class字节码文件

运行期:JVM加载.class并运行.class

编译错误:只是检查语法

十一、多态
多态指的是同一方法可以根据发送对象的不同而采用多种不同的行为方式。

一个对象的实际类型是确定的,但是可以指向对象的引用的类型有很多。

多态存在的条件:

1、 有继承关系

2、 子类重写父类的方法

3、 父类引用指向子类对象

多态的意义:

1、行为的多态(所有抽象方法都是多态的)

2、对象的多态(所有对象都是多态的)

多态的表现形式:

1、重写:根据对象的不同来表现多态

2、重载:根据参数的不同来表现多态

注:多态是方法的多态性,属性没有多态性。

十二、instanceof 和类型转换
instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。

instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例(实例指的是“类”在实例化之后叫做一个“实例”。实例化:通常把用类创建对象的过程称为实例化),返回 boolean 的数据类型。

向上造型:

1)超类型的引用指向派生类的对象

2)能点出来什么,看引用的类型

向下造型:(容易出现类型转换异常)

1)派生类的引用指向超类对象

2)向下造型需要进行强转

3)能点出来什么,看引用的类型

第六周笔记

十三、static和final关键字
1、static修饰成员变量
1、用static修饰的成员变量不属于对象的数据结构,属于类的数据结构。

2、static变量是属于类的变量,通常可以通过类名来引用static成员。

3、static成员变量和类的信息一起存储在方法区,而不是在堆中,一个类的static变量只有一份,无论这个类创建了多少个对象。

2、static静态块
Static块属于类的代码块,在类加载期间指向代码块,只执行一次,可以用来在软件中加载静态资源。

/** * instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。 * * instanceof 是 Java 的保留关键字。它的作用是测试它左边的 * 对象是否是它右边的类的实例(实例指的是“类”在实例化之后叫做一个“实例”。 * 实例化:通常把用类创建对象的过程称为实例化),返回 boolean 的数据类型。 */

4、final修饰变量
1、final关键字修饰成员变量,表示变量不可被改变。

2、final修饰成员变量的两种方式初始化:

a. 声明的同时初始化

b. 构造函数中初始化

3、final关键字也可以修饰局部变量,使用之前初始化即可

5、final修饰方法
1、final关键字修饰的方法不可被重写。

2、使一个方法不能被重写的意义在于:防止子类在定义新方法使造成“不间意”重写。

6、final修饰类
1、final关键字修饰的类不可被继承。

2、 JDK中的一些基础类库被定义为final的,例如:String、Math、Integer、Double等。

3、使一个类不能继承的意义在于:可以保护类不被继承修改,可以控制滥用继承对系统造成的危害。

7、static final常量
1、static final修饰的成员变量称为常量,必须声明同时初始化,不可被改变。

2、static final常量会在编译期被替换,例如:

十四、抽象类(abstract)
抽象类描述:(在Java语言中使用abstract class来定义抽象类)

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

抽象方法:

1、由abstract修饰

2、只有方法的定义,没有具体的实现(连{ }都没有)

如果一个方法使用 abstract 来修饰,则说明该方法是抽象方法,抽象方法只有声明没有实现。需要注意的是 abstract 关键字只能用于普通方法,不能用于 static 方法或者构造方法中。

抽象方法的 3 个特征如下:

1)抽象方法没有方法体

2)抽象方法必须存在于抽象类中

3)子类重写父类时,必须重写父类所有的抽象方法

注意:在使用 abstract 关键字修饰抽象方法时不能使用 private 修饰,因为抽象方法必须被子类重写,而如果使用了 private 声明,则子类是无法重写的。

抽象类:

1、由abstract修饰

2、包含抽象方法的类必须是抽象类

不包含抽象方法的类也可以声明为抽象类------我乐意

3、抽象类不能被实例化

4、抽象类是需要被继承的,派生类:

4.1、重写所有抽象方法--------常用

4.2、也声明为抽象类----------一般不这么做

5、抽象类的意义:

5.1、封装派生类所共有的属性和行为---------代码复用

5.2、给所有派生类提供统一的类型-----------向上造型

5.3、可以包含抽象方法,为所有派生类提供统一的入口

派生类的具体行为不同,但入口是一致的

设计规则:

1、将派生类所共有的属性和行为,抽到超类中--------抽共性

2、所有派生类的行为都一样,设计普通方法

所有派生类的行为都不一样,设计为抽象方法

十五、接口(Interface)
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过实现(implements)接口的方式,从而来实现接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类相似点:

1)一个接口可以有多个方法。

2)接口文件保存在 .java 结尾的文件中,文件名使用接口名。

3)接口的字节码文件保存在 .class 结尾的文件中。

4)接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

1)接口不能用于实例化对象。

2)接口没有构造方法。

3)接口中所有的方法必须是抽象方法。

4)接口不能包含成员变量,除了 static 和 final 变量。

5)接口不是被类继承了,而是要被类实现。

6)接口支持多继承(接口不能继承类,接口只能继承接口)。

接口特性:

1)接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。

2)接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。

3)接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

抽象类和接口的区别:

1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。

2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。

3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。

4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

**注:JDK 1.8 以后,接口里可以有静态方法和方法体了

2、static修饰方法
1、通常的方法都会涉及到对具体对象的操作,这些方法在调用时需要隐式传递对象的引用(this)。

2、static修饰的方法则不需要针对某些对象进行操作,其运行结果仅仅与输入的参数有关,调用时直接用类名引用。

3、static在调用时没有具体的对象,因此在static方法中不能对非static成员进行访问,static方法的作用在于提供一些“工具方法”和“工厂方法”等。

3、static静态块
Static块属于类的代码块,在类加载期间指向代码块,只执行一次,可以用来在软件中加载静态资源。

4、final修饰变量
1、final关键字修饰成员变量,表示变量不可被改变。

2、final修饰成员变量的两种方式初始化:

a. 声明的同时初始化

b. 构造函数中初始化

3、final关键字也可以修饰局部变量,使用之前初始化即可

5、final修饰方法
1、final关键字修饰的方法不可被重写。

2、使一个方法不能被重写的意义在于:防止子类在定义新方法使造成“不间意”重写。

6、final修饰类
1、final关键字修饰的类不可被继承。

2、 JDK中的一些基础类库被定义为final的,例如:String、Math、Integer、Double等。

3、使一个类不能继承的意义在于:可以保护类不被继承修改,可以控制滥用继承对系统造成的危害。

7、static final常量
1、static final修饰的成员变量称为常量,必须声明同时初始化,不可被改变。

2、static final常量会在编译期被替换,

十六、内部类
java内部类的几种类型:成员内部类,静态内部类,方法内部类,匿名内部类。

成员内部类:成员内部类是类内部的非静态类。成员内部类不能定义静态方法和变量(final修饰的除外)。

静态内部类:

静态内部类是 static 修饰的内部类,这种内部类的特点是:

1、 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。

2、 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与 内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员。

3、 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();

方法内部类(局部内部类):

方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。

需要注意:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。

匿名内部类:

匿名类是不能有名称的类,所以没办法引用他们。必须在创建时,作为new语句的一部分来声明他们。但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。

十七、枚举
枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。

1、声明枚举
声明枚举时必须使用 enum 关键字,然后定义枚举的名称、可访问性、基础类型和成员等。

提示:如果没有显式地声明基础类型的枚举,那么意味着它所对应的基础类型是 int。

2、枚举类
Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。

第七周笔记

一、 String 和int的相互转换 1、String转换为int String字符串转整型int有以下两种方式: (1)、Integer.parselnt(str) (2)、Integer.valueOf(str).intValue()

注:在String转换int时, String的伯一 定足整数, 否则会报数字转换异常(java.lang.NumberFormatException)。

2、分配一个新字符串,该字符串包含字符数组参数的子数组中的字符。

 offset参数是子数组第一个字符的索引,count参数指定子数组的长度。

 复制子数组的内容;字符数组的后续修改不会影响新创建的字符串。

3、分配一个新字符串,该字符串包含来自Unicode码点数组参数子数组的字符。

offset参数是子数组第一个编码点的索引,count参数指定子数组的长度。

子数组的内容被转换为字符;int数组的后续修改不会影响新创建的字符串。

4、将字符串转为int类型数据

 *

 * 注意:

 *      将字符串转为int类型的值前提是字符内容必须是纯数字

 */

// 使用包装类进行转换

5、int转换为String 整型int转String字符串类型有以下3种方法: (1)、String S = String.valueOf(); (2)、String S = Integer.toString(); (3)、Strings=""+i;

注意:使用第三种方法相对第一第二种耗时比较大。 在使用第一种valueOf)方法时,注意valueOf括号中的值不能为空,否则会报空指针异常(NullPointerException),

二、valueOf()、 parse()和toString() 1、valueOf() valueOf()方法将数据的内部格式转换为可读的形式。它是一种静态方法,对于所有Java内置的类型,在字符串内被重载,以便每- 种类型都能被转换成字符串。valueOf() 方法还被类型Object重载,所以创建的任何形式类的对象也可被用作一个参数。

2、 parse() parseXxx$String)这种形式,是指把字符串转换为数值型,其中Xxx对应不同的数据类型,然后转换为Xxx指定的类型,如int型和float型。 3、toString() toString()可以把一个引用类型转换为String字符串类型,是sun公司开发Java的时候为了方便所有类的字符串操作而特意加入的一个方法。

三、字符串拼接(连接)

1、使用连接运算符"+“

2、使用concat()方法 在Java中,String 类的concat()方法实现了将一个字符串连接到另一 个字符串的后面。concat() 方法语法格式如下: 字符串1.concat(字符串 2); 执行结果是字符串2被连接到字符串1后面,形成新的字符串。

四、获取字符串长度(length()) 要获取字符串的长度,可以使用String类的length()方法,其语法形式如下: 字符串名.1ength();

五、截取(提取)子字符串(substring()) 在String中提供了两个截取字符串的方法,一个是从指定位置截取到字符串结尾,另-个是截取指定范围的内容。下面对这两种方 法分别进行介绍。 1、substring(int beginIndex)形式

此方式用于提取从索引位置开始至结尾处的字符串部分。调用时,括号中是需要提取字符串的开始位置,方法的返回值是提取的字符串。

2、substring(int begin, int end)形式 此方法中的begin表示截取的起始索引,截取的字符串中包括起始索引对应的字符; end 表示结束索引,截取的字符串中不包括结束 索引对应的字符,如果不指定end,则表示截取到目标字符串末尾。该方法用于提取位置begin和位置end位置之间的字符串部分。

注意: substring( 方法是按字符截取,而不是按字节截取。

第八周笔记

六、分割字符串(spilt())
String 类的 split() 方法可以按指定的分割符对目标字符串进行分割,分割后的内容存放在字符串数组中。该方法主要有如下两种重载形式:

str.split(String sign)

str.split(String sign,int limit)

其中它们的含义如下:

str:为需要分割的目标字符串。

sign:为指定的分割符,可以是任意字符串。

limit:表示分割后生成的字符串的限制个数,如果不指定,则表示不限制,直到将整个目标字符串完全分割为止。

使用分隔符注意如下:

1)“.”和“|”都是转义字符,必须得加“\”。

如果用“.”作为分隔的话,必须写成String.split("\\."),这样才能正确的分隔开,不能用String.split(".")。

如果用“|”作为分隔的话,必须写成String.split("\\|"),这样才能正确的分隔开,不能用String.split("|")。

2)如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“acount=? and uu =? or n=?”,把三个都分隔出来,可以 用String.split("and|or")。

七、字符串的替换
1、replace() 方法
replace() 方法用于将目标字符串中的指定字符(串)替换成新的字符(串),其语法格式如下:

字符串.replace(String oldChar, String newChar)

其中,oldChar 表示被替换的字符串;newChar 表示用于替换的字符串。replace() 方法会将字符串中所有 oldChar 替换成 newChar。

2、replaceFirst() 方法
replaceFirst() 方法用于将目标字符串中匹配某正则表达式的第一个子字符串替换成新的字符串,其语法形式如下:

字符串.replaceFirst(String regex, String replacement)

其中,regex 表示正则表达式;replacement 表示用于替换的字符串。

3、replaceAll() 方法
replaceAll() 方法用于将目标字符串中匹配某正则表达式的所有子字符串替换成新的字符串,其语法形式如下:

字符串.replaceAll(String regex, String replacement)

其中,regex 表示正则表达式,replacement 表示用于替换的字符串。

八、字符串比较
字符串比较是常见的操作,包括比较相等、比较大小、比较前缀和后缀串等。在 Java 中,比较字符串的常用方法有 3 个:equals() 方法、equalsIgnoreCase() 方法、 compareTo() 方法。

1、equals() 方法
equals() 方法将逐个地比较两个字符串的每个字符是否相同。如果两个字符串具有相同的字符和长度,它返回 true,否则返回 false。对于字符的大小写,也在检查的范围之内。equals() 方法的语法格式如下:

str1.equals(str2);

str1 和 str2 可以是字符串变量, 也可以是字符串字面量。

2、equalsIgnoreCase() 方法
equalsIgnoreCase() 方法的作用和语法与 equals() 方法完全相同,唯一不同的是 equalsIgnoreCase() 比较时不区分大小写。当比较两个字符串时,它会认为 A-Z 和 a-z 是一样的。

下面的代码说明了 equalsIgnoreCase() 的使用:

String str1 = "abc";

String str2 = "ABC";

System.out.println(str1.equalsIgnoreCase(str2));    // 输出 true

3、equals()与==的比较
理解 equals() 方法和==运算符执行的是两个不同的操作是重要的。如同刚才解释的那样,equals() 方法比较字符串对象中的字符。而==运算符比较两个对象引用看它们是否引用相同的实例。

4、compareTo() 方法

compareTo() 方法用于按字典顺序比较两个字符串的大小,该比较是基于字符串各个字符的 Unicode 值。compareTo() 方法的语法格式如下:

str.compareTo(String otherstr);

提示:如果两个字符串调用 equals() 方法返回 true,那么调用 compareTo() 方法会返回 0。

九、字符串查找
在给定的字符串中查找字符或字符串是比较常见的操作。字符串查找分为两种形式:一种是在字符串中获取匹配字符(串)的索引值,另一种是在字符串中获取指定索引位置的字符。

1、根据字符查找
String 类的 indexOf() 方法和 lastlndexOf() 方法用于在字符串中获取匹配字符(串)的索引值。

1.1、indexOf() 方法
indexOf() 方法用于返回字符(串)在指定字符串中首次出现的索引位置,如果能找到,则返回索引值,否则返回 -1。该方法主要有两种重载形式:

str.indexOf(value)

str.indexOf(value,int fromIndex)

其中,str 表示指定字符串;value 表示待查找的字符(串);fromIndex 表示查找时的起始索引,如果不指定 fromIndex,则默认从指定字符串中的开始位置(即 fromIndex 默认为 0)开始查找。

1.2、lastlndexOf() 方法
lastIndexOf() 方法用于返回字符(串)在指定字符串中最后一次出现的索引位置,如果能找到则返回索引值,否则返回 -1。该方法也有两种重载形式:

str.lastIndexOf(value)str.lastlndexOf(value, int fromIndex)

注意:lastIndexOf() 方法的查找策略是从右往左查找,如果不指定起始索引,则默认从字符串的末尾开始查找。

2、根据索引查找
String 类的 charAt() 方法可以在字符串内根据指定的索引查找字符,该方法的语法形式如下:

字符串名.charAt(索引值)

提示:字符串本质上是字符数组,因此它也有索引,索引从零开始。

十、StringBuffer 类

1、创建 StringBuffer 类
StringBuffer 类提供了 3 个构造方法来创建一个字符串,如下所示: ​ 1、StringBuffer() 构造一个空的字符串缓冲区,并且初始化为 16 个字符的容量。 ​ 2、StringBuffer(int length) 创建一个空的字符串缓冲区,并且初始化为指定长度 length 的容量。 ​ 3、StringBuffer(String str) 创建一个字符串缓冲区,并将其内容初始化为指定的字符串内容 str,字符串缓冲区的初始容量为 16 加上字符串 str 的长度。

2、追加字符串
StringBuffer 类的 append() 方法用于向原有 StringBuffer 对象中追加字符串。该方法的语法格式如下:

StringBuffer 对象.append(String str)

该方法的作用是追加内容到当前 StringBuffer 对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer 对象的内容也发生了改变,

3、替换字符
StringBuffer 类的 setCharAt() 方法用于在字符串的指定索引位置替换一个字符。该方法的语法格式如下:

StringBuffer 对象.setCharAt(int index, char ch);

该方法的作用是修改对象中索引值为 index 位置的字符为新的字符 ch,

4、反转字符串
StringBuffer 类中的 reverse() 方法用于将字符串序列用其反转的形式取代。该方法的语法格式如下:

StringBuffer 对象.reverse();

5、删除字符串
StringBuffer 类提供了 deleteCharAt() 和 delete() 两个删除字符串的方法,下面详细介绍。

1、deleteCharAt() 方法

deleteCharAt() 方法用于移除序列中指定位置的字符,该方法的语法格式如下:

StringBuffer 对象.deleteCharAt(int index);

2、delete() 方法

delete() 方法用于移除序列中子字符串的字符,该方法的语法格式如下:

StringBuffer 对象.delete(int start,int end);

其中,start 表示要删除字符的起始索引值(包括索引值所对应的字符),end 表示要删除字符串的结束索引值(不包括索引值所对应的字符)。该方法的作用是删除指定区域以内的所有字符,

总结
String 是 Java 中基础且重要的类,被声明为 final class,是不可变字符串。因为它的不可变性,所以拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所影响。

StringBuffer 就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类。它提供了 append 和 add 方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列。

在很多情况下我们的字符串拼接操作不需要线程安全,所以 StringBuilder 登场了。StringBuilder 是 JDK1.5 发布的,它和 StringBuffer 本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。

线程安全:

StringBuffer:线程安全 ​ StringBuilder:线程不安全

速度:

一般情况下,速度从快到慢为 StringBuilder > StringBuffer > String,当然这是相对的,不是绝对的。

使用环境:

操作少量的数据使用 String。 ​ 单线程操作大量数据使用 StringBuilder。 ​ 多线程操作大量数据使用 StringBuffer。

十一、正则表达式
正则表达式(Regular Expression)又称正规表示法、常规表示法,在代码中常简写为 regex、regexp 或 RE,它是计算机科学的一个概念。

    String 类里也提供了如下几个特殊的方法。

            1、boolean matches(String regex):判断该字符串是否匹配指定的正则表达式。

            2、String replaceAll(String regex, String replacement):将该字符串中所有匹配 regex 的子串替换成 replacement。

            3、String replaceFirst(String regex, String replacement):将该字符串中第一个匹配 regex 的子串替换成 replacement。

            4、String[] split(String regex):以 regex 作为分隔符,把该字符串分割成多个子串。

正则表达式中的特殊字符如下表所示。

特殊字符

说明

$

匹配一行的结尾。要匹配 $ 字符本身,请使用\$

^

匹配一行的开头。要匹配 ^ 字符本身,请使用\^

()

标记子表达式的开始和结束位置。要匹配这些字符,请使用\(和\)

[]

用于确定中括号表达式的开始和结束位置。要匹配这些字符,请使用\[和\]

{}

用于标记前面子表达式的出现频度。要匹配这些字符,请使用\{和\}

*

指定前面子表达式可以出现零次或多次。要匹配 * 字符本身,请使用\*

+

指定前面子表达式可以出现一次或多次。要匹配 + 字符本身,请使用\+

?

指定前面子表达式可以出现零次或一次。要匹配 ?字符本身,请使用\?

.

匹配除换行符\n之外的任何单字符。要匹配.字符本身,请使用\.

\

用于转义下一个字符,或指定八进制、十六进制字符。如果需匹配\字符,请用\\

|

指定两项之间任选一项。如果要匹配丨字符本身,请使用\|

正则表达式支持如下表所示的预定义字符。

预定义字符

说明

.

可以匹配任何字符

\d

匹配 0~9 的所有数字

\D

匹配非数字

\s

匹配所有的空白字符,包括空格、制表符、回车符、换页符、换行符等

\S

匹配所有的非空白字符

\w

匹配所有的单词字符,包括 0~9 所有数字、26 个英文字母和下画线_

\W

匹配所有的非单词字符

上面的 7 个预定义字符其实很容易记忆,其中: ​ d 是 digit 的意思,代表数字。 ​ s 是 space 的意思,代表空白。 ​ w 是 word 的意思,代表单词。 ​ d、s、w 的大写形式恰好匹配与之相反的字符。

方括号表达式

说明

表示枚举

例如[abc]表示 a、b、c 其中任意一个字符;[gz]表示 g、z 其中任意一个字符

表示范围:-

例如[a-f]表示 a~f 范围内的任意字符;[\\u0041-\\u0056]表示十六进制字符 \u0041 到 \u0056 范围的字符。范围可以和枚举结合使用,如[a-cx-z],表示 a~c、x~z 范围内的任意字符

表示求否:^

例如[^abc]表示非 a、b、c 的任意字符;[^a-f]表示不是 a~f 范围内的任意字符

表示“与”运算:&&

例如 [a-z&&[def]]是 a~z 和 [def] 的交集,表示 d、e f[a-z&&^bc]]是 a~z 范围内的所有字符,除 b 和 c 之外 [ad-z] [a-z&&[m-p]]是 a~z 范围内的所有字符,除 m~p 范围之外的字符

表示“并”运算

并运算与前面的枚举类似。例如[a-d[m-p]]表示 [a-dm-p]

Java 正则表达式还支持如下表所示的几个边界匹配符。

边界匹配符

说明

^

行的开头

$

行的结尾

\b

单词的边界

\B

非单词的边界

\A

输入的开头

\G

前一个匹配的结尾

\Z

输入的结尾,仅用于最后的结束符

\z

输入的结尾

数字和日期处理
一、Math类的常用方法
Java 中的 +、-、*、/ 和 % 等基本算术运算符不能进行更复杂的数学运算,例如,三角函数、对数运算、指数运算等。于是 Java 提供了 Math 工具类来完成这些复杂的运算。

Math 类位于 java.lang 包,它的构造方法是 private 的,因此无法创建 Math 类的对象,并且 Math 类中的所有方法都是类方法,可以直接通过类名来调用它们。

1、静态常量
Math 类中包含 E 和 PI 两个静态常量,正如它们名字所暗示的,它们的值分别等于 e(自然对数)和 π(圆周率)。

2、求最大值、最小值和绝对值
在程序中常见的就是求最大值、最小值和绝对值问题,如果使用 Math 类提供的方法可以很容易实现。这些方法的说明如下表所示。

方法

说明

static int abs(int a)

返回 a 的绝对值

static long abs(long a)

返回 a 的绝对值

static float abs(float a)

返回 a 的绝对值

static double abs(double a)

返回 a 的绝对值

static int max(int x,int y)

返回 x 和 y 中的最大值

static double max(double x,double y)

返回 x 和 y 中的最大值

static long max(long x,long y)

返回 x 和 y 中的最大值

static float max(float x,float y)

返回 x 和 y 中的最大值

static int min(int x,int y)

返回 x 和 y 中的最小值

static long min(long x,long y)

返回 x 和 y 中的最小值

static double min(double x,double y)

返回 x 和 y 中的最小值

static float min(float x,float y)

返回 x 和 y 中的最小值

二、生成随机数(random()和Random类)
在 Java 中要生成一个指定范围之内的随机数字有两种方法:一种是调用 Math 类的 random() 方法,一种是使用 Random 类。

Random 类位于 java.util 包中,该类常用的有如下两个构造方法。 Random():该构造方法使用一个和当前系统时间对应的数字作为种子数,然后使用这个种子数构造 Random 对象。 Random(long seed):使用单个 long 类型的参数创建一个新的随机数生成器。

三、数字格式化

符号

说明

0

显示数字,如果位数不够则补 0

#

显示数字,如果位数不够不发生变化

.

小数分隔符

-

减号

,

组分隔符

E

分隔科学记数法中的尾数和小数

%

前缀或后缀,乘以 100 后作为百分比显示

?

乘以 1000 后作为千进制货币符显示。用货币符号代替。如果双写,用国际货币符号代替; 如果出现在一个模式中,用货币十进制分隔符代替十进制分隔符

四、Java大数字运算
在 Java 中提供了用于大数字运算的类,即 java.math.BigInteger 类和 java.math.BigDecimal 类。这两个类用于高精度计算,其中 BigInteger 类是针对整型大数字的处理类,而 BigDecimal 类是针对大小数的处理类。

1、BigDecimal 类

BigInteger 和 BigDecimal 都能实现大数字的运算,不同的是 BigDecimal 加入了小数的概念。

BigDecimal 常用的构造方法如下。

1、BigDecimal(double val):实例化时将双精度型转换为 BigDecimal 类型。

2、BigDecimal(String val):实例化时将字符串形式转换为 BigDecimal 类型。

五、Java时间日期的处理

1、Date 类
Date 类表示系统特定的时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。

1.1、构造方法

Date 类有如下两个构造方法。

1、Date():此种形式表示分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒),使用该构造方法创建的对象可 以获取本地的当前时间。

2、Date(long date):此种形式表示从 GMT 时间(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒开始经过参数 date 指定的毫 秒数。

六、Java日期格式化

SimpleDateFormat 类主要有如下 3 种构造方法。 ​ SimpleDateFormat():用默认的格式和默认的语言环境构造 SimpleDateFormat。 ​ SimpleDateFormat(String pattern):用指定的格式和默认的语言环境构造 SimpleDateF ormat。 ​ SimpleDateFormat(String pattern,Locale locale):用指定的格式和指定的语言环境构造 SimpleDateF ormat。

SimpleDateFormat 自定义格式中常用的字母及含义如下表所示。

字母

含义

示例

y

年份。一般用 yy 表示两位年份,yyyy 表示 4 位年份

使用 yy 表示的年扮,如 11; 使用 yyyy 表示的年份,如 2011

M

月份。一般用 MM 表示月份,如果使用 MMM,则会 根据语言环境显示不同语言的月份

使用 MM 表示的月份,如 05; 使用 MMM 表示月份,在 Locale.CHINA 语言环境下,如“十月”;在 Locale.US 语言环境下,如 Oct

d

月份中的天数。一般用 dd 表示天数

使用 dd 表示的天数,如 10

D

年份中的天数。表示当天是当年的第几天, 用 D 表示

使用 D 表示的年份中的天数,如 295

E

星期几。用 E 表示,会根据语言环境的不同, 显示不 同语言的星期几

使用 E 表示星期几,在 Locale.CHINA 语 言环境下,如“星期四”;在 Locale.US 语 言环境下,如 Thu

H

一天中的小时数(0~23)。一般用 HH 表示小时数

使用 HH 表示的小时数,如 18

h

一天中的小时数(1~12)。一般使用 hh 表示小时数

使用 hh 表示的小时数,如 10 (注意 10 有 可能是 10 点,也可能是 22 点)

m

分钟数。一般使用 mm 表示分钟数

使用 mm 表示的分钟数,如 29

s

秒数。一般使用 ss 表示秒数

使用 ss 表示的秒数,如 38

S

毫秒数。一般使用 SSS 表示毫秒数

使用 SSS 表示的毫秒数,如 156

内置类及包装类
一、包装类、装箱和拆箱
1、包装类
在 Java 的设计中提倡一种思想,即一切皆对象。但是从数据类型的划分中,我们知道 Java 中的数据类型分为基本数据类型和引用数据类型,但是基本数据类型怎么能够称为对象呢?于是 Java 为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes),也有地方称为外覆类或数据类型类。

2、装箱和拆箱

基本数据类型转换为包装类的过程称为装箱,例如把 int 包装成 Integer 类的对象;包装类变为基本数据类型的过程称为拆箱,例如把 Integer 类的对象重新简化为 int。

3、包装类的应用

1) 实现 int 和 Integer 的相互转换

可以通过 Integer 类的构造方法将 int 装箱,通过 Integer 类的 intValue 方法将 Integer 拆箱。

2) 将字符串转换为数值类型

在 Integer 和 Float 类中分别提供了以下两种方法:

① Integer 类(String 转 int 型)

int parseInt(String s);

s 为要转换的字符串。

② Float 类(String 转 float 型)

float parseFloat(String s)

注意:使用以上两种方法时,字符串中的数据必须由数字组成,否则转换时会出现程序错误。

3) 将整数转换为字符串

Integer 类有一个静态的 toString() 方法,可以将整数转换为字符串。

二、Object类

Object 是 Java 类库中的一个特殊类,也是所有类的父类。也就是说,Java 允许把任何类型的对象赋给 Object 类型的变量。当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类。

1、toString() 方法
toString() 方法返回该对象的字符串,当程序输出一个对象或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString() 方法返回该对象的字符串表示。

哈希码(hashCode),每个 Java 对象都有哈希码属性,哈希码可以用来标识对象,提高对象在集合操作中的执行效率。

2、equals() 方法

在前面学习字符串比较时,曾经介绍过两种比较方法,分别是==运算符和 equals() 方法,==运算符是比较两个引用变量是否指向同一个实例,equals() 方法是比较两个对象的内容是否相等,通常字符串的比较只是关心内容是否相等。

3、getClass() 方法
getClass() 方法返回对象所属的类,是一个 Class 对象。通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等。

4、接收任意引用类型的对象
既然 Object 类是所有对象的父类,则所有的对象都可以向 Object 进行转换,在这其中也包含了数组和接口类型,即一切的引用数据类型都可以使用 Object 进行接收。

三、Integer类
Integer 类在对象中包装了一个基本类型 int 的值。Integer 类对象包含一个 int 类型的字段。此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。

1、Integer 类的构造方法
Integer 类中的构造方法有以下两个: ​ Integer(int value):构造一个新分配的 Integer 对象,它表示指定的 int 值。 ​ Integer(String s):构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。

2、Integer 类的常量
Integer 类包含以下 4 个常量。 ​ MAX_VALUE:值为 231-1 的常量,它表示 int 类型能够表示的最大值。 ​ MIN_VALUE:值为 -231 的常量,它表示 int 类型能够表示的最小值。 ​ SIZE:用来以二进制补码形式表示 int 值的比特位数。 ​ TYPE:表示基本类型 int 的 Class 实例

四、Float类

1、Float 类的构造方法
Float 类中的构造方法有以下 3 个。 ​ Float(double value):构造一个新分配的 Float 对象,它表示转换为 float 类型的参数。 ​ Float(float value):构造一个新分配的 Float 对象,它表示基本的 float 参数。 ​ Float(String s):构造一个新分配的 Float 对象,它表示 String 参数所指示的 float 值。

五、Double类

1、Double 类的构造方法
Double 类中的构造方法有如下两个。 ​ Double(double value):构造一个新分配的 Double 对象,它表示转换为 double 类型的参数。 ​ Double(String s):构造一个新分配的 Double 对象,它表示 String 参数所指示的 double 值。

四、Number类
Number 是一个抽象类,也是一个超类(即父类)。Number 类属于 java.lang 包,所有的包装类(如 Double、Float、Byte、Short、Integer 以及 Long)都是抽象类 Number 的子类。

Number 类定义了一些抽象方法,以各种不同数字格式返回对象的值。如 xxxValue() 方法,它将 Number 对象转换为 xxx 数据类型的值并返回。

五、Character类
Character 类是字符数据类型 char 的包装类。Character 类的对象包含类型为 char 的单个字段,这样能把基本数据类型当对象来处理,

六、Boolean类

1、Boolean 类的构造方法
Boolean 类有以下两种构造形式:

Boolean(boolean boolValue);

Boolean(String boolString);

其中 boolValue 必须是 true 或 false(不区分大小写),boolString 包含字符串 true(不区分大小写),那么新的 Boolean 对象将包含 true;否则将包含 false。

3、Boolean 类的常用常量
在 Boolean 类中包含了很多的常量,其中较为常用的常量如下。

TRUE:对应基值 true 的 Boolean 对象。

FALSE:对应基值 false 的 Boolean 对象。

TYPE:表示基本类型 boolean 的 Class 对象

七、System类

System 类提供了一些类变量和类方法,允许直接通过 System 类来调用这些类变量和类方法。

1、System 类的成员变量
System 类有 3 个静态成员变量,分别是 PrintStream out、InputStream in 和 PrintStream err。

1)PrintStream out**

标准输出流。此流已打开并准备接收输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。

2)InputStream in

标准输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。

3)PrintStream err

标准的错误输出流。其语法与 System.out 类似,不需要提供参数就可输出错误信息。

2、System 类的成员方法
System 类中提供了一些系统级的操作方法,常用的方法有 arraycopy()、currentTimeMillis()、exit()、gc() 和 getProperty()。

1)arraycopy() 方法

该方法的作用是数组复制,即从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。

2)currentTimeMillis() 方法

该方法的作用是返回当前的计算机时间,时间的格式为当前计算机时间与 GMT 时间(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒所差的毫秒数。一般用它来测试程序的执行时间。

3)exit() 方法

该方法的作用是终止当前正在运行的 Java 虚拟机,

4)gc() 方法

该方法的作用是请求系统进行垃圾回收,完成内存中的垃圾清除。

异常处理
一、异常(Exception)处理及常见异常
1、异常简介

在 Java 中一个异常的产生,主要有如下三种原因:

1、Java 内部错误发生异常,Java 虚拟机产生的异常。

2、编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等。

3、通过 throw 语句手动生成的异常,一般用来告知该方法的调用者一些必要信息。

2、异常类型

Java 专门引入了异常类。在 Java 中所有异常类型都是内置类 java.lang.Throwable 类的子类,即 Throwable 位于异常类层次结构的顶层。Throwable 类下有两个异常分支 Exception 和 Error

下面有 Error 和 Exception 两个子类分别表示错误和异常。其中异常类 Exception 又分为运行时异常和非运行时异常,这两种异常有很大的区别,也称为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。 1、Exception 类用于用户程序可能出现的异常情况,它也是用来创建自定义异常类型类的类。 2、Error 定义了在通常环境下不希望被程序捕获的异常。一般指的是 JVM 错误,如堆栈溢出。

非运行时异常是指 RuntimeException 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、ClassNotFoundException 等以及用户自定义的 Exception 异常(一般情况下不自定义检查异常)。

表 1 和表 2 分别列出了 java.lang 中定义的运行时异常和非运行时异常的类型及作用。

表 1 Java中常见运行时异常

异常类型

说明

ArithmeticException

算术错误异常,如以零做除数

ArraylndexOutOfBoundException

数组索引越界

ArrayStoreException

向类型不兼容的数组元素赋值

ClassCastException

类型转换异常

IllegalArgumentException

使用非法实参调用方法

lIIegalStateException

环境或应用程序处于不正确的状态

lIIegalThreadStateException

被请求的操作与当前线程状态不兼容

IndexOutOfBoundsException

某种类型的索引越界

NullPointerException

尝试访问 null 对象成员,空指针异常

NegativeArraySizeException

再负数范围内创建的数组

NumberFormatException

数字转化格式异常,比如字符串到 float 型数字的转换无效

TypeNotPresentException

类型未找到

表 2 Java常见非运行时异常

异常类型

说明

ClassNotFoundException

没有找到类

IllegalAccessException

访问类被拒绝

InstantiationException

试图创建抽象类或接口的对象

InterruptedException

线程被另一个线程中断

NoSuchFieldException

请求的域不存在

NoSuchMethodException

请求的方法不存在

ReflectiveOperationException

与反射有关的异常的超类

二、Error和Exception的异同
Error(错误)和 Exception(异常)都是 java.lang.Throwable 类的子类,在 Java 代码中只有继承了 Throwable 类的实例才能被 throw 或者 catch。

Exception 又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源码里必须显示的进行捕获处理,这里是编译期检查的一部分。不检查异常就是所谓的运行时异常,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译器强制要求。

如下是常见的 Error 和 Exception:

1)运行时异常(RuntimeException): ​ NullPropagation:空指针异常; ​ ClassCastException:类型强制转换异常 ​ IllegalArgumentException:传递非法参数异常 ​ IndexOutOfBoundsException:下标越界异常 ​ NumberFormatException:数字格式异常

2)非运行时异常: ​ ClassNotFoundException:找不到指定 class 的异常 ​ IOException:IO 操作异常

3)错误(Error): ​ NoClassDefFoundError:找不到 class 定义异常 ​ StackOverflowError:深递归导致栈被耗尽而抛出的异常 ​ OutOfMemoryError:内存溢出异常

第九周笔记

三、异常处理机制
Java 的异常处理通过 5 个关键字来实现:try、catch、throw、throws 和 finally。try catch 语句用于捕获并处理异常,finally 语句用于在任何情况下(除特殊情况外)都必须执行的代码,throw 语句用于拋出异常,throws 语句用于声明可能会出现的异常。

Java 的异常处理机制提供了一种结构性和控制性的方式来处理程序执行期间发生的事件。异常处理的机制如下: ​ 1、在方法中用 try catch 语句捕获并处理异常,catch 语句可以有多个,用来匹配多个异常。 ​ 2、对于处理不了的异常或者要转型的异常,在方法的声明处通过 throws 语句拋出异常,即由上层的调用方法来处理。

四、try catch finally语句

Java的垃圾回收机制不会回收任何物理资源,垃圾回收机制只回收堆内存中对象所占用的内存。

使用 try-catch-finally 语句时需注意以下几点: 1、异常处理语法结构中只有 try 块是必需的,也就是说,如果没有 try 块,则不能有后面的 catch 块和 finally 块; 2、catch 块和 finally 块都是可选的,但 catch 块和 finally 块至少出现其中之一,也可以同时出现; 3、可以有多个 catch 块,捕获父类异常的 catch 块必须位于捕获子类异常的后面; 4、不能只有 try 块,既没有 catch 块,也没有 finally 块; 5、多个 catch 块必须位于 try 块之后,finally 块必须位于所有的 catch 块之后。 6、finally 与 try 语句块匹配的语法格式,此种情况会导致异常丢失,所以不常见。

五、声明和抛出异常
1、throws 声明异常
throws 具体格式如下:

returnType method_name(paramList) throws Exception 1,Exception2,…{…}

其中,returnType 表示返回值类型;method_name 表示方法名;paramList 表示参数列表;Exception 1,Exception2,… 表示异常类。

方法重写时声明抛出异常的限制

使用 throws 声明抛出异常时有一个限制,是方法重写中的一条规则:子类方法声明抛出的异常类型应该是父类方法声明抛出的异常类型的子类或相同,子类方法声明抛出的异常不允许比父类方法声明抛出的异常多。

throws 关键字和 throw 关键字在使用上的几点区别如下: 1、throws 用来声明一个方法可能抛出的所有异常信息,表示出现异常的一种可能性,但并不一定会发生这些异常;throw 则是指拋出的一个具体的异常类型,执行 throw 则一定抛出了某种异常对象。 通常在一个方法(类)的声明处通过 throws 声明方法(类)可能拋出的异常信息,而在方法(类)内部通过 throw 声明一个具体的异常信息。 2、throws 通常不用显示地捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法; throw 则需要用户自己捕获相关的异常,而后再对其进行相关包装,最后将包装后的异常信息抛出。

六、自定义异常

自定义异常类一般包含两个构造方法:一个是无参的默认构造方法,另一个构造方法以字符串的形式接收一个定制的异常消息,并将该消息传递给超类的构造方法。

Lambda 表达式
一、Java 中 Lambda 表达式
1、Lambda 简介
Lambda 表达式(Lambda expression)是一个匿名函数,基于数学中的λ演算得名,也可称为闭包(Closure)。现在很多语言都支持 Lambda 表达式,如 C++、C#、Java、 Python 和 JavaScript 等。

Lambda 表达式是推动 Java 8 发布的重要新特性,它允许把函数作为一个方法的参数(函数作为参数传递进方法中),

2、Java Lambda 表达式的优缺点
优点:

代码简洁,开发迅速方便函数式编程非常容易进行并行计算

Java 引入 Lambda,改善了集合操作(引入 Stream API)

缺点:

代码可读性变差在非并行计算中,很多计算未必有传统的 for 性能要高不容易进行调试

3、函数式接口

Lambda 表达式实现的接口不是普通的接口,而是函数式接口。

集合、泛型
一、集合简介
为了保存数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组),Java 提供了集合类。集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。

接口名称

作 用

Iterator 接口

集合的输出接口,主要用于遍历输出(即迭代访问)Collection 集合中的元素,Iterator 对象被称之为迭代器。迭代器接口是集合接口的父接口,实现类实现 Collection 时就必须实现 Iterator 接口。

Collection 接口

是 List、Set 和 Queue 的父接口,是存放一组单值的最大接口。所谓的单值是指集合中的每个元素都是一个对象。一般很少直接使用此接口直接操作。

Queue 接口

Queue 是 Java 提供的队列实现,有点类似于 List。

Dueue 接口

是 Queue 的一个子接口,为双向队列。

List 接口

是最常用的接口。是有序集合,允许有相同的元素。使用 List 能够精确地控制每个元素插入的位置,用户能够使用索引(元素在 List 中的位置,类似于数组下标)来访问 List 中的元素,与数组类似。

Set 接口

不能包含重复的元素。

Map 接口

是存放一对值的最大接口,即接口中的每个元素都是一对,以 key➡value 的形式保存。

对于 Set、List、Queue 和 Map 这 4 种集合,Java 最常用的实现类分别是 HashSet、TreeSet、ArrayList、ArrayDueue、LinkedList 和 HashMap、TreeMap 等。下表介绍了集合中这些常用的实现类。

类名称

作用

HashSet

为优化査询速度而设计的 Set。它是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,实现比较简单

TreeSet

实现了 Set 接口,是一个有序的 Set,这样就能从 Set 里面提取一个有序序列

ArrayList

一个用数组实现的 List,能进行快速的随机访问,效率高而且实现了可变大小的数组

ArrayDueue

是一个基于数组实现的双端队列,按“先进先出”的方式操作集合元素

LinkedList

对顺序访问进行了优化,但随机访问的速度相对较慢。此外它还有 addFirst()、addLast()、getFirst()、getLast()、removeFirst() 和 removeLast() 等方法,能把它当成栈(Stack)或队列(Queue)来用

HsahMap

按哈希算法来存取键对象

TreeMap

可以对键对象进行排序

二、Collection接口
Collection 接口是 List、Set 和 Queue 接口的父接口,通常情况下不被直接使用。

方法名称

说明

boolean add(E e)

向集合中添加一个元素,如果集合对象被添加操作改变了,则返回 true。E 是元素的数据类型

boolean addAll(Collection c)

向集合中添加集合 c 中的所有元素,如果集合对象被添加操作改变了,则返回 true。

void clear()

清除集合中的所有元素,将集合长度变为 0。

boolean contains(Object o)

判断集合中是否存在指定元素

boolean containsAll(Collection c)

判断集合中是否包含集合 c 中的所有元素

boolean isEmpty()

判断集合是否为空

Iterator<E>iterator()

返回一个 Iterator 对象,用于遍历集合中的元素

boolean remove(Object o)

从集合中删除一个指定元素,当集合中包含了一个或多个元素 o 时,该方法只删除第一个符合条件的元素,该方法将返回 true。

boolean removeAll(Collection c)

从集合中删除所有在集合 c 中出现的元素(相当于把调用该方法的集合减去集合 c)。如果该操作改变了调用该方法的集合,则该方法返回 true。

boolean retainAll(Collection c)

从集合中删除集合 c 里不包含的元素(相当于把调用该方法的集合变成该集合和集合 c 的交集),如果该操作改变了调用该方法的集合,则该方法返回 true。

int size()

返回集合中元素的个数

Object[] toArray()

把集合转换为一个数组,所有的集合元素变成对应的数组元素。

三、List集合
List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0,第二个为 1,依此类推。

List 实现了 Collection 接口,它主要有两个常用的实现类:ArrayList 类和 LinkedList 类。

1、ArrayList 类
ArrayList 类实现了可变数组的大小,存储在内的数据称为元素。

ArrayList 类的常用构造方法有如下两种重载形式:

            1、ArrayList():构造一个初始容量为 10 的空列表。

            2、ArrayList(Collection<?extends E>c):构造一个包含指定 Collection 元素的列表,这些元素是按照该 Collection 的迭代器返        回它们的顺序排列的。

2、LinkedList类
LinkedList 类采用链表结构保存对象,这种结构的优点是便于向集合中插入或者删除元素。

3、ArrayList 类和 LinkedList 类的区别
ArrayList 与 LinkedList 都是 List 接口的实现类,因此都实现了 List 的所有未实现的方法,只是实现的方式有所不同。

ArrayList 是基于动态数组数据结构的实现,访问元素速度优于 LinkedList。LinkedList 是基于链表数据结构的实现,占用的内存空间比较大,但在批量插入或删除数据时优于 ArrayList。

对于快速访问对象的需求,使用 ArrayList 实现执行效率上会比较好。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高。

四、Set集合

Set 实现了 Collection 接口,它主要有两个常用的实现类:HashSet 类和 TreeSet类。

1、HashSet 类
HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时就是使用这个实现类。HashSet 是按照 Hash 算法来存储集合中的元素。因此具有很好的存取和查找性能。

HashSet 具有以下特点: ​ 1、不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。 ​ 2、HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。 ​ 3、集合元素值可以是 null。

五、Map集合
Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键(key)对象和一个值(value)对象。用于保存具有映射关系的数据。

Map 集合里保存着两组值,一组值用于保存 Map 里的 key,另外一组值用于保存 Map 里的 value,key 和 value 都可以是任何引用类型的数据。Map 的 key 不允许重复,value 可以重复,即同一个 Map 对象的任何两个 key 通过 equals 方法比较总是返回 false。

Map 中的 key 和 value 之间存在单向一对一关系,即通过指定的 key,总能找到唯一的、确定的 value。从 Map 中取出数据时,只要给出指定的 key,就可以取出对应的 value。

Map 接口主要有两个实现类:HashMap 类和 TreeMap 类。其中,HashMap 类按哈希算法来存取键对象,而 TreeMap 类可以对键对象进行排序。

Map 集合最典型的用法就是成对地添加、删除 key-value 对,接下来即可判断该

* Map 中是否包含指定 key,也可以通过 Map 提供的 keySet() 方法获取所有 key

* 组成的集合,进而遍历 Map 中所有的 key-value 对。

1、排序(正向和逆向)
Collections 提供了如下方法用于对 List 集合元素进行排序。

void reverse(List list):对指定 List 集合元素进行逆向排序。

void shuffle(List list):对 List 集合元素进行随机排序(shuffle 方法模拟了“洗牌”动作)。

void sort(List list):根据元素的自然顺序对指定 List 集合的元素按升序进行排序。

void sort(List list, Comparator c):根据指定 Comparator 产生的顺序对 List 集合元素进行排序。

void swap(List list, int i, int j):将指定 List 集合中的 i 处元素和 j 处元素进行交换。

void rotate(List list, int distance):当 distance 为正数时,将 list 集合的后 distance 个元素“整体”移到前面;当 distance 为负数时,将 list 集合的前 distance 个元素“整体”移到后面。该方法不会改变集合的长度。

2、查找、替换操作
Collections 还提供了如下常用的用于查找、替换集合元素的方法。

int binarySearch(List list, Object key):使用二分搜索法搜索指定的 List 集合,以获得指定对象在 List 集合中的索引。如果要使该方法可以正常工作,则必须保证 List 中的元素已经处于有序状态。

Object max(Collection coll):根据元素的自然顺序,返回给定集合中的最大元素。

Object max(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最大元素。

Object min(Collection coll):根据元素的自然顺序,返回给定集合中的最小元素。

Object min(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最小元素。

void fill(List list, Object obj):使用指定元素 obj 替换指定 List 集合中的所有元素。

int frequency(Collection c, Object o):返回指定集合中指定元素的出现次数。

int indexOfSubList(List source, List target):返回子 List 对象在父 List 对象中第一次出现的位置索引;如果父 List 中没有出现这样的子 List,则返回 -1。

int lastIndexOfSubList(List source, List target):返回子 List 对象在父 List 对象中最后一次出现的位置索引;如果父 List 中没有岀现这样的子 List,则返回 -1。

boolean replaceAll(List list, Object oldVal, Object newVal):使用一个新值 newVal 替换 List 对象的所有旧值 oldVal。

八、Lambda表达式遍历Collection集合

Java 8 为 Iterable 接口新增了一个 forEach(Consumer action) 默认方法,该方法所需参数的类型是一个函数式接口,而 Iterable 接口是 Collection 接口的父接口,因此 Collection 集合也可直接调用该方法。

当程序调用 Iterable 的 forEach(Consumer action) 遍历集合元素时,程序会依次将集合元素传给 Consumer 的 accept(T t) 方法(该接口中唯一的抽象方法)。正因为 Consumer 是函数式接口,因此可以使用 Lambda 表达式来遍历集合元素。

九、Iterator(迭代器)

Iterator(迭代器)是一个接口,它的作用就是遍历容器的所有元素,也是 Java 集合框架的成员,但它与 Collection 和 Map 系列的集合不一样,Collection 和 Map 系列集合主要用于盛装其他对象,而 Iterator 则主要用于遍历(即迭代访问)Collection 集合中的元素。

Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的统一编程接口。Iterator 接口里定义了如下 4 个方法。 ​ 1、boolean hasNext():如果被迭代的集合元素还没有被遍历完,则返回 true。 ​ 2、Object next():返回集合里的下一个元素。 ​ 3、void remove():删除集合里上一次 next 方法返回的元素。 ​ 4、void forEachRemaining(Consumer action):这是 Java 8 为 Iterator 新增的默认方法,该方法可使用 Lambda 表达式来遍 历集合元素。

Java 8 为 Iterator 引入了一个 forEachRemaining(Consumer action) 默认方法,

* 该方法所需的 Consumer 参数同样也是函数式接口。当程序调用 Iterator 的

* forEachRemaining(Consumer action) 遍历集合元素时,程序会依次将集合元素传给

* Consumer 的 accept(T t) 方法(该接口中唯一的抽象方法)。

Collections 类是 Java 提供的一个操作 Set、List 和 Map 等集合的工具类。

 Collections 类提供了许多操作集合的静态方法,借助这些静态方法可以实现集合元素的排序、 查找替换和复制等操作。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值