记录生活中的点点滴滴

0%

一、Stream API 的操作步骤:

  1. 创建 Stream

  2. 中间操作

  3. 终止操作(终端操作)

中间操作:

筛选与切片

​ filter——接收 Lambda , 从流中排除某些元素。
​ limit——截断流,使其元素不超过给定数量。
​ skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则 返回一个空流。与 limit(n) 互补
​ distinct——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素

映射
map——接收 Lambda , 将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每 个元素上,并将其映射成一个新的元素。
flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

sorted()——自然排序
sorted(Comparator com)——定制排序

终止操作:
allMatch——检查是否匹配所有元素
anyMatch——检查是否至少匹配一个元素
noneMatch——检查是否没有匹配的元素
findFirst——返回第一个元素
findAny——返回当前流中的任意元素
count——返回流中元素的总个数
max——返回流中最大值
min——返回流中最小值

归约
reduce(T identity, BinaryOperator) / reduce(BinaryOperator) ——可以将流中元素反复结合起来,得到一个值。

收集

collect——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法

注意:流进行了终止操作后,不能再次使用

二、Optional 容器类:用于尽量避免空指针异常

  • Optional.of(T t) : 创建一个 Optional 实例
  • Optional.empty() : 创建一个空的 Optional 实例
  • Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例
  • isPresent() : 判断是否包含值
  • orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
  • orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
  • map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
  • flatMap(Function mapper):与 map 类似,要求返回值必须是Optional

三、时间

  1. LocalDate、LocalTime、LocalDateTime

  2. Instant : 时间戳。 (使用 Unix 元年 1970年1月1日 00:00:00 所经历的毫秒值)

  3. Duration : 用于计算两个“时间”间隔
    Period : 用于计算两个“日期”间隔

  4. TemporalAdjuster : 时间校正器

  5. DateTimeFormatter : 解析和格式化日期或时间

  6. ZonedDate、ZonedTime、ZonedDateTime : 带时区的时间或日期

.java文件(源文件) –> 编译成.class字节码文件(检查语法) –> 类装载器 –> Java虚拟机(JVM)(解释成二进制数据) –> 操作系统 –> 硬件平台

jdk –> bin 可执行文件(命令)

   jre 运行时环境 – lib – rt.jar(sun提供好的库)

src是源码

||
一个.java源文件中可以定义多个class,并且一个class会生成一个.class文件
public的class的名字必须要与文件名保持一致,如果要定义public的class,那
抹这个public的class也只能有一个
关于java语言中的字面值
1.什么是字面值?

 一眼看上去就知道是多少的数据,就是字面值
2.字面值本质:

 字面值是有数据类型的:

  整型 100

  浮点型 3.14

  布尔型 true/false

  字符型 ‘中’

  字符串型 “ABC”

 在内存中占用空间:
字面值就是内存中的一块空间。这块空间有类型,有值。

 只有字面值内存无法得到重复利用

 java语言中所有的字符都采用“单引号”括起来

 java语言中所有的字符串都采用“双引号”括起来

关于java语言中的变量
1.java中如何定义变量,语法:

 数据类型 变量名;
2.如何给变量赋值,语法:

 变量名 = 值;
3.变量的本质是什么?

 变量就是内存中的一块空间,这块空间有”类型”,”名字”,”值”
java中的变量必须先声明,再赋值,才能使用

关于变量的作用域:有效范围,作用范围。出了大括号就不认识了

变量根据出现的位置可以分为两种:

 1.局部变量,在方法中声明的叫做局部变量,包括形式参数列表

 2.成员变量,在类体中,方法之外声明的变量统称成员变量

关于char类型

 char是字符类型,java中采用unicode编码,底层占用两个字节

char类型涉及到字符编码方式:

 1.字符编码方式是现实世界中的文字和计算机的表示方式的转换规则。

   ascll

   iso-8859-1

   gb2312<gbk<gb18030

   unicode utf-8 utf-16 utf-32

 2.字符如果采用的编码和解码不一致的话,会出现乱码。

关于转义字符

 \斜线在java语言中有转义功能

 \n 换行符 \t 水平制表符 ' 单引号 \ “ 双引号 \ 普通斜线

 \u xxxx 后跟4位16进制unicode编码,表示一个字符

默认值:

 byte short int long 0

 float double 0.0

 boolean false

 char ‘\u0000’(表现形式上是一个空格)

关于java语言中的数据类型

 byte 1byte(8bit) -128-127

 short 2byte

 int 4byte

 long 8byte
整数有3中表现形式:

 十进制

 八进制  以0开始

 十六进制 以0x开始

在java中基本类型可以相互转换,boolean类型比较特殊不可以转换成其他类型

转换分为自动类型提升和强制类型转换:

 自动类型提升:容量小的类型会默认转换为容量大的类型

 byte -> short -> int -> long -> float -> double

 char

byte,short,char之间计算不会相互转换,首先先转成int

 强制类型转换:

  将容量大的类型转换成容量小的类型,需要进行强制转换

  注意:只要不超出范围可以将整型值直接赋值给byte,short,char

在多种类型混合运算过程中,首先将所有数据转换成容量大的那种,再运算

关于java中的布尔类型

 1.boolean类型的数据只有两个值:true/false,没有1和0

 2.boolean类型的数据主要用在逻辑运算和条件控制语句中
java程序分为编译期和运行期

关系运算符


>= 大等于
< 小于
<= 小等于
== 判断是否相等(基本数据类型)
!= 不等于
关系运算符的运算结果一定是boolean类型

