欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javacode基本概念语法--学习笔记

程序员文章站 2022-06-03 16:02:42
...

javacode学习笔记大纲

一、语法规范

import 是为了避免重复写包名/* 格式是 import java.util.*; /
import就是在java文件开头的地方,先说明会用到那些类别。
import java.lang.
;系统默认添加
package 可以是0 or 1个;
import 可以是0 or n个;
class 可以是1 or n个;但是public class只能是0 or 1个 而且public class(公开类)的类名必须和文件名相同

//单行注释
/* 多行注释 */
多行注释中不能再出现多行注释
比如:   /*   今天是Day02
		/*这样是错误的*/
	*/

/**  */文档注释   配合Javadoc工具使用的

注意: 代码里面写了package 运行的时候就必须带包名运行 比如代码里写了package p5;
运行时就必须是 java p5.类名

标识符
语法: 1.字母 数字 _ $ 数字不能开头
2.大小写敏感
3.长度没有限制
4.不能使用关键字或保留字

&&短路 (前面false后面就不运算)
&非短路 (不管前面是不是false,都要计算完后面的结果才判断)

二、键盘输入

java.util.Scanner sc = new java.util.Scanner(System.in);
键盘输入一个字符串:
String sc = next();
键盘输入一个字符:
char ch = sc.next().charAt(0);
键盘输入一个布尔类型:
boolean bn = sc.nextBoolean();

三、数据类型分类及类型转换

数据类型: 对象类型(除8种外)和8种基本数据类型(byte(1B)、short(2B)、int(4B)、long(8B)、float(4B)、double(8B)、booleen、字符类型char(2B))
char支持unicode编码方式 比如’A’ 65(10进制) ‘\u0041’(16进制) 字符类型是用’‘圈起来
转义字符 水平跳格’\t’ 换行’\n’ ‘’’ ‘"’

String 字符串 有字面值 用"“圈起来 比如"HelloWorld” 字符串加法运算就是把两个字符连接起来 比如 “A” + “B” + “10” = “AB10”

float(4B)和double(8B)可以采用科学计数法进行存储,近似值存储方式

int i ; short s;
自动类型转换 i = s;
强制类型转换 s = (short)i;
a + b
如果a和b有double ==> double;
如果a和b有float ==> float;
如果a和b有long ==> long;
如果没有上述情况 默认为 ==>int;

注意:a+=3不会发生自动类型转换!!;(底层原理:先提升,再强转为存储的变量类型)

a++ 先使用后加1 ++a 先加1后使用 比如说int a = 2; int c = a++; syso©;//结果是2 syso(a)//结果是3
结果是一样 但是过程不同 ++和+同时运算(如果没有括号) ++优先运算

不等于 != 模 %
&和&&的区别: &非短路 即使前面为假,还是会继续判断后面的 &&短路 前面如果为假 程序中止
移位运算符:左移<< 右移>>(有符号正负不变) >>>(无符号全正数) 同理<<<
三元运算符(问号运算符)?: (a>b)3:2 括号里必须放布尔表达式 如果为真 结果等于3 如果为假 结果为2

四、局部变量、switch-case、随机数

局部变量 特点:
(1)作用范围:从定义开始,一直到定义这个变量的代码块结束
(2)必须先赋值,后使用
(3)在重合范围内,不允许两个局部变量命名重合
switch-case switch(i) i只能是整型表达式(byte、short、int、char)
switch(i){
case(a):Syso; break;
case(b):Syso; break;

default:Syso;
}
break: 结束当前循环体
continue: 跳过当前循环,进入到下一个循环的判断,
default :即不满足任何case的情况

随机数生成(Random)
(1)位于java.util包中
导入包:import java.util.Random
(2)创建Random对象
Random rd = new Random();
(3)使用rd生成整数:
int n = rd.nextInt(n);//自动生成0~n-1的数据

五、函数

.函数的作用:
1.避免代码的冗余
2.提高程序的可维护性
3.提高程序的重用性
4.提高程序的灵活性

参数 (比如char echo,int count)

函数
定义位置:类中,任何函数的外部。一个类中,多个函数的顺序是无关紧要的

声明: public static 返回值类型 函数名 (参数表)
形式参数(形参):相当于函数内部的局部变量
实际参数(实参):调用函数时输入的参数
返回值:被调用函数的输出值,必须和返回值类型一致
作用:执行完之后回到调用函数的地方

JVM栈描述的JAVA函数执行的内存模型:每一个函数在执行的时候都会创建
一个栈帧(Strack Frame),用于存储局部变量表
、操作数栈、函数的出口等信息,
每一个函数的执行过程被记录.
注意: 函数一旦执行结束,返回到调用位置,则栈帧空间被收回

六、数组

1.基础概念

数组:一次性定义多个同类型的变量
数组空间在内存中必定是连续的
遍历数组:把数组中每个元素都访问一遍,不重复,不遗漏
数组元素有默认值:
数值类型数组的默认值 0(int) 0.0(double) 0.0F(float) \u0000(char)
boolean类型数组 默认值:false
对象类型数组(除八种基本数据类型外) 默认值:null

2.数组扩容及排序

数组扩容:数组长度是固定的,如果需要扩充,必须创建新数组。原数组的元素要复制到新数组
1.for(int i = 0;i < a.length;i++){
b[i] = a[i];
}
return b;
2. System.arraycopy(a,0,b,0,a.length);
return b;
3. return java.util.Arrays.copyOf(a,b.length);
这三种写法完全等价,随便哪一种都行

数组排序函数
java.util.Arrays.sort(需要排序的数组);

可变长参数(阅读底层源码或是API时,会用到)
1.可变长参数:函数接受的参数个数不再是固定的数量,可以随着需求改变
2.语法:public static 返回值类型 函数名(参数类型 …参数名){}
3.必须是形参列表中的最后一个,而且每个函数中只能有一个可变长参数

3.保留小数(扩充)

java.text.DecimalFormat;

// 0代表可以截断并且位数不够自动补0
// #代表可以自动截断但是位数不够不会补0
// 0和#的个数代表要保留的位数
DecimalFormat df = new DecimalFormat("#.00");
//a代表你要保留小数的数据
System.out.println(df.format(a));