布尔运算符(逻辑运算符)

 & 逻辑与

 | 逻辑或

 ! 逻辑非

 ^ 逻辑异或

 && 短路与

 || 短路或
短路:后边那个表达式不执行

 什么时候发生短路与? 第一个算子结果是false的时候

 什么时候发生短路或?第一个算子结果是true的时候
布尔运算符两边的(算子)必须是布尔类型,整个表达式的运算结果也是一个布尔类型

关于赋值运算符

 基本的赋值运算符

 =

 扩展的赋值运算符

 += 追加

 -=

 *=

 /=

 %=
基本运算符和扩展运算符的区别? 

 扩展运算符不会改变变量本身的数据类型

关于字符串连接运算符

 +运算符可以:

  1.做加法运算(+两边只要都是数字类型,一定是加法运算)

  2.字符串连接(+两边任意一端只要是字符串类型,则一定是字符串连接)

条件运算符(三目运算符)

 ?:

 语法:

  boolean表达式?表达式1:表达式2

  boolean表示式的结果是true,则整个表达式的结果就是表达式1的结果,相反则是表达式2的结果

关于条件控制语句:流程控制语句if…else
1.语法
第一种结构:
if(boolean表达式){
java语句;
}
第二种结构:
if(boolean表达式){
java语句;
}else{
java语句;
}
第三种结构:
if(boolean表达式){
java语句;
}else if(boolean表达式){
java语句;
}else if(boolean表达式){
java语句;
}
第四种结构:
if(boolean表达式){
java语句;
}else if(boolean表达式){
java语句;
}else if(boolean表达式){
java语句;
}else{
}
注意:在if语句中只要有一个分支执行,则整个if语句结束

  上面的结构2.4可以保证一定会有一个分支语句执行,因为他们都有else语句。
!! else 有隐藏条件

关于switch语句:
1.语法:
switch(int类型){
case int类型:
java语句;
java语句;
break;

​ case int类型:
java语句;
​ java语句;
​ break;

​ case int类型:
​ java语句;
​ java语句;
​ break;

​ default:
​ java语句;
​ }

注意:break;语句可以没有,default也可以没有
break语句如果没有,则发生case穿透现象
switch后面的括号可以填写byte/short/char类型,因为可以自动转换
jdk7.0可以是String类型
case可以合并

for 循环:
语法:
for(表达式1;表达式2;表达式3){
java语句
}
表达式1是初始化表达式,最先执行,只执行一次
表达式2必须是boolean类型的表达式

for循环开始执行,先执行表达式1,并只执行一次,进而判断表达式2的结果,如果是true
则执行java语句,再执行表达式3,然后再判断表达式2的结果,知道表达式2的结果是false
则for循环结束。

关于while循环
语法
while(boolean表达式){
java语句;
}
该循环的执行次数:0-N

关于do…while…
语法:
do{
java语句;
}while(boolean表达式);

该循环的执行次数:1-N

break语句:

  • 可以用在switch语句中,结束分支语句

  • break;语句可以出现在循环当中,默认情况下结束离它最近的一个循环
    continue语句:可以用来结束当前一次循环,直接进入下一次循环继续执行

    通过break可以指定结束某个循环(标签)

定义方法的语法:

 [方法的修饰列表] 方法的返回值类型 方法名(方法的形参列表){

  java语句;

 }

1.[方法的修饰列表]是可选项 。暂时携程public static
2.方法的返回值类型,可以是java语言中的任何一种数据类型(基本数据类型和引用数据类型)
3.如果该方法执行结束之后,并没有任何返回值,那抹定义方法的时候,返回值类型写:void
4.方法名只要是合法的标识符即可
5.方法的形参参数列表,可以有参数,也可以没有参数,如果有多个参数的话使用”逗号”分开
6.如果一个方法的返回值的类型不是void,那抹在方法体中必须使用return语句来返回数据

方法的形式参数列表中起决定性作用的是参数的类型
参数的名字(局部变量的名字)是随意的只要是合法的标识符即可

方法覆盖:overrride ,overwriter

 1.什么时候方法需要重写?

  如果父类中的方法已经无法满足当前子类的业务要求,需要将父类的方法进行重写

 2.子类如果重写父类中的方法之后,子类对象一定调用的是重写之后的方法。

 3.发生方法覆盖的条件:

  第一:发生在具有继承关系的两个类之间

  第二:必须具有相同的方法名,相同的返回值类型,相同的参数列表

  第三:重写的方法不能比被重写的方法拥有更低的访问权限

  第四:重写的方法不能比被重写的方法抛出更宽泛的异常

  第五:私有的方法不能被覆盖

  第六:构造方法无法被覆盖,因为构造方法无法被继承

  第七:静态的方法不存在覆盖

    (静态方法执行和对象无关)

  第八:覆盖指的是成员方法,和成员变量无关

 4.继承的基本作用:代码复用。继承最重要的作用:方法重写

 关于java语言中向上转型和向下转型

  1.向上转型(upcasting): 子 –> 父

  2.向下转型(downcasting):父 –> 子

注意:无论是向上转型还是向下转型,两个类之间必须有继承关系

多态作用:使用多态可以使代码之间的耦合度降低

     项目扩展能力增强
耦合度:代码和代码之间的关联程度

super

 1.super不是引用类型,super中存储的不是内存地址,super指向的不是父类对象

 2.super代表的是当前子类对象中的父类型特征

 3.什么时候使用super?

  子类和父类中都有某个数据,例如,子类和父类中都有name这个属性

  如果要在访问子类中父类中的属性,需要使用super

 4.super可以用在什么地方?

  成员方法

  构造方法

super关键字用在构造方法中:
语法:super(实参);
作用:通过子类的构造方法去调用父类的构造方法

语法规则:一个构造方法第一行如果没有this(…),也没有显示的去调用super(…);

     系统会默认调用super();
注意:super(…)的调用只能方在构造方法的第一行
super(…)和this(…)不能共存

通过子类的构造方法去调用父类的构造方法:作用是:给当前子类对象中的父类型特征赋值。

如何定义抽象类?

  • class关键字前abstract

  • 抽象类无法实例化

  • 虽然抽象类没有办法实例化,但是抽象类也有构造方法,该构造方法是给子类创建对象的用的

  • 抽象类中可以定义抽象方法:

  • 抽象方法的语法:在方法的修饰列表中添加abstract关键字,并且抽象方法应该以“;”结束,不能带有“{}”

  • 例如:public abstract void m();

  • 5.抽象类中不一定有抽象方法,但抽像方法所在的类必须是抽象类

  • 一个非抽象的类继承抽象类,必须将抽象类中的抽象方法覆盖,实现,重写。

    抽像类不能被final修饰
    抽象方法不能被final修饰

final修饰的类无法被继承
final修饰的方法无法被重写
final修饰的局部变量一旦赋值不可再改变
final修饰的成员变量需要手动赋值
final修饰的成员变量和static联用称为常量
深入final

  final修饰的引用类型,该引用不可重新指向其他的java对象

  但是final修饰的引用,该引用指向的对象的属性是可以修改的

关于方法的重载(overload)
优点:

 1.程序员只需要记忆很少的方法名,方便调用

 2.代码更加关注
什么时候发生方法的重载:

 1.发生在同一个类中

 2.方法名不同

 3.参数列表不同(类型,个数,顺序)

方法的重载和方法的返回值以及形参名无关

方法的执行原理:

 方法在调用的时候,才会给该方法在内存中分配空间

 如果这个方法只是定义没有调用,则不会在内存中分配空间

方法调用的时候在“栈”中分配空间,(JVM)内存中有一块内存是栈结构
方法调用其实就是“压栈”
方法结束其实就是“弹栈”

关于方法的递归调用

 1.方法的递归调用就是方法自身调用自身

类:一类具有相同特征的事物构成的集合

 把现实世界中的抽象化
实例:类的具体化

OOA 面向对象的分析
OOD 面向对象的设计
OOP 面向对象的编程

JVM中所有new出来的数据统一被储存在堆区中,程序员是无法对堆区数据直接操作,
只能通过内存地址间接访问

访问成员变量或者成员方法必须使用“引用.”(成员变量属于对象级的)

面向对象的封装性指的是:

 1.属性私有化

 2.对外部提供公开的setter,getter

  set和get方法的方法名应该遵循规范

关于java类的构造函数

 1.构造方法语法

 [修饰符列表] 构造方法名[形式参数表]{

  方法体

 }

 2.构造方法的方法名必须要类名一致

 3.构造方法的作用是什莫?

  第一:创建对象

  第二:初始化对象的属性

 4.构造方法应该如何调用?

  new 构造方法名(实参); 在堆中开辟空间储存对象

 5.如果一个类没有提供任何构造方法,系统会默认提供无参构造方法

  如果一个类已经手动提供了构造方法,那抹系统不再提供任何构造方法

 6.成员变量到底什么时候赋值?

  只有在调用构造方法的时候,才会给成员变量赋值

GC垃圾回收机制主要针对堆中的数据,当没有更多的引用指向时,则会被垃圾回收机制
如果使用空的引用去访问,则会出现空指针异常

参数传递的问题:

 1.传递的数据是基本数据类型 (值)

 2.传递的数据是引用数据类型 (地址)

this关键字:

 1.this是什么?

  this是一个引用类型

 在堆中java的每个对象中都有一个this,保存地址指向当前对象

 2.this能用在哪些地方?

  构造方法,实例方法

this可以用来区分成员变量和局部变量

 this不能出现在静态方法中:

  静态方法的执行根本不需要java对象的存在,直接使用 类名.方式的访问

  而this代表的是当前对象,所以静态方法中根本没有this

static关键字:

 1.static修饰的变量叫做”静态变量”

 2.static修饰的方法叫做”静态方法”

 3.static还可以定义静态语句块

 static定义的静态语句块在类加载阶段执行,并且只执行一次,并且是自上而下的顺序执行

 关于实例语句块:

 每一次调用构造方法之前会执行一次

 实例语句块执行顺序也是自上而下

 static修饰的方法叫做静态方法

 静态方法正规方式访问:”类名.”方式调用

 一般情况下工具类中的大部分方法都是静态方法

 静态方法不用创建对象也能直接访问该方法

 静态方法中不能直接访问非静态数据 

 静态方法中不能使用this

  !!静态方法也能使用“引用.”访问,在编译阶段检查出类型,运行的时候仍然使用”类.调用”

 static修饰的变量叫做“静态变量”

 方法区

 什么时候变量声明为静态变量?

 如果这个属性所有的对象都有,并且这个属性的值是相同的,则该属性声明成静态的属性

 静态变量储存在方法区,所有的java对象共享这一份

 所以静态变量是类级别的,使用“类名.”的方式访问

单例设计模式:

 1.构造方法私有化

 2.对外提供一个公开的静态的获取当前类型对象的方法

 3.提供一个当前类型的静态变量