七、面向对象

1.面向对象的思想:

对象:一切客观存在的事物
属性:有什么 比如说电脑的属性有 主机显示器鼠标网卡内存条…
方法:能做什么

对象的属性可能又是一个对象
对象的方法的使用者也是一个对象

客观世界是由对象组成的
1.小对象组成大对象
2.对象间彼此方法调用

解决客观问题:
1.把解决问题所需要的对象准备好
2.对象间如何配合 完成需求

计算机中的对象:
JVM中连续的存储对象(数据)
代表生活中的对象 生活中的对象在计算机中的抽象

2.特点

各司其职 对象应该保持简单性 越复杂的系统对象越简单
弱耦合性 对象和对象之间的联系应该尽量弱化
可重用性
可扩展性

3.类的概念

1.对象共性的抽象
2.客观对象在人脑中的主观反映 类是对象的认识
3.类是对象的模板

4. 如何编写一个类

属性:实例变量(没有定义在方法[也就是函数]内部的变量)
1.有默认值(和数组的默认值规则一样)
2.作用范围 至少是全类的内部
3.实例变量和实例变量可以命名冲突,冲突时局部变量优先,但是同一类型的变量不可以冲突

5.面试题+应用

成员变量 和 局部变量的区别。【重点:面试+应用】
局部变量 成员变量
位置: 定义方法内 定义在类以内,方法以外
默认值:没有默认值,先赋值后使用 具有默认值
作用范围: 从定义开始,到定义它的代码块结束 至少在本类中有效
命名冲突: 在重合的作用范围内,不允许命名冲突 可以和局部变量命名冲突,冲突时,在定义局部变量的方法中,优先使用局部变量

6.方法的概念

方法:
方法的声明: 对象能做什么
修饰符(比如public static 修饰符的位置可以颠倒) 返回值类型 方法名(参数表) 抛出的异常
方法的实现:

7.方法重载

方法的重载
允许定义多个同名的方法,参数表不同
1.参数个数不同
2.参数类型不同
3.参数类型的排列顺序不同
光是形参名不同的不算重载!

编译器按照 指定时先精确匹配,精确匹配不成功,再就近向上匹配,如果还不成功,则编译报错。
注意:方法重载时,避免调用发生匹配混淆现象!!!跟返回值类型无关 可以相同也可以不同

作用:一个对象的同类方法,由于参数表的不同造成的差异,对用户屏蔽!

8.构造方法

构造方法
1.没有返回值类型
2.方法名必须和类名相同
3.不允许手工调用,在对象构造过程中自动调用1次

如果一个类中没有定义任何构造方法,系统会默认添加一个公开无参构造方法

9.对象的创建过程(初步认识)

对象的创建过程:
1.分配空间 所有的实例变量被赋予默认值
2.初始化属性 所有的实例变量被赋予初始值
假如这个属性也是一个对象创建的语句,那么就会执行该对象的创建过程
3.调用构造方法 实例变量常常被第三次赋值

构造方法经常用来为属性赋值

变量按照类型划分
简单变量 :存值
对象变量(引用变量):存对象的地址

Java中参数的传递规则:
简单类型的参数 传值
对象类型的参数 传地址 传引用 实参和形参指向同一对象

10.this关键字

this
1.表示引用 指向当前(谁引用的就是指谁)对象
比如 Student s1 = new Student();
this.name 它指的是s1这个引用所指向的Student对象
当实例变量和局部变量命名冲突的时候,用this.表示实例变量,不加this.指的就是局部变量
2.调用本类其它构造方法this(参数);
this(参数);必须是构造方法中的第一个语句

八、三大特性

三大特性笔记链接: https://blog.csdn.net/zxwwantlearnjava/article/details/104877377

1.基础概念

面向对象的三大特性:封装,继承,多态
封装: 对象的便捷对对象的内部起到保护作用:
数据隐藏(四种访问修饰符)
public 公开 可以继承
(default)本类和同包可以访问 如果一个属性既不是public也不是private 那就默认是default 同包的子类可以继承

2.四个访问修饰符

private 私有 只能在本类内部访问 无法突破边界 不能继承
protected 受保护的 本类+同包+不同包的子类都可以访问 可以继承

private protected 只能修饰属性、方法、构造方法

default public 可以修饰属性、方法、构造方法、类

构造方法不能继承!

3.方法覆盖

子类用特殊的方法实现替换掉父类继承给它的一般的方法实现
(也就是说计算机在子类中找到了需要调用的方法,就不用去调用父类的方法了)

父类的静态方法(static)不能被子类覆盖

注意:子类替换父类的方法的时候,不能改变父类构造方法的返回值类型,方法名,参数表,访问修饰符相同或更宽

4.set、get方法

属性私有 提供公开的setXXX/getXXX用来访问属性
字符串名.length() 字符串长度
方法私有 只给自己调用
方法公开 声明公开(你只需要知道能做什么) 实现隐藏(不需要知道怎么实现的)
实现的改变对架构的影响最小

<<左移一位 乘2 >>右移一位 除2

5.继承

继承:
父类:子类的共性抽象出来的 比如动物是猫狗鸡鸭鱼鸟等的父类
class b{}
class a extends b{} a是b的子类

只有子类能够访问到的父类的属性和方法,才算是子类继承的

继承的作用:
1.使代码可重用,大大减少了写重复代码的次数
2.增强程序的可扩展性
3.增强程序的可维护性
4.使人们能够更加清晰的看清楚各个对象之间的联系

6.对象的创建过程(重新认识)

对象的构造过程
1.分配空间 本类+父类 一并分配
2.递归的构造父类对象()
3.初始化本类属性
4.调用本类构造方法

例如A<–B<–C
创建C对象:
1.分配空间
2.初始化A属性
3.调用A的构造方法
4.初始化B属性
5.调用B的构造方法
6.初始化C属性
7.调用C的构造方法

7.super关键字

super
1.引用:父类对象
访问父类被遮盖的属性或调用被覆盖的方法
2.用在构造方法中 指定调用父类的哪一个构造方法
必须是构造方法中的第一个语句

如果一个构造方法的第一句话,不是this(…),也不是super(…),系统默认添加super();
常常用来把构造参数传给父类,去设置父类的属性!

九、多态

1.概念

子类的对象可以看作是父类的对象
子类对象可以放入父类的引用
比如Animal a = new Dog();

2.特点

1.对象类型不变
2.只能对引用调用其引用类型中声明的方法
3.运行时,根据对象实际类型找子类覆盖之后的方法

子类引用赋值给父类引用 可以直接赋值
父类引用赋值给子类引用 必须强制类型转换 编译肯定会通过的
但是运行时可能会发生类型转换异常(因为对象类型不能变)

3.instanceof关键字

instanceof 可以判断c是不是A的子类 也可以判断a里面存的是不是子类C

在强制类型转换的时候 可以加个instanceof判断父类里面装的是不是子类对象
比如 if(a instanceof b){
子类类型 b = (子类类型)a;
} 就肯定不会类型转换异常 意思就是如果a 里面装的是子类b 那么就强制类型转换

十、三个修饰符

三个修饰符笔记链接: https://blog.csdn.net/zxwwantlearnjava/article/details/105078612

1.static 静态的

可以修饰:
1.属性
类变量 全类公有 允许直接用类名访问
类加载: 当JVM第一次使用一个类时,需要通过ClassPath找到这个类对应的.class文件,
把这个文件包含的类的信息读入JVM并保存起来.一般的说,一个类只会加载一次!

类加载的时机:
(1)创建类的对象
(2)第一次访问类的静态成员
(3)加载子类必须先加载父类
注意: 如果仅仅是声明类的引用,不会类加载!

2.方法
静态方法 允许直接用类名调用
在静态方法中,只能访问类的静态成员
静态方法可以被子类的静态方法覆盖,而且没有多态(第三条不适用:不会根据对象实际类型去找子类覆盖后的方法)
对引用调用其静态方法,仅相当于对引用的引用类型调用静态方法

静态修饰的成员 跟对象无关 任何与对象有关系的关键字 方法 属性都不能够直接用

	!!!!!!!!!!!!!!!!注意!!!!!!!!!!!!!!!!!!

非静态方法可以直接访问本类中的静态方法或非静态方法,但是静态方法只能直接访问本类中的静态方法

3.初始代码块
静态初始代码块中的代码,在类加载的时候执行一次
子类继承父类静态属性不会加载子类静态代码块
子类覆盖父类静态属性先加载父类静态代码块再加载子类静态代码块

2.final

可以修饰:
1.变量 一旦赋值 不能改变
对于final属性 系统不会提供默认值
如果是final实例变量 可以在初始化属性或是构造方法中赋值
如果是final类变量 可以在初始化属性或是静态初始代码块中赋值

2.方法
可以被子类继承,但是不能被子类覆盖

3.类
final修饰的类,不能被继承,没有子类,所有方法属性指向的都是本类的

intern() 返回一个对象在串池中的地址的方法
比如引用b b = b.intern();

String对象是由final修饰的
String 资源共享,不能被改变,如果要累加,就会每加一次创建一个新的对象,会造成空间浪费
StringBuffer可以被改变,在原有基础上累加,解决String累加造成空间浪费的问题
String str = “a”;
StringBuffer sb = new StringBuffer(str);
sb.append(“b”); //ab
sb.append(“c”); //abc
sb.append(“d”); //abcd
str = sb.toString();

使用StringBuffer的注意事项:
StringBuffer s1 = new StringBuffer ();
for(int i =0; i<50000; i++){
s1.append(“hello”);
}

StringBuffer s2 = new StringBuffer (250000);
for(int i =0; i<50000; i++){
s2.append(“hello”);
}
s2的速度要比s1的速度要快,原因如下:
StringBuffer内部实现的是char数组,默认初始长度为16,每当字符串长度大于数组长度时,
JVM会构造更大的新数组,然后将原先的数组内容复制到新数组,增加了开销,
这给我们的启示是在声明StringBuffer对象时,指定合适的capacity(也就是字符串长度*循环次数),不要使用默认值。

StringBuilder是非线程安全的,StringBuffer是线程安全的,总结如下:
如果需要操作少量字符串,为了方便,我们用String;
处理单线程大量字符串,用StringBuilder;
处理多线程大量字符串,用StringBuffer;

3.abstract抽象的

1.类 抽象类只能声明引用,不能创建对象 (也就是一个类的半成品,还没有写完,不能拿来创建对象的时候修饰的)

2.方法 抽象方法 只有声明,没有实现
!!!!!!!!!!!!!!!!!!!!!!
(用于让子类继承并覆盖父类的抽象方法并且利用多态实现父类抽象方法)

如果一个类中有抽象方法,这个类就必须是抽象类
子类继承抽象类,子类如果不希望也成为抽象类,就必须实现父类中声明的所有抽象方法

利用abstract,可以把方法声明放到父类中,方法实现留在子类中,更好的体现"共性放在父类"原则!

修饰符组合:
private static final 均不能和abstract联用

十一、接口

接口笔记链接: https://blog.csdn.net/zxwwantlearnjava/article/details/105163160

1.基础概念及语法

接口interface 是一个特殊的抽象类
1.所有的属性都是公开静态常量
2.所有的方法都是公开抽象方法
3.没有构造方法
属性和方法的修饰符可以不写,默认是public static final(属性)和 public abstract(方法)

2.implements关键字

子实现类的关键字implements,效果等同于extends,只不过是接口的专用关键字
一个类去实现接口,如果这个类不希望也成为抽象类,就必须实现接口中所有的方法,否则这个类必须是抽象类
子接口也是用extends关键词

3.特点

1.接口和接口之间可以多继承
2.一个类在继承另外一个类的同时,还可以实现多个接口
必须先写继承类,再写实现的接口 比如class Sub extends Super implements IA,ID{}
3.Person p = (Person)Animal 只要两边有一个是接口类型的,这句话就能编译通过