单例设计模式分为两种:

 懒汉式

 饿汉式

继承:

 引入类继承基本的作用:代码复用

 语法:

  [修饰符列表] class 子类名 extends 父类名 {

   类体
 }
java语言单继承
java语言中子类继承父类,会将父类中所有的数据全部继承,包括私有的也能全部继承过来
但是在子类中无法直接方法父类中的私有数据,但是可以间接的访问。
注意:构造方法无法被子类继承

1.异常是什么?

 第一,异常模拟的是现实世界中的不正常“事件”

 第二,java中采用“类”去模拟异常

 第三,类是可以创建对象的

  NullPointerExeption e = 0x1234;

  e是引用类型,e中保存的内存地址指向堆中的“对象”

  这个对象一定是NullPointerException类型

  这个对象就表示真实存在的异常事件

  NullPointerException是一类异常

​ “抢劫”就是一类异常
​ “张三被抢劫”就是一个异常事件

2.异常机制的作用?

 java语言为我们提供一种完善的异常处理机制,

 作用是:程序发生异常事件之后,为我们输出详细的信息

 程序员通过这个信息,可以对程序进行一些处理,使程序

 更加健壮。

本质:程序执行过程中发生了算术异常这个事件,JVM为我们创建了ArithmeticException类型的对象

   并且这个对象中包含了异常的详细信息,并且JVM将这个对象中的信息输出到控制台。

所有Exception的直接子类都是编译型异常(发生的概率比较高)

​ 所有编译时异常,要求程序员在编写程序阶段,必须对它进行处理,如果不处理的话

  编译不通过。处理异常有两种方式,捕捉和声明抛出。捕捉:try…catch…,声明抛出

  就是在方法声明的位置上使用throws关键字抛出异常。

所有RuntimeException的子类都是运行时异常,运行时异常程序员在编写阶段(发生的概率比较低)

不需要对它进行处理

处理异常有两种方式:

 1.声明抛出 throws

 2.捕捉 try ..catch..

数组:

  • 数组是一种引用类型
  • 数组是一种简单的数据结构,线性结构
  • 数组是一个容器,可以用来存储其他元素
  • 数组可以存储任意类型数据结构的元素
  • 数组分为:一维数组,二维数组,三维数组,多维数组
  • 数组中存储的元素类型是统一的
  • 数组长度不可变,数组一旦创建长度不可变的,固定的

数组拿首元素的内存地址作为数组对象的内存地址
数组中存储元素的类型是统一的,每一个元素在内存中所占的空间大小是相同的,
知道数组的首元素内存地址,要查找的元素只要知道下标就可以快速的计算出偏移量
通过首元素内存地址+偏移量,快速计算出要查找元素的内存地址,通过内存地址快速
定位该元素,所以数组查找元素的效率较高
随机的对数组进行增删元素,当增加元素的时候,为了保证数组中元素在空间存储上是有序的,
所以被添加元素位置后面的所有元素都要向后移动。删除元素也是,后面所有的元素要向前移动
所以数组的增删元素的效率很低

初始化一维数组

 1.静态初始化

 2.动态初始化

  动态初始化一维数组,会先在堆内存中分配这个数组,并且数组中每一个元素都采用默认值

关于main方法中的参数俩表String[] args

 1.String[] args是专门用来接收命令行参数的

 2.列如:java ArrayTest abc def aaa

  JVM在调用ArrayTest 的main方法之前先将”abc def aaa”这个字符串以空格的方式分割,然后存储在

 String数组中

关于数组的拷贝

 System.arraycopy

二维数组的特点:

 1.二维数组是一个特殊的一维数组

 2.特殊的一维数组,特殊在一维数组的每一个元素都是“一维数组”

二分法查找:

 1.建立在已经排序的基础上的

  数组中没有重复元素

java.lang.String

 1.字符串一旦创建不可再改变。“abc”字符串一旦创建,不可变成“abcd”

 2.提升字符串的访问效率,在程序中使用了“缓存”技术,所以在java中所有使用双引号括起来的字符串都会在”字符串常量池”中创建一份

  字符串常量池在方法区中

 3.在程序执行过程中,如果程序用到某个字符串,例如“abc”,那抹程序会在字符串常量池中搜索字符串,如果没有找到则在字符串常量池中新建一个“abc”字符串,如果找到就直接拿过来用 [字符串常量池是个缓冲区,为了提高字符串的访问效率]

使用String需要注意的问题:尽量不要做字符串频繁拼接的操作
因为字符串一旦创建不可改变,只要频繁拼接,就会在字符串常
量池中创建大量的字符串对象,给垃圾回收带来问题.

关于字符串常用方法

  • char charAt(int index)
  • boolean endsWith(String endStr)
  • boolean equalsIgnoreCase(String anotherString) 判断字符串是否相等,忽略大小写
  • getBytes
  • indexOf / indexOf(String str,int fromIndex)
  • lastIndexOf(String str) / lastIndexOf(Sting fromIndex) 反向搜索
  • length
  • String replaceAll(String s1,String s2)
  • split
  • boolean startsWith(String s)
  • String substring(int begin) / String substring(int beginIndex,int endIndex)
  • char[] toCharArray
  • toUpperCase
  • toLowerCase
  • trim
  • String valueOf(Object obj)

正则表达式

 1.正则表达式是一门独立的学科

 2.正则表达式是一种字符模型,专门做字符串格式匹配的

 3.正则表达式是通用的