利用接口实现多继承,不会破坏类之间树状关系的简单性
利用接口解耦,实现java的弱耦合性
把标准的使用者和标准的实现者分离

4.接口回调

在定义接口之后,先有接口的使用者,后有接口的实现者,使用者通过接口调用实现者中的方法

5.JDK高版本的一些新特性(jdk8.0、jdk9.0)

JDK高版本对接口语法升级
(1)JDK8.0版本接口的升级内容
可以定义默认方法
a.语法:default 返回值类型 方法名(形参列表){}
b.注意:
接口中默认方法中的default不再是访问修饰符,代表此方法可以写方法的实现部分
接口中 默认方法 访问权限public

可以定义静态方法
a.语法:public static 返回值类型 方法名(形参){}
b.注意: 接口中静态方法默认访问权限也是public 可以省略
c.使用:接口名.静态方法名(实参);

(2)JDK9.0版本接口中升级:可以定义私有方法
语法: private 返回值类型 方法名(形参列表){}

6.接口的分类

接口的分类:
(1)常量接口: 接口中只有公开静态常量,没有定义方法 —>应用不广泛
(2)标记接口: 空接口,接口中没有定义任何的常量和方法,例如IO对象序列化
(3)普通接口: 定义至少一个抽象方法 —> 开发广泛应用
(4)函数式接口: 是一种特殊的普通接口,接口中只有一个抽象方法,对静态方法和默认方法没有要求

7.Comparable接口

Comparable<对象名> 用来比较对象大小的接口
需要实现int compareTo(对象名 引用);
this < 引用 return 负数;
this = 引用 return 0;
this > 引用 return 正数

十二、内部类

内部类笔记链接: https://blog.csdn.net/zxwwantlearnjava/article/details/105069205

1.成员内部类

内部类:
成员内部类 :跟成员变量的位置是一样的 方法外,外部类以内

	Outer o1 = new Outer(100);
	Outer o2 = new Outer(200);
	Outer.Inner in1 = o1.new Inner();
	in1.print(); //100
	Outer.Inner in2 = o2.new Inner();
	in2.print(); //200

class Outer{
	private int a;
	public class Inner{
		public void print(){
			System.out.println(a);	
		}
	}
}

(1)可以访问外部类的私有成员
(2)创建成员内部类对象,必须先创建外部类对象,再通过外部类对象.new 构造内部类对象
(3)成员内部类中不能有静态成员
(4)外部类类名.this指向外部类的当前对象

2.静态内部类

静态内部类 :成员内部类加了一个static
(1)只能访问外部类的静态成员
(2)创建静态内部类对象,不需要先创建外部类对象

3.局部内部类

局部内部类 :定义在方法以内的内部类
(1)使用范围等同于局部变量
(2)不仅可以访问外部类的私有成员,还可以访问外部类的局部常量(也就是final修饰的局部变量)

匿名内部类 :特殊的局部内部类

interface IA{
	void method();
}

class TestAnonymousInnerClass{
	public static void main(String []args){
		m(new IA(){
			public void method(){
				System.out.println("我是匿名内部类的实现方法");
			}
		});	
	}

	public static void m(IA ia){
		ia.method();
	}
}

使用条件
(1)是用来继承一个类或者实现一个接口
(2)只会创建该类的一个对象

作用:
1.匿名内部类可以很好的实现隐藏,一般的非内部类,是不允许有 private 与protected权限的,但内部类可以。

2.内部类拥有外部类的所有元素的访问权限。

3.可以实现多重继承。

4.可以避免修改接口而实现同一个类中两种同名方法的调用。

4.Lambda表达式