java.lang.StringBuffer
java.lang.StringBuilder

 1.StringBuffer和StringBuilder是什么?

  是一个字符串缓冲区

 2.工作原理
  预先在内存中申请一块空间,以容乃字符序列

  如果预留的空间不够用,则进行自动扩容,以容纳更

  多字符序列。
3.StringBuffer,StringBuilder和String的最大区别?

  String是不可变字符序列,存储字符串常量池中

  StringBuffer底层是一个char数组,但是该char数组是可变的

  并且可以自动扩容
4.StringBuffer和StringBuilder的默认初始化容量是16
5.如何优化StringBuffer和StringBuilder

  最好在创建StringBuffer之前,预测StringBuffer的存储字符数量

  然后再创建StringBuffer的时候采用指定容量的方式创建StringBuffer

  为了减少底层数组的拷贝,提交效率
6.StringBuffer线程安全

  StringBuilder线程不安全

Java中八种数据类型对应的包装类型:
基本数据类型 包装类
byte java.lang.Byte
short java.lang.Short
int Java.lang.Integer
long java.lang.Long

​ float java.lang.Float
​ double java.lang.Double

​ boolean java.lang.Boolean
​ char java.lang.Charactor

Integer中的常用方法:
int –> Integer 基本数据类型–>引用数据类型

  Integer i1 = new Integer(10);
Integer – > int 引用数据类型 –> 基本数据类型

   int i2 = i1.intValue();
String –> int 字符串转数字

   int i3 = Integer.parseInt(“25”);

toBinaryString 十进制转成2进制
toHexString 十进制转成16进制
toOctalString 十进制转成8进制
int –> Integer
Integer i4 = Integer.valueOf(10);
String –> Integer
Integer i5 = Integer.valueOf(“10”);

Integet
int
String
三种类型互相转换
1.int–>Integer

 Integer i1 = Integer.valueOf(10);
2.Integer–>int

 int i2 = i1.intValue();
3.String–>Integr

 Integer i3 = Integer.valueOf(“10”);
4.Integer –> String

 String s1 = i3.toString();
5.string –> int

 int i4 = Integer.parseInt(“123”);
6.int –> String

 String s5 = 10 + “”;

JDK5.0新特性:

 以下的特性适合JDK1.5版本之后的。包括1.5

 JDK1.4,包括1.4在内之前的所有版本不能使用以下特性

 自动装箱(auto_boxing)和自动拆箱(auto_unboxing)

深入自动装箱和自动拆箱

 1.自动装箱和自动拆箱是程序编译阶段的一个概念

  和程序运行无关

 2.自动装箱和自动拆箱主要目的是为方便程序员编码

Integer重写了equals方法

如果数据是在-128 127之间,java中引入了一个“整型常量池”,在方法区中
该整型常量池只容乃-127
128的数据

获取自1970/1/1 00/00/00/000到当前的毫秒数(时间戳)
System.currentTimeMillis();
获取系统当前时间对应的毫秒数
Date类
格式化日期
java.util.Date –> String

 sdf.format()
解析日期
String –> java.util.Date

 sdf.parse()
解析格式应该和字符串相同

日期格式
y 年
M 月
d 日
H 小时
m 分
s 秒
S 毫秒

Date t1 = new Date(1000);

 1000是自1970-1-1 00:00:00 000的毫秒数

java.math.BigDecimal

 该类型精确度极高,适合做财务软件

 财务软件double类型精确度太低

生成随机数

 创建随机数生成器

 Random random = new Random();

接口也是一种引用类型,可以等同看做类

  • 如何定义接口,语法:

  [修饰符] interface 接口名{}

  • 接口中只能出现常量和抽象方法
  • 接口其实是一个特殊的抽象类,特殊在接口是完全抽象的
  • 接口中没有构造方法,接口无法被实例化
  • 接口与接口之间可以多继承
  • 一个类可以实现多个接口(这里的实现可以等同看成继承)
  • 一个非抽象的类实现接口,需要将接口中所有的方法“实现/重写/覆盖”

接口中的常量public static final
接口中的抽象方法public abstract
implements是实现的意思,是一个关键字
implements和extends意义相同

接口作用:

 1.可以使项目分层,所有层都面向接口开发,开发效率提高了

 2.接口使代码和代码之间的耦合度降低,就像内存条和主板的关系,变得“可插拔”,可以随意切换

  接口和抽象类都能完成某个功能,优先选择接口

  因为接口可以多实现,多继承

  并且一个类除了实现接口之外,还可以去继承其他类,保留了类的继承

Object

 toString 以字符串的形式返回java对象

 类名@java对象在堆中的内存地址(哈希算法转成16进制)

equals

 finalize方法什么时候调用?

  1.finalize方法每个java对象都有

  2.finalize方法不需要程序员去调用,由系统调用

  3.java对象如果没有更多的引用指向它,则该java对象成为垃圾数据
等待垃圾回收器的回收,垃圾回收器在回收这个java对象之前会自动
调用该对象的finalize方法

 finalize方法时该对象马上就要回收了,列如:需要释放资源,则可以在该方法中释放

 程序员只能“建议”垃圾回收器回收垃圾

 hashCode返回该对象的哈希码值

 java对象的内存地址经过哈希算法得出的int类型的数值

 clone 数据的副本

软件包机制:

 1.为了解决类的命名冲突问题,在类前加命名空间(包机制)

 2.在java中使用package语句定义包(单包,复包)

 3.package语句只能出现在.java源文件的第一行

 4.package定义的格式,通常采用公司域名倒叙方式:

 例如:com.bjpowernode.oa.system;

 以上包含义:bjpowernode公司开发oa项目,system是oa项目中的一个模块

 5.完整的类名是带有包名的

 6.带有package语句的java源文件必须这样编译

 javac -d 生成路径 java源文件路径
 7.运行:

  java com.bjpowernode.oa.system.A

目录也是类,类的姓

import语句可以引入其他类
import语句只能出现在package语句之下,class定义的语句之上
java.lang 软件包下所有类不需要手动导入.系统自动导入

关于访问权限修饰符:修饰类,修饰方法,修饰变量

 private 只能在本类中访问

 public 可以在任意位置访问

 protected 本类,同一个包下,不同包下不行,但是子类中可以

 缺省 本类,同一个包下,不同包下不行

关于静态内部类

 1.静态内部类可以等同看做静态变量

  内部类的重要作用,可以访问外部类中私有的数据

 2.静态内部类可以直接访问外部类的静态数据,无法直接访问成员(静态上下文)

关于成员内部类

 1.成员内部类可以等同看做成员变量

 2.成员内部类不能有静态声明

 3.成员内部类可以访问外部类所有的数据

 局部内部类等同于局部变量

 局部内部类不能用访问控制权限修饰符修饰

 重点:局部内部类在访问局部变量的时候,局部变量必须使用final修饰

匿名内部类:指的是类没有名字

 匿名内部类优点:少定义一个类

 缺点:无法重复使用

泛化 实现 关联

聚合关系:整体不依赖部分,部分也不会依赖整体
整体不决定部分的生命周期

合成关系
合成关系与聚合关系是相似的,区别的地方在:整体和部分是紧密关联的

迭代器,集合获取到迭代器之后,可以使用迭代器去遍历集合
List

  存储元素的特点:有序可重复.有序,存进去是什么顺序,取出来时候还是这个顺序

  ArrayList底层使用的是数组存储元素的,所以ArrayList适合查询,不适合频繁的增删元素

  LinekList底层使用双向链表这种数据结构存储数据的,链表适合频繁的增删元素,不适合查询操作

  Vector集合底层和ArrayList相同,但是Vector是线程安全的,效率较低
Set

  存储元素的特点:无序不重复.存进去的时候是这样一个顺序,取出来的时候就不一定是这个顺序取出了

哈希表/散列表

Sorted 继承 Set

 存储元素的特点:无序不重复的。但是存储进去的元素可以按照元素的大小自动排序

Collection 常用方法

boolean add(Object element) 向集合中请添加元素
void clear() 清空集合
boolean isEmpty() 判断集合是否为空
int size() 获取集合中元素个数

Interator iterator() 获取集合所依赖的迭代器对象

 通过迭代器中方法完成集合的迭代(遍历)

 注意:这种方式是所有集合通用的遍历方式

迭代器面向接口编程
不需要关心底层集合的具体类型,所有集合依赖的迭代器都实现了java.util.Iterator接口
hasNext 判断是否还有更多的元素
next 将迭代器向下移动一位,并取出指向的元素

boolean contains(Object o) 集合中是否包含某个元素

 底层调用的是equals方法,如果equals返回true,就是包含
boolean remove(Object o) 删除集合中某个元素

存储在集合中的元素应该去重写equals方法

boolean remove(Object o)
remove和contains都需要集合中的元素重写equals方法,因为Object中的equals方法
比较内存地址,在现实的业务逻辑当中不能比较内存地址,该比较内容

深入remove方法

 1.迭代器的remove方法

 2.集合自身带的remove方法
推荐使用迭代器本身自带的方法删除元素

List集合存储元素特点:

 1.有序(List元素存储有下标):存进去是这样的顺序,取出来还是按照这个顺序取出

 2.可重复

深入List集合
ArrayList集合底层是数组,数组下标是有序的
所以在ArrayList集合有很多自己的特性
ArrayList集合底层默认初始化容量是10,扩大之后的容量是原容量的1.5倍
Vector集合底层默认初始化容量是10,扩大之后的容量是原容量的2倍

如何优化ArrayList和Vector

 尽量减少扩容操作,因为扩容需要数组拷贝,数组拷贝很耗内存

 一般推荐在创建集合的时候指定初始化容量

Set集合:HashSet

  • HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构

  • 哈希表又叫散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表
    每个单向链表都有独一无二的hash值,代表数组的下标.在某个单向链表的每一个节点
    上的hash值是相等的.hash值实际上是key调用hashCode方法,再通过“hash function”

    转换成的值

  • 如何向哈希表中添加元素:

       先调用被存储的key的hashCode方法,经过某个算法得出hash值,如果在这个哈希表中

        不存在这个hash值,则直接添加元素.如果该hash值已经存在,继续调用key之间的equals

    方法,如果equals返回false,则将该元素添加。如果equals方法返回true,则放弃添加该元素

  • HashSet其实是HashMap中的key部分。HashSet有什么特点,HashMap中的key应该具有相同的特点
    5.HashMap和HashSet初始化容量都是16,默认加载因子是0.75

关于往Set集合中存储的元素,该元素的hashCode方法和equals方法
HashMap中有一个put方法,put(key,value) key是无序的不可重复的
结论:存储在HashSet集合或者HashMap集合key部分的元素,需要同时重写hashCode1+equals

java.util.Set

 java.util.SortedSet 无序不重复,但是存进去的元素可以按照元素大小自动排序

  java.util.TreeSet