使用场景(接口中只有一个抽象方法)
接口名 引用 = (形参列表)->{//方法实现部分};
而且Lambda表达式中形参列表的数据类型可以省略,编译器自行推断
带有返回值的要在实现语句中返回对应的类型;而且可以省略return关键字和花括号

public class TestLambda{
	public static void main(String []args){
		IC ic = ()->{System.out.println("mc()...");}
		ID id = (a,b)->{System.out.println("mc()...");}
		IE ie = (a,b)->"mc()...";
	}
}

interface IC{
	void mc();
}

interface ID{
	void md(int a,String b);
}

interface IE{
	String md(double a,char c);
}

十三、常用类

1.Object类

Object类 Java所有类的父类 类继承关系树的树根
1.Object o; o中可以装任何对象
2.Object类中的方法 是所有对象都具有的方法

finalize(): 由垃圾收集器在回收垃圾对象时,最后调用
a.垃圾回收器如何认定垃圾对象 零引用算法(也就是没有任何引用指向该对象)
b.垃圾回收器如何释放垃圾对象 必须释放的时候(也就是内存用完了)
手动回收机制:使用System.gc() 通知JVM执行垃圾回收

getClass(): 返回对象的实际类型

toString(): 返回对象的String形式
打印一个对象的引用就是打印这个对象的toString方法的返回值

boolean equals(Object o):判断当前对象和o对象内容是否相同
注意: Object里面默认的equals是比较地址的,想要比较内容你得覆盖这个方法
sum默认把String对象类型的equals覆盖成了比较内容的方法

equals的覆盖步骤

(1)判断自反性(是否为同一个对象)
if (this == O) return true;
(2)判断o是不是null
if (o == null) return false;
(3)判断是否为同一类对象
if (this.getClass() != o.getClass()) return false;
(4)强制类型转换
(5)根据自己需求写出判断条件

2.包装类

包装类
1.为8种简单类型提供对象形式,方便让Object统一所有的数据类型
2.对于数值类型的属性,区分0和null

//int <–> Integer
int i = 12;
Integer ii = new Integer(i);
int i2 = ii.intValue();

//int<–>String
String s = i +"";
int i3 = Integer.parseInt(s);

//Integer<–>String
String s2 = ii.toString();
Integer ii2 = Integer.valueOf(s2);

//Char–>String
char c = ‘c’;
String str = String.valueOf©;

3.自动装箱、拆箱

JDK5.0以后的版本编译器会自动进行包装类和基本数据类型之间的转换(自动装箱拆箱)
比如Object o = 12; //编译通过 其原因是 编译器自动转换成了Object o = new Integer(12);
Integer k = (Integer)o;
k++;//k=new Integer(k.intValue()+1);

自动装箱原理分析
(1)自动装箱时,jvm默认调用Integer类中的静态方法valueOf(int n)
实现对应int–>Integer之间的转换
(2)valueOf
(3)缓冲区的作用:Integer 对常数数据段-128-127进行了预先包装处理,包装处理的结果存储在
常量池(也称为缓冲区),为了提高包装的效率,从而提高JVM内存的空间利用率

4.常用方法:

charAt(int index)// 根据下标获取字符
contains(String str)// 判断当前字符串中是否包含str
toCharArray()// 将字符串转换成char数组
indexOf(String str)// 在当前串中查找str出现的下标,如存在,返回第一次出现的下标,如不存在,返回-1
indexOf(String str,int fromindex)// 同上,从指定下标开始查找
lastIndexOf(String str)// 返回str在当前字符串中最后一次出现的下标
trim()// 去掉字符串前后的空格
split(String str)// 根据str做拆分
toUpperCase()// 小写转换成大写
toLowerCase()// 大写转换成小写
endWith(String str)// 判断字符串是否以str结尾
intern()// 从串池中获取和当前字符串内容相同的字符串
equalsIgnoreCase(String str)// 忽略大小写比较字符串的内容
split("[/ : . - _ # %]");  // []里面表示需要分割的符号

String str = "asjeji";
System.out.println(str.charAt(4)); //j    获取当前字符串下标对象的字符
System.out.println(str.substring(2,5));  //jej   取两个参数的中间字符
System.out.println(str.replace('j','x'));  //asjeji  String为不可变长字符串,所以replace方法是先拷贝一个副文本,完成字符的替换,如果获取替换后的结果,需要接收replace方法的返回值。

5.String、StringBuilder、StringBuffer的区别

String和StringBuilder,StringBuffer操作字符串时的区别。

(1) String:不可变长字符串,完成字符串拼接时效率相对较低
(2) StringBuilder:线程不安全,执行效率高,可变长字符串,完成字符串拼接时效率相对较高

(3) StringBuffer:线程安全,执行效率较低,可变长字符串,完成字符串拼接时效率相对较高

十四、集合

集合笔记链接: https://blog.csdn.net/zxwwantlearnjava/article/details/105331925

1.基础概念

集合框架
集合:容器 一个对象,用来储存其它多个对象

2.Collection接口

Collection接口
特点:元素是Object
子接口: List 和 Set
常用方法:
add(Object o):把对象o放入集合
addAll(Collection c): 把c中的所有对象放入当前集合
clear():清空集合
contains(Object o): 判断对象o在集合中是否存在
isEmpty(): 判断集合是否为空
remove(Object o):把对象o从集合中删除
removeAll(Collection c)删掉集合c中所有对象
size():返回集合中对象的个数
toArray():把集合转换成数组返回
iterator():返回一个Iterator对象 迭代器
遍历: 迭代遍历
while(o.hasNext()){ //hasNext()指针右边没对象,返回false,有对象返回true
Object os = o.next();
System.out.println(os);
}
实现类:无

3.List接口及其实现类

List接口
特点:元素有顺序(下标) 可以重复
方法:
add(int pos,Object o):把对象o插入到pos位置
get(int pos):返回pos位置的元素
indexOf(Obeject o):返回对象o在数组中的下标
remove(int pos):删除pos位置的元素
set(int pos,Object o):把pos位置的元素替换成o
遍历:
1.for 下标遍历
2.迭代遍历

实现类:
1.ArrayList 用数组实现 数组查询快,增删慢
jdk1.2版本 轻量级(运行速度快) 线程不安全

2.Vector 用数组实现
jdk1.0版本 重量级(运行速度慢) 线程安全

3.LinkedList 用链表实现 链表查询慢 增删快

4.Collections工具类

Collections 操作集合的工具类(方法都是static修饰)
常用方法:
reserve(List list); //倒叙
shuffle(List list); // 随机
sort(List list); //排序

(1)Collections.sort(集合名)
如果参与排序的集合中存储的是自定义类型的对象,则该对象应需要
实现java.lang.Comparable接口中的compareTo方法指定排序规则—>内置比较器

(2)List接口中提供默认方法 sort(Comparator c):如果参与排序的集合存储的是
自定义类型的对象,则需要在参与比较的对象以外的地方定义一个匿名内部类
(或是Lambda表达式)实现java.util.Comparator接口,同时实现Compare(T t1,T t2)
方法指定的排序规则—>外置比较器

5.Set接口及其实现类

Set接口
特点:元素无顺序 不可重复
方法:全部继承自Collection接口
遍历:迭代遍历
实现类:
HashSet
把自定义对象放入HashSet,为保证元素不重复 必须:
(1)覆盖hashCode() 保证相同对象返回相同的int
为了提高效率,尽量保证不同对象返回不同的int
(2)覆盖equals() 保证相同对象返回true

LinkedHashSet
是HashSet的子类,去除重复元素,同时可以按照元素添加顺序操作元素,

TreeSet
是SortedSet接口(Set的子实现类)的实现类
对元素自动排序 要求元素对象必须实现Comparable接口

6.Map接口及其实现类

Map
特点:元素由键值对组成 其中键唯一 值可以重复
方法:
put(Object k,Object v):把k-v这个键值对放入Map 如果k已经存在,那么新的v会替换旧的v
get(Object k):返回Map中k对应的v
remove(Object k):删除以k为键的键值对
size():返回键值对的数量
containsKey(Object k):判断k这个键是否存在
containsValue(Object v):判断这个值是否存在

遍历:
1.值遍历: values() 返回Map中所有值的集合:Collection
2.键遍历: keySet() 返回Map中所有键的集合:Set
3.键值对遍历: entrySet() 返回Map中所有键值对的集合:Set
键值对:Map.Entry对象 封装了一个key和一个value

实现类:
1.HashMap : jdk1.2版本 允许用null作为key或者value
2.Hashtable: jdk1.0版本 不允许null作为key或者value
两者区别等同于ArrayList和Vector的区别
3.Properties: Hashtable的子类 key和value都是String 一般用于配置文件的读取
4.TreeMap:实现了SortedMap(Map的子接口) 自动对Key排序

十五、泛型

泛型和枚举笔记链接: https://blog.csdn.net/zxwwantlearnjava/article/details/105456397

1.基础概念

泛型:
(1)泛型集合:数据安全性的集合,强制要求集合中存储的数据类型统一
a.list<数据类型> list = new ArrayList<数据类型>();
list<数据类型> list = new ArrayList<>();// 简略写法
b.集合中存储的元素必须是<>中指定的数据类型

(2)自定义的泛型类:
a.class 类名<泛型标识>{
//在类中将泛型标识作为一种数据类型
}

 注意: 通常会用K/V/T/E等单个大写字母作为泛型标识。

b.泛型类中泛型标识具体的数据类型是根据对象创建时指定:
类名<具体的数据类型> 引用名 = new 类名<具体的数据类型>();
注意: 基本数据类型必须使用其包装类型作为泛型类型

2.通配符

泛型的通配符:
? 表示任何类型
? extends Number: 表示Number类或Number的任何子类
? super Number: 表示Number类或Number的任何父类
? extends Comparable: 表示任何实现Comparable接口的类

比如 static void print(List< ? > list){}
static void print(List< ? extends Number > list){}
static void print(List< ? super Number >){}
static void print(List< ? extends Comparable >){}

3.泛型方法

泛型方法:
<T extends Number & Comparable>: T既是Number的子类,还得实现Comparable接口

泛型技术应用在集合框架中: 实现类型安全的集合
泛型: 约定集合中的元素类型

静态引入:
用到一个类中静态成员时,可以省略类名
比如import static java.lang.System.*; //意思是导入System类中的所有静态成员
打印语句就可以写成out.println(“Hello World”);

4.printf格式化打印

格式化输入输出
System.out.printf(“My name is %s , my name is % d”,name,age);

%s:字符串占位符
%d:整数占位符
%f:浮点数占位符
%1.3f:保留3位小数 1表示小数点前有1位 3表示小数点后有3位

5.枚举

枚举
类: 这个类的对象是构造好的,不允许用户构造该类的新对象
是特殊的类 默认是Enum的子类 默认被final修饰
所有的构造方法必须是私有的 可以不写,默认添加private(跟接口差不多)
枚举值: 该枚举类型的对象,也是枚举类中的公开静态常量
枚举中可以定义抽象方法,由枚举值分别实现

十六、异常

1.异常处理

提高程序的容错性:解决运行时错误

2.异常的分类

避免异常: 尽可能使异常不出现,不发生

处理异常: 当异常发生时,应对这种异常
有部分代码,正常情况不执行,异常发生时才执行

Throwable 所有异常的父类

(1)构造方法
Throwable();无参构造方法
Throwable(String message):带有异常信息的构造方法

(2)成员方法
String getMessage():获取字符串异常信息
void printStackTrace():打印栈追踪信息

1.Error 错误 严重的底层错误 不可避免 无法处理

2.Exception 异常 可以处理
(1)RuntimeException 运行时异常 未检查异常 可以避免
(2)非RuntimeException 已检查异常 不可避免

3.异常的产生和传递

throw 异常对象;
抛出一个异常
抛出异常:方法以异常对象作为返回值返回 等同于return语句

异常对象的传递:
沿着方法调用链,以返回值的形式,逐级回传到JVM,然后JVM会中止运行

4.异常的处理

1.声明抛出
public void method() throws Exception{}
方法覆盖时,子类方法不能比父类抛出更多的异常(范围)

2.捕获异常
try {
语句1
语句2

语句n
}
catch(异常类型A e){

}
catch(异常类型B e){

}

catch块个数不做限制

finally{
//无论如何代码都会执行
}

可以同时捕获父类异常和子类异常,但是必须先捕获子类异常再捕获父类异常

try块的三种结构
(1) try{} catch{}
(2) try{} catch{} finally{}
(3) try{} finally{} 无法捕获异常,利用finally必须执行的特点,完成特定操作

十七、IO流

IO流笔记连接: https://blog.csdn.net/zxwwantlearnjava/article/details/105714901

1.流的概念

概念: 流就是内存与存储设备之间传输数据的通道、管道

流对象:用来传输数据的对象

2.流的分类

流的方向(以JVM内存为参照物):输入流/输出流
输入流:将存储设备中的数据读入到JVM内存中
输出流:将JVM内存中的数据写入到存储设备中

数据单位:字节流/字符流

字节流:以字节为单位 处理任意类型的文件
字符流:以字符为单位 处理文本类型的文件

注意:文本类型的文件:能以记事本打开而且不乱码的文件
例如: .txt /.html /.java /.xml /.c是文本文件
.class /.world /.ppt /.map4是非文本文件

流的功能:节点流/过滤流

节点流:只具有基本的读写功能
过滤流:为节点流增强功能

抽象类 所有字节流的父类
InputStream(字节输入流)
OutputStream(字节输出流)

3.InputStream子类

FileInputStream(文件字节输入流)
常用构造方法:
(1)FileInputStream fis = new FileInputStream(“E:/text/a.txt”);
和下面的区别就是 文件必须存在 否则报错 java.io.FileNotFoundException

FileOutputStream(文件字节输出流)
常用构造方法:
(1)FileOutputStream fos = new FileOutputStream(“E:/text/a.txt”);
a.参数代表: 文件的路径及文件名: 例如:E:/text/a.txt或是E:\text\a.txt
如果指定文件不存在,则JVM会自动创建文件,但是如果指定文件夹
不存在,则jvm报错,错误信息为: java.io.FileNotFoundException(系统找不到指定路径)
b.绝对路径: 带有盘符的路径. 盘符:/文件夹/文件

(2)FileOutputStream fos = new FileOutputStream(“a.txt”);
a.相对路径: 默认在当前项目的根目录下查找所需要的文件,如果有,直接使用,如果没有,JVM自动创建

(3)FileOutputStream fos = new FileOutputStream(“file/a.txt”);
a.开发时,通常在项目的根目录下创建一个文件夹,用于存储项目中操作的文件,便于管理

(4)FileOutputStream fos = new FileOutputStream(“file/a.txt,true”);
参数说明:
第一个参数: 指定操作的文件路径及文件名
第二个参数: boolean 是否在原有内容进行追加

4.字节过滤流

(1)BufferedOutputStream/BufferedInputStream
a.缓冲流,提高IO读写效率,减少访问磁盘次数
b.数据存储在缓冲区,可以通过flush方法或是close方法
将缓冲区内容一次性写入到文件中,并清空缓冲区
1.flush方法只是清空缓冲区同时将缓冲区的内容一次性
写入到文件中,但是流还是可以继续使用
2.close方法关闭流的同时清空缓冲区,将缓冲区的内容
一次性写入到文件中,流一旦关闭不能再继续使用
注意: 缓冲区满时,将缓冲区的内容一次性写入到文件中,同时清空缓冲区

(2)PrintStream(输出流)
a.缓冲流,提高IO写的效率
b.增强了操作基本数据类型的方法,同时还可以操作字符串
print(int n)/print(long l)/print(boolean b)/print(double /d)/print(String str)–>不自动换行
println(int n)/println(long l)/println(boolean b)/println(double /d)/println(String str)–>自动换行

(3)ObjectOutputStream/ObjectInputStream(过滤流)
a.增强缓冲区,提高IO读写效率
b.增强了8种基本数据类型方法
c.对象序列化:
①概念:对象放在流上进行传输的过程
②参与对象序列化的要求:参与对象序列化的对象对应的类型必须实现java.io.Serializable
③对象的读写操作:
void writeObject(Object obj):将指定的对象写入到文件
Object readObject();从文件中读取对象
④文件达到尾部的标记:java.io.EOFException
⑤如果对象的某一个属性不想参与对象序列化,则对象前面用transient修饰
⑥如果参与对象序列化的对象中有自定义类型的属性,该属性也必须实现java.io.Serializable
否则运行报错:java.io.NotSerializableException(不可序列化异常)

write('A'); // 可以传入一个字节大小的字符  

5.JDK7.0新特性(try-with-resources)

try(定义资源 实现了Autocloseable接口){ 代码 }
catch(Exception e){e.printStackTrack();}

6.File类

java.io.File File对象代表磁盘上的一个文件或目录
creatNewFile();创建新文件
mkdir(): 创建新目录
delete(): 删除文件/文件夹

注意: 如果删除文件夹,则该文件夹必须为空,否则删除失败
如果删除文件,不管有没有数据,都会删除成功

exists(): 文件对象所代表的文件(或目录)是否存在
getName(): 获取文件名,带有后缀(文件类型,扩展名)
isDirectory(): 判断文件对象所代表的是否是目录
isFile(): 判断文件对象所代表的是否是文件
getAbsolutePath(): 获取绝对路径
listFiles(): 列出一个目录下的所有文件和子目录
listFiles(FileFilter f): 文件过滤器 实现FileFilter接口

7.数据过滤流

DataInputStream/DataOutputStream
直接读取8种基本数据类型和String readUTF()/writeUTF();

PipedInputStream/PipedOutputStream 管道流 用来在线程间交换数据
RandomAccessFile: 随机访问文件

8.字符的编解码

当字符编码和字符的接码不一致时,就会出现乱码

Reader/Writer 字符流的父类
FileReader/FileWriter 文件字符流 节点流
BufferedReader/BufferedWriter 缓冲流 过滤流
PrintWriter作用和BufferedWriter一样 但是更方便

9.桥转换流

桥转换流: InputStreamReader / OutputStreamWriter

当进行读写操作时,流会记录对象的状态,如果想要修改对象信息,进行二次读写操作,需要克隆对象

10.对象的克隆

实现Cloneable接口
覆盖Object中的clone方法
public Object clone(){
try{
return super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
return null;
}
}

十八、多线程

1.基础概念

链接: https://blog.csdn.net/zxwwantlearnjava/article/details/105601989

进程: 操作系统(OS)中正在执行的应用程序
CPU分时间片 宏观并行 微观串行 由操作系统负责调度

线程:在进程中,可以同时执行多个任务,每一个任务可以说是一个线程,线程是进程的工作单位。也被成为轻量级的进程

2.线程的组成

1.CPU 由操作系统负责分配

2.Data 堆空间共享 栈空间独立
堆空间: 存储对象 (存储实例变量)
栈空间: 存储局部变量
方法区: 存储静态数据、常量

3.代码 由程序员指定 :继承Thread类(覆盖run())或者实现Runnable接口中的run()

3.五个基本状态:

1.初始状态
2.可运行状态
3.运行状态
4.阻塞状态
5.终止状态
一个Thread对象代表一个线程

t1: t2.join() t1阻塞
当t2进入终止状态时,t1回到可运行状态

4.线程池

①线程池: 线程容器,将预先创建的线程对象存到线程池中,只要将任务提交给线程池,
会分配线程对象完成提交任务,线程池中的线程对象可以被重复使用
②好处: 避免频繁的创建线程和销毁,从而提高空间利用率和执行效率
③线程池常用的接口和类:(位于java.util.concurrent包中)
a.Executor:线程池的*接口
b.ExecutorService:是Executor的子接口,线程池的核心接口
(1)submit(Runnable task):将线程任务提交给线程池
(2)shutdown():关闭线程池,将线程池的线程对象全部销毁
c.Executors: 获取线程池对象的工具类,其中方法基本都为静态方法
static ExecutorService newFixedThreadPool(int n):获取一个固定数量线程的线程池
参数指定线程池中线程对象的数量
static ExecutorService newCachedThreadPool():获取动态数量线程对象的线程池,
根据提交的任务需求,不够用时,则自动完成线程创建

5.Callable接口

a.Callable接口: 位于java.util.concurrent包中,类似于Runnable接口的应用,对应的对象代表线程任务。
注意: Callable是泛型接口,泛型约束了接口中方法的返回值数据类型
b.接口中的方法: V call(): 带有返回值的方法,同时可以抛出异常
Future f = pool.submit(c1);
c.Future是存储submit提交任务执行之后的返回值
利用Future中的get方法获取执行的结果

6.线程的同步

当多线程并发访问临界资源(同一个对象)时,如果破坏了原子操作(不可分割的操作),就会造成数据不一致

synchronized(o){}:对o加锁的同步代码块 锁的是o对象
任何对象都有一个互斥锁标记,用来分配给线程
只有拿到对象锁标记的线程,才能进入对该对象加锁的同步代码块
线程退出同步代码块,会释放相应的锁标记

同步方法:在整个方法的范围内,对当前对象加锁
只有拿到对象锁标记的线程,才能调用该对象的同步方法

7.Lock

a.Lock:接口,位于java.util.concurrent.locks包中,代表锁
b.Lock中常用方法:
(1)void lock(): 获取锁
(2)void unlock(): 释放锁
c.实现类: ReentrackLock
锁池:任何对象都有的一个空间,用来存放等待该对象锁标记的线程

一个线程可以同时拥有多个对象的锁标记,当线程阻塞在锁池中时,不会释放
已经拥有的锁标记,由此可能造成死锁

8.解决死锁的办法

线程间的通信:等待-通知
任何对象都有一个等待队列,用来存放线程
t1: o.wait() 必须放在对o加锁的同步代码块中
效果(1) t1会释放其拥有的所有锁标记;
(2) 同时t1会阻塞在o的等待队列中

t2: o.notify()/notifyAll()必须放在对o加锁的同步代码块
效果 从o的等待队列中释放一个/全部线程
notify()
notifyAll()

9.集合的扩充

1.CopyOnWriteArrayList
(1)位于:java.util.concurrent包中
(2)在所有读操作(不会改变集合中数据内容的操作)中不加锁;在写操作时加锁,为了保证数据正确性,
写操作时,拷贝一个副文本,在副文本上进行写操作,写操作完成之后,新数据替换旧数据允许多个
线程同时进行读操作,但是同一时间只允许一个线程进行写操作,同时一个线程进行写操作,也允许
多个线程进行读操作。(牺牲写操作的效率提高读操作的效率)
(3)应用场景: 读操作的次数远远大于写操作次数时
(4)CopyOnWriteArrayList和Vector的共同特点和区别
区别:CopyOnWriteArrayList在读次数远远多于写操作时,效率远高于Vector,仅次于ArrayList
共同点:都是线程安全
CopyOnWriteArrayList和ArrayList
区别:CopyOnWriteArrayList线程安全,ArrayList线程不安全
共同点:用法和ArrayList一样(遍历方式等)

2.ConcurrentHashMap:(高效且线程安全)
(1)位于:java.util.concurrent包中
(2)采用分段锁,减小锁定的范围,从而减少锁冲突的可能性,提高线程的并发效率(分为16段)
(3)应用场景: 在全局操作不频繁的情况下(例如size等操作),效率较高
注意: jdk8.0版本及以上ConcurrentHashMap采用CAS算法(比较交换算法)和synchronized保证线程安全
(4)ConcurrentHashMap、HashMap、Hashtable的区别
ConcurrentHashMap:线程安全,执行效率更高,采用的分段锁提高并发效率,全局操作不频繁时,效率仅次于HashMap
HashMap:线程不安全,运行效率高
Hashtable:线程安全,底层锁的粒度太大,所以执行效率较低

3.Queue接口(java.util包中)
(1)Queue是Collection的子接口,描述队列存储结构,队列存储结构的特点:先进先出,后进后出,队列存储结构简称为FIFO
(2)常见的方法:
offer(Object o): 往队列中添加元素
poll(): 获取队头元素,并移除队头元素

4.BlockingQueue: 是Queue的子接口(java.util.concurrent包中)
(1)常用方法:
put(Object o):往队列结构中存储元素,如果没可用空间,则等待
take(): 从队列结构中取元素,如果没有可取元素,则等待
(2)常用实现类:
ArrayBlockingQueue: 数组实现,指定固定容量,有界队列
LinkedBlockingQueue: 链表实现,可以实现*队列

5.ConcurrentLinkedQueue是 Queue接口的实现类
(1)java.util.concurrent
(2)特点: 无锁并且线程安全的集合实现类,采用的CAS(比较交换算法)实现线程安全

注意: java.util.concurrent并发包(juc)

ArrayList: 所有方法都不是同步方法 可能会造成数据不一致 线程不安全 多线程并发时效率高
Vector: 方法基本上都是同步方法 线程安全 多线程并发时效率低

修饰符组合:
synchronized和static联用: 给当前类对象加锁

10.注意事项

以下内容不能和synchronized联用
synchronized不可以和abstract联用
synchronized不可以和构造方法联用

十九、反射

反射笔记链接: https://blog.csdn.net/zxwwantlearnjava/article/details/105737823
反射 通用编程
类对象 --> Class类的对象
类加载的产物,封装了一个类的所有信息(包名 类名 父类 接口 属性 成员方法 构造方法 …)

获取类对象的方式
(1)通过类的对象,获取类对象,getClass方法
Student s = new Student();
Class c1 = s.getClass();
(2)通过类名.class获取类对象
Class c2 = Student.class;
(3)利用Class类中静态方法forName(“包名.类名”);
注意: forName方法中参数需要的是

二十、23种设计模式(部分)

23种设计模式笔记链接: https://blog.csdn.net/zxwwantlearnjava/article/details/105737823
1.设计模式: 是一套被反复使用,多数人知晓、经过分类编目的代码经验总结
2.适配器设计模式
3.单例设计模式
(1)概念: 定义一个类,保证jvm中只有该类的一个实例对象存在
(2)代码实现单例模式:
a.饿汉式
优点:并发效率较高
缺点:
b.懒汉式
优点:空间利用率相对较高
缺点:并发效率相对较低,因为方法被synchronized修饰
c.扩充

4.工厂设计模式
(1)主要解决的问题:对象的创建,