SortedSet存储元素为什么可以自动排序? (equals返回false,才会比较)

  因为被存储的元素实现了Comparable接口,

 SUN编写TreeSet集合在添加元素的时候,会

 调用compareTo方法完成比较

让SortedSet集合做到排序还有另一种方式java..util.Comparator
单独编写一个比较器

map集合中的常用方法
void clear() 清空map
boolean containsKey(Object key) 判断集合中是否包含这样的key
boolean containsValue(Object value) 判断集合中是否包含这样的value

Set<Map.Entry<K,V>> entrySet()

  返回此映射中包含的映射关系的 Set 视图。

V get(Object key) 通过key获取value
boolean isEmpty() 判断该集合是否为空
Set keySet() 获取map中所有key
V put(K key, V value) 向集合中添加键值对
V remove(Object key) 通过key删除元素
int size() 获取map中键值对的个数
Collection values 获取map集合中所有value
Set keySet() 获取所有的key
set entrySet() Map转换成Set

注意:存储在Map集合key部分的元素需要同时重写hashCode+equals

  HashMap和HashSet初始化容量都是16,默认加载因子是0.75

Map中如果key重复了,value采用的是“覆盖”

HashMap和HashSet初始化容量都是16,默认加载因子是0.75
Hashtable默认初始化容量是11,默认加载因子是0.75
java.util.Properties 也是由key和value组成,但是key和value都是字符串类型

SortedMap中的key特点:无需不可重复,但是存进去的元素可以按照大小自动排序
如果想自动排序:key部分的元素需要,1.实现comparable接口 2.单独写一个比较器

关于集合工具类 java.util.Collections
java.util.Collecition 集合接口

  Collections工具类可以对List集合中的元素排序,但是集合中的元素必须是“可比较的”,实现comparable接口

关于JDK5.0新特性的新特性:泛型(编译期概念)

 1.为什么引入泛型?

  1.可以统一集合中的数据类型

  2.可以减少强制类型转换

 2.泛型语法如何实现?

  泛型是一个编译阶段的语法

  在编译阶段统一集合中的类型

 3.泛型的有点和缺点?

  优点:同一类型,减少强制转换

  缺点:类型太统一了

自定义泛型

JDK5.0新特性:

 关于增强for循环

 语法:

  for(类型 变量:数组名/集合名){}

 集合要想使用增强for循环这种语法,集合需要使用泛型

 如果集合不使用泛型,该集合在使用增强for循环的时候应该使用Object类型定义

关于增强for的缺点:没有下标

File
boolean canExecute()
测试应用程序是否可以执行此抽象路径名表示的文件。
boolean canRead()
测试应用程序是否可以读取此抽象路径名表示的文件。
boolean canWrite()
测试应用程序是否可以修改此抽象路径名表示的文件。
int compareTo(File pathname)
按字母顺序比较两个抽象路径名。
boolean createNewFile()
当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
static File createTempFile(String prefix, String suffix)
在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
static File createTempFile(String prefix, String suffix, File directory)
在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
boolean delete()
删除此抽象路径名表示的文件或目录。
void deleteOnExit()
在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
boolean equals(Object obj)
测试此抽象路径名与给定对象是否相等。
boolean exists()
测试此抽象路径名表示的文件或目录是否存在。
File getAbsoluteFile()
返回此抽象路径名的绝对路径名形式。
String getAbsolutePath()
返回此抽象路径名的绝对路径名字符串。
File getCanonicalFile()
返回此抽象路径名的规范形式。
String getCanonicalPath()
返回此抽象路径名的规范路径名字符串。
long getFreeSpace()
返回此抽象路径名指定的分区中未分配的字节数。
String getName()
返回由此抽象路径名表示的文件或目录的名称。
String getParent()
返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
File getParentFile()
返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
String getPath()
将此抽象路径名转换为一个路径名字符串。
long getTotalSpace()
返回此抽象路径名指定的分区大小。
long getUsableSpace()
返回此抽象路径名指定的分区上可用于此虚拟机的字节数。
int hashCode()
计算此抽象路径名的哈希码。
boolean isAbsolute()
测试此抽象路径名是否为绝对路径名。
boolean isDirectory()
测试此抽象路径名表示的文件是否是一个目录。
boolean isFile()
测试此抽象路径名表示的文件是否是一个标准文件。
boolean isHidden()
测试此抽象路径名指定的文件是否是一个隐藏文件。
long lastModified()
返回此抽象路径名表示的文件最后一次被修改的时间。
long length()
返回由此抽象路径名表示的文件的长度。
String[] list()
返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
String[] list(FilenameFilter filter)
返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
File[] listFiles()
返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
File[] listFiles(FileFilter filter)
返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
File[] listFiles(FilenameFilter filter)
返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。
static File[] listRoots()
列出可用的文件系统根。
boolean mkdir()
创建此抽象路径名指定的目录。
boolean mkdirs()
创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
boolean renameTo(File dest)
重新命名此抽象路径名表示的文件。
boolean setExecutable(boolean executable)
设置此抽象路径名所有者执行权限的一个便捷方法。
boolean setExecutable(boolean executable, boolean ownerOnly)
设置此抽象路径名的所有者或所有用户的执行权限。
boolean setLastModified(long time)
设置此抽象路径名指定的文件或目录的最后一次修改时间。
boolean setReadable(boolean readable)
设置此抽象路径名所有者读权限的一个便捷方法。
boolean setReadable(boolean readable, boolean ownerOnly)
设置此抽象路径名的所有者或所有用户的读权限。
boolean setReadOnly()
标记此抽象路径名指定的文件或目录,从而只能对其进行读操作。
boolean setWritable(boolean writable)
设置此抽象路径名所有者写权限的一个便捷方法。
boolean setWritable(boolean writable, boolean ownerOnly)
设置此抽象路径名的所有者或所有用户的写权限。
String toString()
返回此抽象路径名的路径名字符串。
URI toURI()
构造一个表示此抽象路径名的 file: URI。
URL toURL()
已过时。 此方法不会自动转义 URL 中的非法字符。建议新的代码使用以下方式将抽象路径名转换为 URL:首先通过 toURI 方法将其转换为 URI,然后通过 URI.toURL 方法将 URI 装换为 URL。

多进程:提高CPU的使用率

 进程和进程之间的内存是独立的
多线程:线程是进程中的一个执行场景

 提高应用程序的使用率

 线程和线程共享“堆内存和方法区内存”,栈内存是独立的,一个线程一个栈

创建线程的2种方式
继承Thread
实现Runnable接口

线程优先级高的获取的cpu的时间片相对多一些

 优先级1-10

 最低1

 最高10

 默认5

setPriority()

getPriority();

MAX_PRIORITY 10
NORM_PRIORITY 5
MIN_PRIORITY 1

Thread.sleep(毫秒);

 2.sleep()方法是一个静态方法

 3.该方法的作用:阻塞当前线程,腾出cpu,让给其他线程

interrupt() 中断休眠,利用的是异常处理机制
join 线程合并

异步线程模型

 线程之间不必等待
同步线程模型

 线程之间排队

什么时候使用同步呢?为什么要引入线程同步呢?

 1.为了数据的安全.尽管应用程序的使用率低,但是为了保证书是安全的,必须加入线程同步机制

  线程同步机制是程序变成了(等同)单线程

 2.什么条件下使用线程同步?

  第一: 必须是多线程环境

  第二:多线程环境共享同一个数据

  第三:共享的数据涉及到修改操作

synchronized(){} 同步代码块

守护线程

 其他所有的用户线程结束,则守护线程退出

 守护线程一般都是无限执行的

 setDaemon

关于定时器的应用

  作用:每隔一段固定的时间执行一段代码

以下是sun提供的反射机制中的类
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.Method;
java.lang.Modifier;

​ private User{

​ }

反射机制的作用:

  1.反编译: .class -> .java

  2.通过反射机制访问java类的属性,方法,构造方法等.

第一种方式:

  将类加载到JVM中

  Class c1 = Class.forName(“User”); // c1引用保存地址指向堆中的对象,该对象代表的是User整个类
第二种方式:

  Class c2 = User.class;
第三种方式:

  User u = new User();

  Class sc3 = u.getClass();

newInstance相当于调用了无参构造器

关于java中的可变长参数

 如果有精确匹配的方法,则调用该方法,不会再去执行可变长形参的那个方法

 可变长形参等同看做数组

 可变长参数只能出现一次,并且只能出现在参数列表的最后一个位置上

IO+Properties

配置文件(属性文件)
java规范要求属性文件以“.properties”
配置文件的作用使程序更灵活
注意:一般程序中可变的东西不要写死,推荐写到配置文件中 运行同样的程序得到不同的结果

java.io.*;

FileInputStream
FileOutputStream
FileReader
FileWriter

BufferedReader 带有缓冲区的字符输入流
BufferedWriter 带有缓冲区的字符输出流

字节
BufferedInputStream
BufferedOutputStream

DateInputStream
DateOutputStream

ObjectInputStream
ObjectOutputStream

转换流(字节流转换成字符流)
InputStreamReader
OutputStreamWriter

PrintWriter
PrintStream 标椎输出流,默认输出到控制台

java语言中的流分为:4大家族(InputStream,OutputStream,Reader,Writer)

java.io.InputStream

 java.io.FileInputStream 文件字节输入流

 按照字节方式读取文件

int read()
int read(byte[] bytes)
available 流中估计的字节数
skip(int n) 跳过多少个字节

java.io.OutputStream

 java.io.FileOutputStream 文件字节输出流

 将计算机内存中的数据写入硬盘文件中

java.io.Reader;

 java.io.InputStremReader; 转换流

  java.io.FileReader; 文件字符输出流
skip

java.io.Writer;

java.io.ObjectOutputStream 序列化JAVA对象到硬盘(Serial)

  java.io.ObjectInputStream 将硬盘中的数据“反序列化”到JVM内存中(DeSerial)

Compile 编译(java–>class)
Decompile 反编译(class–>java)

标识接口的作用:起到标识的作用

  JVM如果看到该对象实现某个标识接口,会对它特殊待遇

java.io.OutputStreamWriter; 转换流

 java.io.FileWriter; 文件字符输出流

java.io.DateOutputStream 数据字节输出流

 可以将内存中的“int i = 10”写入到硬盘文件中

 写进去的不是字符串,写进去的是二进制数据,带类型

注意:要使用该流数据读取数据,必须提前知道该文件中数据存储格式,顺序

  读的顺序必须和写入的顺序一致

根据流出现的位置,流又可以分为:包装流或者处理流和节点流

java.io.ObjectOutputStream 序列化JAVA对象到硬盘(Serial)
java.io.ObjectInputStream 将硬盘中的数据“反序列化”到JVM内存中(DeSerial)

Compile 编译(java–>class)
Decompile 反编译(class–>java

标识接口的作用:起到标识的作用
JVM如果看到该对象实现某个标识接口,会对它特殊待遇

Serializable 可序列化
transient 不参加序列化