java学习笔记

学习的重点

1.如何快速学习java技术

2.Java运行机制

3.JDK

4.Java开发规范

5.数据类型

6.二进制

7.位运算符

8.循环

9.数组

10.成员方法

11.成员方法传参机制

12.构造器

13.封装

14.继承

15.多态

16.类变量和类方法

17.接口

18.内部类

19.异常体系图

20.异常处理

21.String

22.StringBuffer

23.StringBuilder

24.集合框架体系

25.ArrayList

26.Vector

27.HashSet

28.HashMap

29.自定义泛型

30.Synchronized

31.互斥锁

32.项目&学以致用

33.TCP编程

34.反射获取类的结构信息

35.MySQL数据类型

36.CRUD

37.MySQL的增删改查

38.mysql的函数

39.mysql的外连接

40.mysql的索引

41.JDBC API

42.事务

43.连接池

44.Druid

45.DAO增删改查-BasicDao

46.三个常用类

47.分组、捕获、反向引用

48.元字符

49.Lambda

50.函数式接口

51.stream API

52.类型推断

53.集合增强API

java就业方向

javaEE

电商、团购、众筹、sns(社交网络)、教育平台、金融、搜索。

大数据软件工程师

1.大数据应用工程师

2.大数据算法工程师

3.大数据分析挖掘

Android软件工程师

Java开发场景

SSM

Spring(轻量级的容器框架)

SpringMVC(分层的web开发框架)

MyBatis(持久性框架)

Java应用领域

1.企业级应用

2.Android平台应用

3.移动领域应用

(LTS)长期支持 8&11

Java语言重要特点

1.Java语言是面向对象的(oop)

2.Java语言是健壮的。Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。

3.Java语言是跨平台性的。【即:一个编译好的.class文件可以在多个系统下运行,这种特性称为跨平台】

4.JAVA语言是解释型的。

解释性语言:Javascript,PHP,java 编译性语言:c/c++

区别是:解释性语言,编译后的代码,不能直接的被机器执行,编译性语言,编译后的代码,可以直接被机器执行,c/c++。

jbk

JVM:java虚拟机

java核心机制,java虚拟机【JVM java virtual machine】

1.JVM是一个虚拟的计算机,具有指令集并适用不同的存储区域。负责执行指令,管理数据、内存、寄存器、包含在jdk中。

2.对于不同的平台,有不同的虚拟机。

3.java虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”

jdk基本介绍

1.jdk全程(java Development Kit java开发工具包)

​ jdk = JRE + java的开发工具包【java,javac,javadoc,javap等】

2.JDK是提供了给java开发人员使用的,其中包含了java的开发工具,也包括了JRE。

​ 所以安装了JDK,就不用在单独安装JRE了。

JRE基本介绍

1.JRE(java Runtime Environment java运行环境)

​ JRE = JVM + java的核心类库[类]

2.包括java虚拟机(JVM java Virtual Machine)和 java程序所需的核心类库等,

​ 如果想要运行一个开发好的java程序,计算机中只需要安装JRE即可。

JDK,JRE,JVM关系

1.JDK = JRE + 开发工具集(例如Javac。java编译工具等)

2.JRE = JVM + Java SE标准类库

3.JDK = JVM + Java SE标注类库 + 开发工具集

4.如果只想运行开发的.class文件 只需JRE

第一个程序

//这是java的快速入门,演示java的开发步骤
//对代码的相关说明
//1.public class Hello 表示Hello是个类,是一个public共有的类
//2.Hello{}表示一个类的开始和结束
//3.public static void main(Strin[] args)表示一个主方法,即我们程序的入口
//4.main() {}表示方法的开始和结束
//5.System.out.println("hello,world~");表示输出“hello,world~”到屏幕
//6.;表示一个语句的结束
//7.javac -encoding UTF-8 *.java 如遇“错误: 编码GBK的不可映射字符”

public class Hello {
	// 编写一个main方法
	public static void main(String[] args){
		System.out.println("hello,world~");55 
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TTn0z3wP-1654397259785)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1648950884639.png)]

java执行流程分析

java源文件——javac编码——.class文件(字节码文件)——java运行——结果

Java 开发注意事项和细节说明

1.java源文件以.java 为拓展。源文件的基本组成部分是类(class),如本类中的Hello类。

2.java应用程序的直行入口是main()方法。他有固定的书写格式:

public static void main(String【】args){……}

3.java语言严格区分大小写。

4.java方法由一条条语句构成,每个语句以“;”结束。

5.大括号都是成对出现的,缺一不可。【习惯,先写{}再写代码】

6.一个源文件中最多只有一个public类。其他类的个数不限。

7.如果原文件包括一个public类,则文件名必须按该类名命名!

8.一个与文件中最多只能有一个public类,其他类的个数不限,也可以将main方法写在非public类中,然后制定运行非public类,这样入口方法就是非public的main方法。

如何快速学习技术或者知识点、心得分享

需求

1.工作需求

2.跳槽,对方要求

3.技术控

|

|

看看能否使用传统技术解决

1.能解决,但是不完美

2.解决不了

|

|

引出我们学习的新技术和知识点

|

|

学习新技术或者知识点的基本原理和基本语法(不要考虑细节)

|

|

快速入门(基本程序,crud)

|

|

开始研究技术的质疑事项使用细节,使用规范,如何优化=》没有止境,技术魅力

转义字符

java常用的转义字符

1.\t:一个制表位,实现对齐的功能。

2.\n:换行符

3.\ \ :一个\

4.\ “:一个”

5.\ ‘:一个’

  1. \ r:一个回车 System.out.println(“xxxx\rccccc”);

在控制台,输入tab键,可以时间命令补全。

注意\r

class Tiger{
	public static void main(String[] args){
		System.out.println("张正杰\r大帅");
	}
}

大帅杰

class Tiger{
	public static void main(String[] args){
		System.out.println("张正杰\r\n大帅");
	}
}

张正杰
大帅

class Tiger{
	public static void main(String[] args){
		System.out.println("书名\t作者\t价格\t销量\n三国\t罗贯中\t120\t1000");
	}
}

书名 作者 价格 销量
三国 罗贯中 120 1000

注释 comment

单行注释

/ /

多行注释

/* */

多行注释里面不允许有多行注释嵌套

文档注释

注释内容可以被jdk提供的工具javadoc所解析,生成一套以网页文件形式体现的该程序的说明文档,一般写在类

javadoc -d 文件夹名 -xx -yy Demo3.java

//文档注释

/**
*@author 张正杰
*@version 1.0
*/

public class comment02{
	public static void main(String[] args){

	}
}

javadoc -d d:\temp -author -version -encoding UTF-8 comment02.java

@author标识一个类的作者@author description
@deprecated指名一个过期的类或成员@deprecated description
{@docRoot}指明当前文档根目录的路径Directory Path
@exception标志一个类抛出的异常@exception exception-name explanation
{@inheritDoc}从直接父类继承的注释Inherits a comment from the immediate surperclass.
{@link}插入一个到另一个主题的链接{@link name text}
{@linkplain}插入一个到另一个主题的链接,但是该链接显示纯文本字体Inserts an in-line link to another topic.
@param说明一个方法的参数@param parameter-name explanation
@return说明返回值类型@return explanation
@see指定一个到另一个主题的链接@see anchor
@serial说明一个序列化属性@serial description
@serialData说明通过writeObject( ) 和 writeExternal( )方法写的数据@serialData description
@serialField说明一个ObjectStreamField组件@serialField name type description
@since标记当引入一个特定的变化时@since release
@throws和 @exception标签一样.The @throws tag has the same meaning as the @exception tag.
{@value}显示常量的值,该常量必须是static属性。Displays the value of a constant, which must be a static field.
@version指定类的版本@version info

java代码规范

1.类、方法的注释,要以Javadoc的方法来写。

2.非java doc的注释,往往是给代码的维护者看的,着重告诉读者为什么这样写,如何修改,注意什么问题。

3.使用tab操作,实现缩进,默认整体右边移动,时候用shift+tab整体向左移。

4.运算符和 = 两边习惯性各加一个空格。比如:2 + 4 * 5 + 345 - 89

5.源文件使用utf-8编码

6.行宽度不要超过80字符

7.行代码编写次行风格行尾风格

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oEgR67BM-1654397259786)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1648986206139.png)]

DOS命令(了解)

dos 的基本原理

1.接受指令

2.解析指令

3.执行指令

dos常用命令

1.查看当前目录是有什么:dir dir d:\abc2\test200

2.切换到其他盘下:盘符号 cd

​ 演示:切换到c盘 cd /D c:

3.切换到当前盘的其他目录下(使用相对路径和绝对路径演示)

​ 案例演示:cd d:\abc2\test200\ cd …\ … \ abc2 \ test200

4.切换到上一级:

​ 案例演示: cd…

5.切换到根目录: cd\

​ 案例演示:cd \

6.查看指定的目录下所有的自己目录

​ tree 盘符路径 tree d:\abc

7.清屏

​ cls【苍老师】

8.退出DOS

​ exit

9.md[创建目录],rd[删除目录],copy[拷贝文件],del[删除文件],echo[输入内容到文件],type[],move[剪切]

路径

相对路径

从当前目录开始定位,形成的一个路径

绝对路径

从顶级目录d,开始定位,形成的路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8wIvD78w-1654397259787)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1648988411674.png)]

变量

概念

变量相当于内存中一个数据存储空间的表示,你可以把变量看做是一个房间的门牌号,通过门牌号我们可以找到房间,而通过变量名可以访问到变量(值)

变量使用注意事项

1.变量表示内存中的一个存储区域【不同的变量,类型不同,占用的空间大小不同,比如:int 4个字节,double 8个字节】

2.该区域有自己的名称【变量名】和类型【数据类型】

3.变量必需先声明,后使用

4.该区域的数据可以在同一类型范围内不断变化

5.变量在同一作用域内不能重名

6.变量=变量名+值+数据类型

+号的使用

1.当左右两边都是数值型时,则做加法运算

2.当左右两边有一方为字符串,则做拼接运算

public class comment02{
	public static void main(String[] args){
			System.out.println(100 + 10);
			System.out.println("100" + 10);
			System.out.println(100 + 10 + "hello");
			System.out.println("hello" + 100 +10);
	}
}

110
10010
110hello
hello10010

数据类型 *

1.java数据类型分两大类基本数据类型,引用数据类型

基本数据类型

基本数据类型有8个

数值型:【byte字节[1],short短整型[2],int[4],long[8],float[4],doubke[8]】char[2],boolean[1]

引用类型

【类(class),接口(interface),数组([])】

整数数据类型

类型占用存储空间范围
byte[字节]1字节-128~127
short[短整型]2字节-(215)~215-1 -32760~32767
int[整型]4字节-231~231-1 -2147483648 - 2147483648
long[长整型]8字节-2^63 ~ 2^63-1

1.java个整数类型有固定的的范围和字段长度,不受具体OS[操作系统]的影响,以保证java程序的可移植性.

2.java的整形常量(具体值)么认为int类型,声明long型常量需后加’l’或’L’

3.java程序中变量常声明为int型,除非不足以表示大数,才使用long

4.bit:计算机中的最储存单位,byte:计算机中基本储存单位,1byte = bit

​ [二进制再详细说,简单举例一个byte 3 和 short 3]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d6tQmhAl-1654397259788)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649034149601.png)]

浮点类型

类型占用存储空间范围
单精度float4字节-3.403E38 ~ 3.403E38
双精度double8字节-1.798E308 ~ 1.798E308

1.浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位

2.尾数部分可能丢失,造成精度损失(小数都是近似值)

细节

1.与整数类型类似,java浮点类型也有固定的范围和字段长度,不受具体OS的影响.[float 4 个字节 double 是 8个字节]

2.java的浮点型常量默认为double型,声明float型常量,需后加’f’ 或 ‘F’

3.浮点型常量有两种表示形式

​ 十进制数形式:如 5.12 521.0f .521 (必须有小数点)

4.通常情况下,应该使用double型,因为它比float型更精准.

​ double num9 = 2.12345678;

​ float num10 = 2.123456789F;

5.浮点型使用陷阱: 2.7 和 8.1 / 3 比较

float num = 1.1; //错
float num = 1.1F;//对
double num = 1.1 //对
double num = 2.3 //对
double num1 = 2.7;
			double num2 = 8.1 / 3;
			System.out.println(num1);
			System.out.println(num2);
			if(Math.abs( num1 - num2 ) < 0.000001){
				System.out.println("差值很小");
			}
			System.out.println(Math.abs(num1 - num2));

2.7
2.6999999999999997
差值很小
4.440892098500626E-16

API 文档

1.API(Application Programming Interface ,应用程序编写接口)是java提供的基本编程接口(java提供的类还有相关方法).中文文档:https://www.matools.com

2.java语言提供了大量的基础类,因此Oracle公司也为这些基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及这些类里包含的方法。

3.java类的组织形式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G6vEynCe-1654397259788)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649048774059.png)]

  1. 包->类->方法

    直接索引

字符类型

字符类型可以表示单个字符,字符类型是char,char是两个字节(可以放汉字),多个字符我们用字符串String

快捷键 Ctrl+Shift+D 复制光标所在行插入到下一行。

字符细节

1.字符常量是用单引号(‘ ’)括起来的单个字符.

2.java 中还允许使用转义字符 ‘\’ 来将其后的字符转变为特殊字符型常量。

3.在java中,char的本质是一个整数,在输出时,是unicode码对应的字符。

4.可以直接给char赋值一个整数,然后输出时,会按照对应的unicode字符输出

5.char类型是可以进行运算的,相当于一个整数,因为它对应都unicode码

char c1 = 98; //b
		//在java中,char的本质是一个整数,在输出时,是unicode码对应的字符
		System.out.println("c1:" + c1);

		char c2 = '\n';
		char c3 = 'a';
		char c5 = 'a';
		char c4 = '张';
		char c6 = 24352;
		System.out.println("c2:" + c3);
		System.out.println(c2);
		System.out.println((int)c4);
		System.out.println((int)c5);//输出’a'对应的数字
		System.out.println(c6);

c1:b
c2:a

24352
97

System.out.println('a' + 10); //107
		char c7 = 'b' + 1 ;
		System.out.println((int) c7);
		System.out.println(c7);

99
c

字符类型本质探讨

1.字符型 储存到 计算机中,需要将字符对应的码值(整型)找出来,比如‘a’储存:’a’==>码值97

>二进制(1100001)>存储 读取:二进制(1100001)=>97 ===> ‘a’=>显示

2.字符和码值的对应关系是通过字符编码表决定的

字符编码

ASCII(ASCII编码表一个字节表示,一个128个字符,实际上一个字节可以表示256个字符,只用128)

Unicode(Unicode 编码表 固定大小的编码表,使用两个字节来表示字符,子母和汉字统一都是占用两个字节,这样浪费空间)

utf-8 (编码表,大小可变的编码,字母使用1个字节,汉字使用3个字节)

gbk(可以表示汉字,而且范围广,字母使用1个字节,汉字2个字节)

gb2312(可以表示汉字,gb2312<gbk)

big5 码(繁体中文,台湾,香港)

boolean布尔类型

public class Boolean01 {
	public static void main(String[] args){
		boolean isPass = true ;
		if (isPass == true){
			System.out.println("恭喜恭喜");
		}else{
			System.out.println("加油!");
		}
	} 
}

恭喜恭喜

基本数据类型的转换

介绍

当java程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是*自动类型转换*。

数据类型按精度(容量)大小排序为

char->int->long->float->double

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

int a = 'c'; //对的
double d = 80//对的

自动类型转换注意和细节

1.多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的哪种数据类型,然后再进行计算。

2.当我们吧精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,就会报错,反之就会进行自动类型转换。

3.(byte,short)和char之间不会相互自动转换。

4.byte,short,char 他们三者可以计算,在计算时首先转换为int类型。

5.Boolean 不参与转换

6.自动提升原则:表达式结果的类型自动提升为 操作数中最大的类型

float d1 = 10 + 1.1; //错误  10+1.1结果类型为 double
float d1 = 10 + 1.1F; //对  结果为 float
byte b1 = 10 ; 
byte b2 = 10 ;
char c1 = b1 ;// 错误,原因byte不能自动转成 char
short s1 = 1 ;
short s2 = b2 + s1 ;//错误,b2 + s1 => int
int s3 = b2 + s1 ; //对
byte b3 = b2 + b1 ; //不对

强制数据类型转化

自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型,使用时要加上强制转换符(),但可能造成精度降低或者溢出,格外要注意。

public class ForceConvert{
	public static void main(String[] args){
		int n1 = (int)1.9 ;
		System.out.println("n1=" + n1);//造成精度损失

		int n2 = 2000;
		byte b1 = (byte)n2;
		System.out.println("n2=" + b1);//造成数据溢出
	}
}

n1=1
n2=-48

细节说明

1.当进行数据的大小从 大——>小,就需要使用到强制转换。

2.强转符号只针对于最近的炒作数有效,往往会使用小括号提升优先级

3.char类型可以保存int的常量值,但不能保存int的变量值,需要强制转换

4.byte和chort类型在进行运算时,当做int类型处理。

char c1 = 100;
		int m = 100;
		// char c2 = m;  //错误
		char c3 = (char)m;
		System.out.println(c3);

d

		short s = 12;
		s -= 9; //对的
		s = s - 9; //错 int—>short
		System.out.println(s); //对 结果为3

		byte b = 10;
		b += 11;
		b = b + 11; //错 int->byte
		b = (byte)(b + 11);
		System.out.println(b); //对 结果为32

		char c = 'a';
		int i = 16;
		float d = .314F;
		double result = c + i + d;
		System.out.println(result); //对 结果为113.31400299072266

		byte b1 = 16;
		short s1 = 14;
		// short t1 = s1 + b1; //错 不兼容的类型: 从int转换到short可能会有损失
		System.out.println(t1);

基本数据类型和String类型的转换

基本类型转String类型

将基本类型的值 + “ ” 即可

public class StringToBasic{
	public static void main(String[] args){
		//基本数据类型->string
		int n1 = 100;
		float f1 = 1.1F;
		double d1 = 4.5;
		boolean b1 = true;
		String s1 = n1 + "";
		String s2 = f1 + "";
		String s3 = d1 + "";
		String s4 = b1 + "";
		System.out.println(s1 + " " + s2 + " " + s3 + " " + s4);
	}
}

100 1.1 4.5 true

String类型转基本数据类型

通过基本类型的包装类调用parseXX方法即可

String s5 = "123";
		int num1 = Integer.parseInt(s5);
		double num2 = Double.parseDouble(s5);
		float num3 = Float.parseFloat(s5);
		long num4 = Long.parseLong(s5);
		byte num5 = Byte.parseByte(s5);
		boolean b = Boolean.parseBoolean("true"); 
		short num6 = Short.parseShort(s5);
		System.out.println(num1+" "+num2+" "+num3+" "+num4+" "+num5+" "+b+" "+num6);

123 123.0 123.0 123 123 true 123

//怎么把字符串转成字符char -> 含义是指 把字符串的第一个字符得到
//解读 s5.charAt(0)得到s5字符串的第一个字符“1”
System.out.println(s5.charAt(0));
public class demo001{
	public static void main(String[] args){
		char a1 = '\n';
		char a2 = '\t';
		char a3 = '\r';
		char a4 = '\\';
		char a6 = '1';
		char a7 = '2';
		char a8 = '3';
		System.out.println(a1 + " " +a2 + " " +a3 + " " +a4 + " " + a6 + " " + a7 + " " + a8);
	}
}
class demo002{
	public static void main(String[] args){
		String bookName = "雪山飞狐";
		String bookName01 = "倚天屠龙记";
		System.out.println(bookName + bookName01);

		char sex = '男';
		char sex1 = '女';
		System.out.println(sex + "" + sex1);//得到男女
		System.out.println(sex + sex1);//得到 字符码值 + 字符码值

		float rmb = 12.4F;
		float rmb1 = 43.2F;
		System.out.println(rmb + rmb1); // 得到 两数相加
	}
}
class demo003{
	public static void main(String[] args){
		String name = "张正杰";
		int age = 20;
		int result = 100;
		char sex = '男';
		String live = "羽毛球";
		System.out.println("姓名\t年龄\t成绩\t性别\t爱好");
		System.out.print(name + '\t' + age + '\t' + result + '\t' + sex + '\t' + live );

	}
}

雪山飞狐倚天屠龙记
男女
55.6

姓名 年龄 成绩 性别 爱好
张正杰 20 100 男 羽毛球

运算符

运算符介绍

运算符运算
+正号
-负号
+
-
*
/
%取模(取余)
++自增
自减
+字符串相加

算数运算符

System.out.println(10 / 4); //结果:2
System.out.println(10.0 / 4); // 结果:2.5
double d = 10 / 4;
System.out.println(d); //结果: 2.0

// 在 % 的本质,看一个公式 a % b = a - a / b * b
// -10 % 3 => -10 - (-10) / 3 * 3 = -10 + 9 = -1
// 10 % -3 => -0 - 10 / (-3) * (-3) = 10 - 9 = 1
System.out.println(10 % 3); //结果为:1
System.out.println(-10 % 3); //结果为:-1
System.out.println(10 % -3); //结果为:1
System.out.println(-10 % -3); //结果为:-1

求华氏温度转摄氏温度

// 1.需求
// 	定义一个变量保存华氏温度,华氏温度转换摄氏度的公式为
// 	:5/9*(华氏温度-100),请求出华氏温度对应的是摄氏度

// 2.思路分析
// 	(1)先定义一个double huaShi 变量保存 华氏温度
// 	(2)根据给出的公式,进行计算即可5/9*(华氏温度-100)
// 	(3)将得到的结果保存到double sheShi

public class huashiwendu{
	public static void main(String[] args){
		double huaShi = 234.6;
		double sheShi = 5 / 9.0 * (huaShi - 100);
		System.out.println("华氏温度" + huaShi +
							 "对应的摄氏温度" + sheShi);
	}
}

华氏温度234.6对应的摄氏温度74.77777777777777

关系运算符

运算符运算
==相等于
!=不等于
<小于
>大于
<=小于等于
>=大于等于
instaceof检测是否是类的对象 “hsp” instanceof String true
int a = 9;
int b = 8;
boolean flag = a > b;

flag=true

逻辑运算符

短路与 &&

规则:当a和b同时为true,则结果为true,否则为false

​ 如果第一个条件为false,后面的条件不再判断

​ 效率高

短路或 ||

规则:当a和b,有一个为true,则结果为true,否则为false

​ 如果第一个为true,则第二个条件不会判断,最终结果为true

​ 效率高

取反 !

当a为true,则结果为false

逻辑与 &

规则:当a和b同时为ture则结果为true,否则为false

​ 如果第一个条件为false,后面的条件仍会判断

​ 效率低

逻辑或 |

规则:当a和b,有个为true,则结果为true,否则非false

​ 如果第一个为true,则第二个条件仍会判断

​ 效率低

逻辑异或 ^

当a和b不同时,则结果为true,否则为false

aba&ba&&ba|ba||b!aa^b
truetruetruetruetruetruefalsefalse
truefalsefalsefalsetruetruefalsetrue
falsetruefalsefalsetruetruetruetrue
falsefalsefalsefalsefalsefalsetruefalse
public class logicQuestions{
	public static void main(String[] args){
		boolean num1 = true;
		boolean num2 = false;
		short z = 46;
		if ((z++ == 46) && (num2 = true)) z++;
		if ((num1 = false) || (++z == 49)) z++; 
		System.out.println("z =" + z);
	}
}

z =50

赋值运算符

基本赋值运算符 =

复合赋值运算符

+= , -= , *= ,/= ,%= 等。(强转)

特点

1.运算顺序从右往左 int num = a + b + c

2.赋值运算符的左边 只能是变量,右边,可以是变量,表达式,常量值

​ int num = 20;int num2 = 78 * 34 - 10; int num3 = a;

3.复合赋值运算符等价于下面的效果

​ 比如:a + = 3; 等价于a = a + 3;

4.复合赋值运算符会进行类型转换;

byte b = 2; b += 3; b++ ;
byte b = 3;
b += 2; //等价 b = (byte)(b + 2);
b++; // b = (byte)(b + 1); 

三元运算符

基本语句

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

运算规则

1.如果条件表达式为true,运算后的结果是表达式1;

2.如果条件表达式为false,运算后的结果是表达式2;

使用细节

1.表达式1和表达式2要为可以赋值给接受变量的类型(或可以自动转换)

2.三元运算符可以转成 if–else语句

int res = a > b ? a++ : --b;
public class maxNum{
	public static void main(String[] args){
		int num1 = 4 , num2 = 7 , num3 = 5 , max;
		// num1 = num1 > num2 ? num1 : num2;
		// num1 = num1 > num3 ? num1 : num3;

		max = (num1 > num2 ? num1 : num2) > num3 ? 
				(num1 > num2 ? num1 : num2) : num3;
		System.out.print(max);
	}
}

7

运算符优先级

1.(),{}等

2.单目运行 ++ ——

3.算术运算符

4.位移运算符

5.比较运算符

6.逻辑运算符

7.三目运算符

8.赋值运算符

标识符的命名规则和规范

1.java对各种变量,方法和类命名时使用的字符序列成为标识符

2.凡是自己可以起名字的地方都叫标识符 int num1 = 90;

标识符的命名规则

1.由26个英文字母大小写,0-9,_或者$组成的

2.数字不可开头,

3.不可使用关键字和保留字,但能包含关键字和保留字

4.java中严格区分大小写,长度无限。

5.标识符不能包含空格

标识符的命名规范

1.包名:多单词组成时所有字母都小写:aaa.bbb.ccc //比如com.hsp.crm

2.类名,接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz

​ 比如:TankShotGame

3.变量名,方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个

​ 单词首字母大写:xxxYyyZzz

​ 比如:tankShotGame

4.常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ

​ 比如:定义一个所得税率 TAX_RATE

关键字

定义:被java语言赋予了特殊含义,用作专门用途的字符串

特点:关键字中所有字母都为小写

保留字

现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字。

键盘输入

import java.util.Scanner;//表示把java.util下的Scanner类导入
public class Input{

	public static void main(String[] args){
		//演示接受用户的输入
		//步骤
		//Scanner类 表示 简单文本扫描器,在java.util 包
		//1.引入 Scanner类所在的包
		//2.创建 Scanner 对象,new 创建一个对象,体会
		// 	MyScanner 就是 Scanner类的对象
		Scanner myScanner = new Scanner(System.in);
		//3.接收用户输入了, 使用 相关的方法
		System.out.println("请输入名字");

		//当程序执行到 next 方法时, 会等待用户输入~~~
		String name = myScanner.next();//接收用户输入字符串
		System.out.println("请输入年龄");
		int age = myScanner.nextInt();//接收用户输入int
		System.out.println("请输入薪水");
		double sal = myScanner.nextDouble();//接收用户的double
		System.out.println("人的信息如下:");
		System.out.println("名字:" + name + 
							"年龄:" + age +
							"薪水:" + sal);
	}
}

进制

二进制: 0,1,满2进1,以0b或0B开头表示。

十进制:0-9,满10进1

八进制:0-7,满8进1,以数字0开头表示。

十六进制:0-9及(10)-F(15),满16进1,以0x或0X开头表示。此处的A-F不区分大小写。

int n1 = 0b1010;
int n2 = 1010;
int n3 = 01010;
int n4 = 0x10101;

n1 = 10
n2 = 1010
n3 = 520
n4 = 65793

进制的转换(基本功)

二进制转十进制

从最低位(右边)开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和

0b1011 = 1 * 2的0次方 + 1 * 2的1次方 + 0 * 2 的2次方 + 1 * 2 的3次方 = 1 + 2 +0 +8 = 11

八进制转换成十进制

从最低位(右边)开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和

0234 = 4 * 8^0 + 3 * 8^1 + 2 * 8^2 = 4 + 24 + 128 = 156

十六进制转换成十进制

从最低位(右边)开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和

十进制转化成二进制

将该数不断除与2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pnL4Ibnr-1654397259789)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649422421225.png)]

十进制转换成十六进制

将该数不断除与16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。

二进制转换成八进制,十六进制

从低位开始,将二进制数每三位一组,转成对应的八进制数即可。

11 ( 3 ) 010 ( 2 ) 101 ( 5 ) = > 0325 11(3) 010(2) 101(5) => 0325 11(3)010(2)101(5)=>0325

二进制转换成十六进制

从低位开始,将二进制数每四位一组,转成对应的十六 进制数即可。
1101 ( D ) 0101 ( 5 ) = 0 x D 5 1101(D)0101(5) = 0xD5 1101(D)0101(5)=0xD5

八进制,十六进制转成二进制

八进制转二进制

将八进制数每1位,转成对应的一个3位的二进制数即可。
02 ( 010 ) 3 ( 011 ) 7 ( 111 ) = o b 010011111 02(010)3(011)7(111) = ob010011111 02(010)3(011)7(111)=ob010011111

十六进制转二进制

将十六进制数每1位,转成对应的一个4位的二进制数即可。
0 x 2 ( 0010 ) 3 ( 0011 ) B ( 1011 ) = 0 b 001000111011 0x2(0010)3(0011)B(1011) = 0b001000111011 0x2(0010)3(0011)B(1011)=0b001000111011

位运算

练习

public class BitOperation{
	public static void main(String[] args){
		int num1 = 1 >> 2;  //1向右右位移2位
		int num2 = -1 >> 2;
		int num3 = -1 << 2;
		int num4 = 1 << 2;
		int num5 = 3 >>> 2;//算数右移

		System.out.println("num1=" + num1);
		System.out.println("num2=" + num2);
		System.out.println("num3=" + num3);
		System.out.println("num4=" + num4);
		System.out.println("num5=" + num5);
		
	}
}

num1=0
num2=-1
num3=-4
num4=4
num5=0


~2=? // 按位取反

2&3=?//2按位与3

2|3=? //

~-5=?

13&7=?

5|4=?

-3^3=? //^按位异或

二进制运算说明

​ 1现代的电子计算机技术全部采用的事二进制,因为他只有0,1两个数字符号,非常简单方便,易用电子方式实现。计算机内部处理的信息,都采用二进制数来表示,二进制(Binary)数用0和1两份数字及其组合来表示任何数。进为规则是"逢2进1",数字1在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增。

原码,反码,补码(重点,难点)

介绍

  1. 二进制的最高位是符号位:0表示正数,1表示复数(口诀:0->0 1->-)

  2. 正数的原码,反码,补码都一样(三码合一)

  3. 负数的反码=它的原码符号位不变,其他位取反(0->1,1->0)

  4. 负数的补码=它的反码+1,负数的反码=负数的补码-1

  5. 0的反码,补码都是0

  6. java没有无符号数,换言之,java中的数都是有符号的

  7. 在计算机运算的时候,都是以补码的方式来运算的

  8. 当我们看运算结果的时候,要看他的原码(重点)

位运算符

七个位运算符(&,|,^,~,>>,<<,>>>)

按位与&

两位全是1,结果为1,否者为0.

按位或|

两位有一个为1,结果为1,否这为0

按位异或^

两位一个为0,一个为1,结果为1,否者为0

按位取反~

0->1,1->0

练习

public class BitOperation{
	public static void main(String[] args){
		//1.先得到 2的补码 => 2原码 00000000 00000000 00000000 00000010
		//	2的补码 00000000 00000000 000000000 00000010	
		//2.3的补码 3的原码 00000000 00000000 00000000 00000011
		//	3的补码 00000000 00000000 000000000 00000011
		//3.按位&
		//	00000000 00000000 000000000 00000010
		//	00000000 00000000 000000000 00000011
		//	00000000 00000000 000000000 00000010 & 运算后的补码
		//	运算后的原码 也是 00000000 000000000 00000010
		//  结果为	2
		System.out.println(2&3);//2

		//1.-2的补码 => -2的原码 10000000 00000000 00000000 00000010
		//2.-2的反码 11111111 11111111 11111111 11111101
		//3.-2的补码 11111111 11111111 11111111 11111110
		//4.~-2操作	 00000000 00000000 00000000 00000001
		//5.运算后的原码 就是 00000000 00000000 00000000 00000001
		System.out.println(~-2); //1

		//1.2的补码 00000000 00000000 00000000 00000010
		//2.~2操作  11111111 11111111 11111111 11111101 运算后的补码
		//3.运算后的反 11111111 11111111 11111111 11111100  
		//4.运算后的原码 10000000 00000000 00000000 00000011 => -3  
		System.out.println(~2); //-3
		
		//2的原码 00000000 00000000 00000000 00000010
		//3的原码 00000000 00000000 00000000 00000011
		//2|3	00000000 00000000 00000000 00000010
		//		00000000 00000000 00000000 00000011
		// 		00000000 00000000 00000000 00000011
		System.out.println(2|3);//3

		//2的原码 00000000 00000000 00000000 00000010
		//3的原码 00000000 00000000 00000000 00000011
		//2|3	00000000 00000000 00000000 00000010
		//		00000000 00000000 00000000 00000011
		//		00000000 00000000 00000000 00000001
		System.out.println(2^3);//1
	}
}

算数右移 >>

低位溢出,符号位不变,并用符号位补溢出的高位

算数左移<<

符号位不变,低位补0

>>> 逻辑右移也叫无符号右移

低位溢出,高位补0

程序控制结构

介绍

1.顺序控制

2.分支控制

3.循环控制

分值控制 if-else

1.单分支

2.双分支

3.多分支

基本语法

if(条件表达式){

​ 执行代码块;

​ }

说明:如果只有一条语句,则可以不用{},建议写上{}

2.双分支

if(条件表达式){

​ 执行代码块1;

​ }

​ else{

​ 执行代码块2;

​ }

说明:当条件表达式成立,及执行代码块1,否则执行代码块2,如果执行代码块只有一条语句,则{}可以省略,否则,不能省略。

练习if判断是否闰年

import java.util.Scanner;

public class LeapYear{
	public static void main(String[] args){
		//输入一个年份
		Scanner myScanner = new Scanner(System.in);
		System.out.println("请输入年份用来判断是否是闰年。");
		String scannerYear = myScanner.next();
		//将输入的String类型转换成int类型
		int year = Integer.parseInt(scannerYear);
		//进行是否为闰年判断
		//年份能被4整除,但不能被100整除或能被400百整除的
		if((year % 4 == 0 && year % 100 != 0) || (year % 400 ==0)){
			System.out.print(year + "是闰年");
		}else{
			System.out.print(year + "不是是闰年");
		}

	}
}

3.多分支

if(条件表达式){

​ 执行代码块1;

​ }

​ else if(条件表达式2){

​ 执行代码块2;

​ }

​ ……

​ else{

​ 执行代码块n;

​ }

特别说明:(1)多分支,可以没有else,如果所有的条件表达式都不成立,则一个执行入口都没有

​ (2)如果有else,如果所有的条件表达式都不成立,则默认执行else代码块

4.嵌套分支

if(){

​ if(){

​ // if-else……

​ }else{

​ //if-else

​ }

​ }

switch分支结构

基本语法

switch(表达式){

​ case 常量1;

​ 语句块1;

​ break;

​ case 常量2;

​ 语句块2;

​ break;

​ ……

​ case 常量n;

​ 语句块n;

​ break;

​ default;

​ default语句块;

​ break;

}

  1. switch关键字,表示swtich分支
  2. 表达式对应一个值
  3. case常量1:当表达式的值等于常量1,就执行语句块1
  4. break:表示退出swtich
  5. 如果和case常量1匹配,就执行语句块1,如果没有匹配,就继续匹配case常量2
  6. 如果一个都没有匹配上,执行default

switch注意事项和细节

  1. 表达式数据类型,应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符,而常量是int
  2. switch(表达式)中表达式的返回值必须是:(byte,short,int,char,enum[枚举],String)
  3. case子句中的值必须是常量,而不能是变量
  4. default子句是可选的,当没有匹配的case时,执行default
  5. break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有写break,程序会顺序执行到switch结尾。
public class SwitchDetail{
	public static void main(String[] args){
		//应和case后的常量类型一致,或者是可以自动转成可以相互比较的类型,比如输入的是字符,而常量是int
		//字符与int类型可以比较

		Char c = 'a';
		switch(c) {
			case 'a':
			System.out.println("ok1");
			break;
		case 20 + 1:
			System.out.println("ok2");
			break;
		default:
			System.out.println("ok3");
		}
	}
}

for循环

for(循环变量初始化;循环条件;循环变量迭代){ 循环操作语句}

  1. for关键字,表示循环控制
  2. for有四要素:(1)循环初始化(2)循环条件(3)存缓操作(4)循环变量
  3. 循环操作,这里可以有多条语句,也就是我们要循环执行的代码
  4. 如果循环操作(语句)只有一条语句,可以省略{},建议不要省略

注意事项和细节

  1. 循环条件时返回一个布尔类型的表达式

  2. for(;循环判断条件;)中的初始化和变量迭代可以写到其他地方,但是两边的分号不能省略。

  3. 循环初始化值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,

    循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开。

while循环控制

基本语法

循环变量初始化;

while(循环条件){

​ 循环体(语句);

​ 循环变量迭代;

​ }

说明

  1. while循环也要四要素
  2. 只是四要素放的位置,不一样。

do…while循环控制

基本语法

do{

​ 循环体(语句);

​ 循环变量迭代;

​ }while(循环条件);

说明

  1. do while 是关键字
  2. 也有循环四要素,只是位置不一样
  3. 先执行,再判断,也就是说,一定会执行一次
  4. 最后有个分号;

注意事项和细节

  1. 循环条件是返回一个布尔值的表达式
  2. do…while循环是先执行,再判断,因此它至少执行一次

练习

import java.util.Scanner;
public class Do_While{
	public static void main(String[] args){
		Scanner myScanner = new Scanner(System.in);
		char answer = ' ';
		do{
			System.out.println("拍拍拍,五连鞭!");
			System.out.println("还钱吗?");
			answer = myScanner.next().charAt(0);
		}while(answer != '还');
	}
}

金字塔

public class Pyramid{
	public static void main(String[] rags){

		for(int i = 1 ; i <= 6 ; i++) {
			for(int k = 1 ; k <= 6 - i ; k++) {
			System.out.print(" ");
		}
			for(int j = 1 ; j <= 2 * i - 1 ; j++) {
				if(j == 1 || j == 2 * i - 1 || i == 6){
					System.out.print("*");
				}else{
					System.out.print(" ");
				}
			}
			System.out.println();
		}
	}
}

跳转控制语句 break

注意事项和细节

  1. break语句出现在多层嵌套的语句块中时,可以通过指明要终止的是哪一层语句块
  2. 标签的基本使用

label1:{……

label2:{……

lable3:{……

​ break label2;

​ }

​ }

​ }

  1. break语句可以指定退出那层
  2. lable1是标签,用程序员指定
  3. break后制定到哪个label就退出到哪里
  4. 在实践中的开发中,尽量不使用标签
  5. 如果没有指定break,默认退出最近的循环

跳转控制语句 continue

也可标签,同break

跳转控制语句 return

练习

某人有10000元,每经过一次路口,需要缴费规则如下;

  1. 当现金>50000时,每次交5%
  2. 当现金 <= 50000时,每次交1000

编程计算该人可以经过多少次路口

public class Homework01{
	public static void main(String[] args){
		double money = 100000;
		int count = 0;
		while(true) {
			if(money > 50000) {
				money *= 0.95;
				count++;
			}else if(money >= 10000) {
				money -= 1000;
				count++;
			}else {
				break;
			}
		}
	}
}

水仙花数

import java.util.Scanner;
public class Daffodils{
	public static void main(String[] args){
		Scanner myScanner = new Scanner(System.in);
		System.out.println("输入一个三位数:");
		int num0 = myScanner.nextInt();
		
		int sum = 0;
		int num01 = num0 % 10;
		int num02 = num0 / 10 % 10;
		int num03 = num0 / 100;

		if(num0 == num01*num01*num01 + num02*num02*num02 + num03*num03*num03){
			System.out.println(num0 + "是水仙花数" );
		}else{
			System.out.println(num0 + "不是水仙花数");
		}
	}
}

数组

类型 [] 变量名 = {值};

类型 变量名 []= {值};

数组长度

变量名.length

数组的定义

动态初始化

数据类型 数组名[] = new 数据类型[大小];

数据类型 数组名[];也可以 数据类型[] 数组名;

创建数组

语法:数组名 = new 数组类型[大小];

  1. 数组的引用(使用/访问/获取数组元素/)
  2. 数组名[下标/索引/index]

静态初始化

语法:数据类型 数组名[] = {元素值,元素值……}

数组使用注意事项和细节

  1. 数组是多个相同类型数据的组合,实现对这些数据的统一管理
  2. 数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型,但是不能混用
  3. 数组创建后,如果没有赋值,有默认值(int 0 ,short 0 , long 0 ,float 0.0 , double 0.0,char \n0000,boolean false,String null)
  4. 数组属引用类型,数组型数据是对象(object)

数组赋值机制

  1. 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。
  2. 数组在默认情况下是引用传递,赋的值是地址。
public class ArrayAssign {
	public static void main(String[]  args) {
		//基本数据类型赋值,赋值方法为值拷贝
		//n2的变化,不会影响到n1的值
		int n1 = 10;
		int n2 = n1;

		n2 = 90;
		System.out.println("n1=" + n1);
		System.out.println("n2=" + n2);

		//数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用赋值
		//是一个地址,arr2变化会影响到arr1
		int arr1[] = {1,2,3};
		int arr2[] = arr1;

		arr2[0] = 4;

		for(int i = 0; i < arr1.length; i++) {
			System.out.println(arr1[i]);
		}
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2yGz2EvB-1654397259790)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649678193355.png)]

数组的拷贝

int[] = {1,2,3};
//创建一个新的数组arr2,开辟新的数据空间
//大小 arr1.length
int[] arr2 = new int[arr1.length];
//遍历arr1,把每个元素拷贝到arr2对应的元素位置
for(int i = 0; i < arr1.length; i++) {
    arr2[i] = arr1[i];
}

排序

内部排序

指将需要处理的所有数据都加载到内部储存器中进行排序。包括(交换式排序法,选择式排序法和插入式排序法)

外部排序

数据量过大,无法全部加载到内存中,需要借助外部内存进行排序,包括(合并排序法和直接合并排序法)

多维数组—二维数组

int[][] arr = {{},{}};

动态初始化

语法:类型[][] [] [] 数组名 = new 类型[大小] [大小]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q3PjjaV1-1654397259791)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649681927471.png)]

动态初始化2

先声明: 类型 数组名 [] [] ;

再定义(开辟空间)数组名 = new 类型[大小] [大小];

动态初始化-列数不确定

一个多维数组中的一维数组可以是不同大小的数组

静态初始化

类型 数组名[] [] = {{值1,值2……},{值1,值2……},{值1,值2……}};

二维数组使用细节和注意事项

  1. 一维数组的声明方式有:

    int [] x 或者 int x[]

  2. 二位数组的声明方式有:

    int[] [] y 或者 int[] y[] 或者 int y[]

  3. 二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。

面向对象(基础)

  1. 单独的定义变量解决
  2. 使用数组解决

java设计者,引入类与对象(OOP),根本原因就是现有的技术,不能完美的解决新的新的需求。

类与对象

  1. 类是抽象的,概念的,代表一类事物,比如人类,……,即它是数据类型。
  2. 对象时具体的,实际的,代表一个具体事物,即 是实例。
  3. 类是对象的模板,对象是类的一个个体,对应一个实例
public class Obiect01 {
	public static void main(String[] args) {
		//使用oop面向对象解决
		Cat catMiMi = new Cat();
		catMiMi.name = "小白";
		catMiMi.age = 4;
		catMiMi.color = "白色";

		Cat catChuChu = new Cat();
		catChuChu.name = "小黑";
		catChuChu.age = 3;
		catChuChu.color = "黑色"; 

		System.out.println("catMiMi是" + catMiMi.name + catMiMi.age + catMiMi.color);
	}
}

//定义一个猫类 cat-> 自定义的数据类型
class Cat{
	//属性
	String name;
	int age;
	String color;
}

对象在内存中存在形式(重要)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XzejlgrM-1654397259791)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649731495564.png)]

属性/成员变量

  1. 成员变量 = 属性 = field(字段)(即 成员变量是用来表示属性的)
  2. 属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)

注意事项和细节

  1. 属性的定义语法同变量 示例:访问修饰符 属性类型 属性名:

    访问修饰符:控制属性的范围有四种访问修饰符:public ,proctected,默认,private

  2. 属性的定义类型可以为任意类型,包含基本类型或者引用类型

  3. 属性如果不赋值,有默认值,规则和数组一致。

创建对象

  1. 先声明再创建

    Cat cat;

    cat = new Cat();

  2. 直接创建

    Cat cat = new Cat();

访问属性

对象名.属性名;

cat.name;

cat.age;

cat.color;

类与对象的内存分配机制(重要)

Person p1 = new Person();
p1.age = 10;
p1.name = "zzj";
Person p2 = p1; //吧p1赋给了p2,让p2指向p1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SdQijVPu-1654397259792)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649733466147.png)]

类的对象的内存分配机制

  1. 栈:一般存放基本数据类型(局部变量)
  2. 堆:存放对象(Cat cat,数组等)
  3. 方法区:常量池(常量,比如字符串),类加载信息

成员方法

基本介绍

在某些情况下,我们要需要定义成员方法(简称方法)。比如人类:除了有一些属性外(年龄,姓名。。)我们人类还有一些行为比如:可以说话、跑步…,这是就要用成员方法才能完成。

public class Method01 {
	//编写一个main方法
	public static void main(String[] args) {
		//方法使用
		//1.不调用不会生效
		//2.先创建一个对象,然后调用方法
	Person p1 = new Person();
	p1.speak();//调用方法
    int returnRes = p1.getSum(10,20); 
	}
} 

class Person {

	String name;
	int age;
	// 方法 (成员方法)
	// 添加speak 成员方法,输出“我是一个好人”
	//1.public 表示方法是公开
	//2.void : 表示方法没有返回值
	//3. speak() : speak是方法名 ()形参列表
	//4.{}方法题,可以写我们要执行的代码
	public void speak() {
		System.out.println("我是一个好人");
	}
	public int getSum(int num1 , int num2) {
        int res = num1 + num2;
        return res;
    }
}

方法的调用机制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M7EFykV6-1654397259793)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649767507089.png)]

public class Method02 {
	public static void main(String[] args) {

		int [][] map = {{0,0,1},{1,1,1},{1,1,3}};
		//使用方法完成输出,创建MyTools类,myTools为对象
		MyTools myTools = new MyTools();
		myTools.printSrr(map);
	}
}

class MyTools {
	//接受二维数组
	public void printSrr(int[][] map) {
		for(int i = 0; i< map.length; i++){
			for(int j = 0; j < map[i].length; j++) {
				System.out.print(map[i][j] + "\t");
			}
			System.out.println();
		}
	}
}

成员方法的定义

public 返回数据类型 方法名 (参数列表){//方法体

​ 语句;

​ return 返回值;

}

注意事项和使用细节

  1. 访问修饰符(作用是控制,方法使用的范围)可选,有四种public,protected,默认,private

  2. 方法最多有一个返回值

public class MethodDetail {
	public static void main(String[] args) {
		AA a = new AA();
		int[] res = a.getSumAudSub(10,2);
		System.out.println(res[0] + " " + res[1]);
	}
}
class AA {
	public int[] getSumAudSub(int n1,int n2) {

		int[] resArr = new int[2];
		resArr[0] = n1 + n2;
		resArr[1] = n1 - n2;
		return resArr;
	}
}
  1. 返回类型可以为任意类型,包含基本类型和引用类型(数组,对象)
  2. 如果方法是void,则方法中可以没有return语句,或者只写return;

方法体

里面不能再定义方法!即方法不能嵌套定义

方法的调用

同一个类中的方法调用:直接调用即可

class A {
 public void print(int n){
 	System.out.println(n);
 }
public void sayOk() {//sayOK调用print
	print(10);
}
}

方法的递归调用

public class Recursion01 {
	public static void main(String[] args) {
		T t1 = new T();
		int sum = t1.test(4);
		System.out.println(sum);
	}
}
class T {
	public int test(int n) {
		if (n == 1) {
			return 1;
		}else {
			return test(n - 1) * n;
		}
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HdnBEqe2-1654397259793)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1649854301027.png)]

递归重要规则

  1. 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
  2. 方法的局部变量是独立的,不会相互影响
  3. 如果方法中使用的事引用类型变量(比如数组),就会共享该引用类型的数据
  4. 递归必须退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死龟了:)
  5. 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将你结果返回给谁,同时方法执行完毕或者返回是,该方法就执行完毕

斐波那契数列

public class fibonacci {
	public static void main(String[] args) {
		Num num01 = new Num();
		System.out.println("当为6 对应的斐波那契数列=" + num01.count(6));
	}
}
class Num {
	public int count(int n) {
		if( n >= 1) {
			if(n == 1 || n == 2) {
			return 1;
		}else {
			return count(n - 1) + count(n-2);
		}
		}else{
			System.out.println("这个数小于1");
			return -1;
	}
}
}

老鼠走迷宫(递归调用)

public class MiGong {
	public static void main(String[] grgs) {
		//思路
		//1.先创建迷宫,用二维数组表示 int[][] map = new int[8][7];
		//2.先归哪个 map 数组的元素值: 0 表示可以走1. 表示障碍物

		int[][] map = new int[8][7];
		//3.将最上面的一行和最下面的一行,全部设置1
		for(int i = 0; i < 7; i++) {
			map[0][i] = 1;
			map[7][i] = 1;
		}

		//4.将最左边与最右边的一列,全部设置为1
		for(int i = 0; i < 7; i++) {
			map[i][0] = 1;
			map[i][6] = 1;
		}
		map[3][1] = 1;
		map[3][2] = 1;


		//输出当前的地图
		System.out.println("====当前地图情况=====");
		for(int i = 0; i < map.length; i++) {
			for(int j = 0; j < map[i].length; j++) {
				System.out.print(map[i][j] + " ");//输出一行
			}
			System.out.println();
		}

		//使用findWay给老鼠找路
		T t1 = new T();
		t1.findWay(map,1,1);

		System.out.println("\n====找路的情况如下====");

		for(int i = 0; i < map.length; i++) {
			for(int j = 0; j < map[i].length; j++) {
				System.out.print(map[i][j] + " ");//输出一行
			}
			System.out.println();
		}
	}
}

class T {
	//使用递归回溯的思路来解决老鼠出迷宫
	//1.findWay方法就是专门来找出迷宫的路径
	//2.如果找到,就返回true,否则返回false
	//3.map 就是二维数组,即迷宫
	//4.i,j就是老鼠的位置,初始化的位置为(1,1)
	//5.因为我们是递归的找路,所以为们先规定map数组的各个值的含义
	//   0表示可以走  1表示路障 2表示可以走 3表示走过,但是走不通
	//6.当map[6][5] = 2 就说明找到通路,否则继续找
	//7.先确定老鼠找路策略 下,右,上,左
	public boolean findWay(int[][] map, int i , int j) {
		
		if(map[6][5] == 2) {//说明已经找到
			return true;
		}else{
			if(map[i][j] == 0) {//当前这个位置0,说明表示可以走
				//我们假定可以走通
				map[i][j] = 2;
				//使用找路策略,来确定该位置是否真的可以走通
				//下,右,上,左
				if(findWay(map, i + 1, j)) {//先走下
					return true;
				} else if(findWay(map,i , j + 1)) {//右
					return true;
				} else if(findWay(map, i - 1, j)){//上
					return true;
				}else if(findWay(map, i , j + 1)){//左
					return true;
				} else {
					map[i][j] = 3;
					return false;
				}
			} else { //map[i][j] 1,2,3
					return false;
		  	}
		}
	}
}

汉诺塔

public class HanoiTower {
	public static void main(String[] args) {
		Tower tower = new Tower();
		tower.move( 5, 'A', 'B', 'c');

	}
}

class Tower {
	//方法
	//num 表示要移动个数,a,b,c分别代表A塔,B塔,C塔
	public void move(int num, char a, char b,char c) {
		//如果只用一个盘 num = 1
		if(num == 1) {
			System.out.println(a + "->" + c);
		} else {
			//如果有多个盘,可以看成两个,最下面的和上面的所有盘(num-1)
			//(1)先移动上面所有的盘到 b,借助 c
			move(num - 1, a, c, b);
			//(2)把最下面的这个盘,移动到c
			System.out.println(a + "->" + c);
			//(3)再把b塔的所有盘,移动到c,借助a
			move(num - 1, b, a, c);
		}
	}
}

八皇后

方法重载(OverLoad)

基本介绍

java 中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!

比如:System.out.println( ); out是PrintStream类型

重载的好处

1)减轻了起名的麻烦

2)减轻了记名的麻烦

细节

  1. 方法名:必须相同
  2. 参数列表:必须不同(参数类型或个数或顺序,至少有一样不同,参数名无要求)
  3. 返回类型:无要求

可变参数

基本概念

java允许将同一个类中多个同名同功能参数个数不同的方法,封装成一个方法。

就可以通过可变参数实现

基本语法

访问修饰符 返回值 方法名(类型数据 形参名){ }

public class VarParameter01 {
	public static void main(String[] args) {
		HspMethod hm = new HspMethod();
		System.out.println(hm.sum(1,2,3,4,5));
	}
}
class HspMethod {
	//1.int... 表示接受的事可变参数,类型是int,既可以接受多个int(0-多)
	//2.使用可变参数时,可以当做数组来使用 即 nums 可以当做数组
	public int sum(int... nums) {
		int sum = 0;
		for( int i = 0 ; i < nums.length; i++ ) {
			sum += nums[i];
		}
		return sum;
	}
}

细节

  1. 可变参数的实参可以为0个或任意多个
  2. 可变参数的实参可以为数组(前后同类型)
  3. 可变参数的本质就是数组
  4. 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
  5. 一个形参列表中只能出现一个可变参数

作用域

  1. 在java编程中,主要的变量就是属性(成员变量)和局部变量

  2. 我们说的局部变量一般是指在成员方法中定义的变量

  3. java中作用域的分类

    全局变量:就是属性,作用域为整个类体

    局部变量:也就是除了属性之外的其他变量,作用域为定义他的代码块中

  4. 全局变量(属性)可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能使用,因为没有默认值。

细节

  1. 属性和局部变量可以重名,访问时遵循就近原则

  2. 在同一个作用域中,比如在同一个成员方法中,两份局部变量,不能重名

  3. 属性生命周期较长,伴随着对象的创建而创建,办税这对象的死亡而死亡,局部变量,生命周期较短,办税这它的代码块的执行而创建,伴随着代码块的结束而死亡,即在一次方法调用过程中

  4. 作用域不同

    全局变量:可以被本类使用,或其它类使用(通过对象调用)

    局部变量:只能在本类中对用的方法中使用

  5. 修饰符不同

    全局变量/属性可以加修饰符

    全局变量不可以加修饰符

构造方法/构造器

介绍

是类的一种特殊的方法,它的主要作用是完成对新对象的初始化

特点

  1. 方法名和类名相同
  2. 没有返回值
  3. 在创建对象时,系统会自动的调用该类的构造器完成对对象的初始化

基本句法

【修饰符】方法名(形参列表){ 方法体;}

说明

  1. 构造器的修饰符可以默认 也可public protected private
  2. 构造器没有返回值
  3. 方法名和类名字必须一样
  4. 参数列表和成员方法一样的规则
  5. 构造器的调用系统完成

例子

public class Constructor01 {
	public static void main(String[] args) {
		Person p1 = new Person( "smith", 80);
		System.out.println("p1的信息如下:");
		System.out.println("p1对象name=" + p1.name);
		System.out.println("p1对象age=" + p1.age);
	}
}

class Person {

	String name;
	int age;

	public Person( String pName, int pAge) {
		System.out.println("构造器被调用^-^");
		name = pName;
		age = pAge;
	} 
}

细节

  1. 一个类可以定义多个不同的构造器,即构造器重载

  2. 构造器名和类名要相同

  3. 构造器没有返回值

  4. 构造器是完成对象的初始化,并不是创建对象

  5. 再创建对象时,系统自动的调用该类的构造方法

    (不能 p2.Person(); )

  6. 如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器) 反编译 javap

  7. 一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下 即:Person(){} (这点很重要)

this关键字

java虚拟机会给每个对象分配 this,代表当前对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mKIWu1St-1654397259794)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1650695880547.png)]

小结

那个对象调用,this就代表那个对象

细节

  1. this关键字可以用来访问本类的属性,方法,构造器
  2. this用于区分当前类的属性和局部变量
  3. 访问成员方法的语句:this.方法名(参数列表);
  4. 访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另一个构造器,必须放置第一条语句)
  5. this不能在类定义的外部使用,只能在类定义的方法中使用

练习

public class TestPerson {
	public static void main(String[] args) {
		Person p1 = new Person("mary", 20);
		Person p2 = new Person("mary", 20);
		System.out.println(p1.compareTo(p2));
	}
}

class Person {
	String name;
	int age;
	//构造器
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	//compareTo比较方法
	public boolean compareTo(Person p) {

		// if(this.name.equals(p.name) && this.age == p.age) {
		// 	return ture;
		// }else {
		// 	return false;
		// }

		return this.name.equals(p.name) && this.age == p.age;
	}
}

idea 使用

IDEA快捷键

  1. 删除当行 Ctrl+D
  2. 复制当前行 ctrl+alt+向下光标
  3. 补全代码 alt + /
  4. 导入该行需要的类 alt + enter
  5. 快速格式化代码 ctrl + shift + L
  6. 快速运行程序 自定义 alt + R
  7. 生成构造器 alt + insert
  8. 查看一个类的层级关系 ctrl + H 【提高开发效率】
  9. 将光标放在一个方法上,输入ctrl + B 可以选择定位到哪个类方法 【学继承后,非常有用】
  10. 自动的分配变量名 , 通过 在后面.var

模板/自定义模板

包的本质,实际上就是创建不同的文件夹来保存类文件

作用

  1. 区分相同名字的类
  2. 当类很多时,可以很好的管理类
  3. 控制访问范围

基本语法

package com.hspedu;

说明

  1. package 关键字,表示打包。
  2. com.hspedu:表示包名

命名

命名规则

只能包含数字,字母,下划线,小圆点.,但是不能用数字开头,不能是关键字或保留字

命名规范

一般是小写字母+小圆点一般是

com.公司名.项目名.业务模块名

例:com.hspedu.oa.model;

常用包

一个包下,包含很多的类,java中常用的包有:

java.lang.* //lang包是基本包,默认引入,不需要再引用

java.util.* //util包,系统提供的工具包,工具类,使用Scanner

java.net.* //网络包,网络开发

java.awt.* //是做java的页面开发,GUI

引入包

语法: import 包;

例: import java.util.Scanner;

​ import.java.util.*;

细节

  1. package的作用是声明当前类所在的包,需要放在类的最上面,一个类最多只有一句package
  2. import指令 位置放在 package的下面,在类定义前面,可以有多句且没有顺序要求

访问修饰符

基本介绍

java提供四种访问控制符号,用于控制方法和属性(成员变量)的访问权限(范围):

  1. 公开级别:用public修饰,对外公开
  2. 受保护级别:用protected修饰,对子类和同一个包中的类公开
  3. 默认级别:没有修饰符,向同一个包的类公开
  4. 私有级别:用private修饰,只有类本身可以访问,不对外公开

范围

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dyjvaFTt-1654397259794)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1650765752549.png)]

注意事项

  1. 修饰符可以用来修饰类中的属性,成员方法以及类
  2. 只有默认的和public才能修饰类,并且遵循上述访问权限特点
  3. 成员方法的访问规则和属性完全一样

面向对象(中级)

封装(encapsulation)

封装介绍

就是把抽象出来的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作[方法],才能对数据进行操作。

理解与好处

  1. 隐藏实现细节 方法<–调用
  2. 可以对数据进行验证,保证安全合理

实现步骤

  1. 将属性进行私有化 private【不能直接修改属性】
  2. 提供一个公共的(public)set方法,用于对属性判断并赋值
public void setXxx(类型 参数名) {
    //加入数据验证的业务逻辑
    属性 = 参数名;
}
  1. 提供一个公共的(public)get方法,用于获取属性的

    public XX getXxx() { //权限判断
    	return xx;
    }
    

继承

基本介绍

继承可以解决代码的复用,让我们你的编程更加靠近人类思维,当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出来父类,在父类这中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需用通过 extends 来生明继承父类即可。

基本语法

class 子类 extends 父类 {
		}
  1. 子类就会自动拥有父类定义的属性和方法
  2. 父类又叫 超类,基类
  3. 子类又叫派生类

示意图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VtwfoewM-1654397259795)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1650966097260.png)]

细节

  1. 子类继承了所有的属性和方法,但是私有属性和方法不能再子类直接访问,要通过公共的方法去访问
  2. 子类必须调用父类的构造器,完成父类的初始化
  3. 当创建子类的对象时,不管使用子类的那个构造器,默认情况下总回去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用的那个构造器完成父类的初始化工作,否则,编译不会通过
  4. 如果希望指定去调用父类的某个构造器,则显式的调用一下;super(参数列表)
  5. super在使用时,需要放在构造器第一行
  6. super()和this() 都只能放在构造器的第一行,因此这两个方法不能共存在一个构造器
  7. java所有的类都是Object类的子类
  8. 父类构造器的调用不限于直接父类!将一值往上追溯直接Object类(顶级父类)
  9. 子类最多只能继承一个父类(指直接继承),即java中是 单继承机制
  10. 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系

本质

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NtCxBxOu-1654397259795)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1651050311254.png)]

super

基本介绍

super代表父类的引用,用于访问父类的属性,方法,构造器

基本语法

  1. 访问父类的属性,但不能访问父类的private属性

    super.属性名;

  2. 访问父类的方法,不能访问父类的private方法

    super.方法名(参数列表);

  3. 访问父类的构造器:

    super(参数列表);只能放在构造器的第一句,只能出现一句!

便利/细节

  1. 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)
  2. 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super,this,直接访问时一样的的效果!
  3. super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类中都有同名的成员,使用super访问遵循就近原则。A->B->C

方法重写/覆盖(override)

注意事项

  1. 子类的方法名的参数,方法名称,要和父类方法的参数,方法名称完全一样。
  2. 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类
  3. 子类方法不能缩小父类方法的访问权限

多态

多(多种)态(状态)基本介绍

方法或者对象具体有多种形态。是面向对象的三大特征,多态是建立在封装和继承基础上的。

对象的多态(核心,重点)

  1. 一个对象的编译类型和运行类型可以不一致
  2. 编译类型在定义对象时,就确定了,不能改变
  3. 运行类型是可以变化的
  4. 编译类型看定义时 = 号 的左边 , 运行类型看 = 号的 右边
package poly_.objectpoly_;

public class PolyObject {
    public static void main(String[] args) {
        //体验对象多态的特点
        //animal 编译类型就是 Animal,运行类型 Dog
        Animal animal = new Dog();
        //因为运行时,执行到该行时,animal运行类型是Dog,所以cry就是Dog的cry
        animal.cry();//小狗汪汪叫

        //animal 编译类型 Animal , 运行类型 Cat
        animal = new Cat();
        animal.cry();  //小猫喵毛
    }
}

小案例

主人喂动物

main类

package com.zzj.poly;

public class poly01 {
    public static void main(String[] args) {
        Master tom = new Master("汤姆");
        Dog wangwang = new Dog("大黄");
        Bone bone = new Bone("排骨");

        tom.food(wangwang ,bone );

        Cat mimi = new Cat("咪咪");
        Fish rishfish = new Fish("黄花鱼");

        tom.food(mimi , rishfish);

        Pig pig = new Pig("忍者");
        Rice rice = new Rice("高贵的五常大米,主人都吃不起的那种。");

        tom.food(pig , rice);
    }
}

主人类

package com.zzj.poly;

public class Master {
    private String name;

    public Master(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void food(Animal animal , Food food) {
        System.out.println(name + "给" + animal.getName() + "喂" + food.getName());
    }

//    主人给小狗喂骨头
//    public void food(Dog dog , Bone bone) {
//        System.out.println(name + "给" + dog.getName() + "喂" + bone.getName());
//    }
}

动物类

package com.zzj.poly;

public class Food {
    private String name;

    public Food(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

狗类

package com.zzj.poly;

public class Dog extends Animal{
    public Dog(String name) {
        super(name);
    }
}

猫类

package com.zzj.poly;

public class Cat extends Animal{
    public Cat(String name) {
        super(name);
    }
}

猪类

package com.zzj.poly;

public class Pig extends Animal{
    public Pig(String name) {
        super(name);
    }
}

食物类

package com.zzj.poly;

public class Food {
    private String name;

    public Food(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

骨头类

package com.zzj.poly;

public class Bone extends Food{
    public Bone(String name) {
        super(name);
    }
}

鱼类

package com.zzj.poly;

public class Fish extends Food{
    public Fish(String name) {
        super(name);
    }
}

米饭类

package com.zzj.poly;

public class Rice extends Food{
    public Rice(String name) {
        super(name);
    }
}

细节

多态的前提条件

两个对象(类)存在继承关系

多态的向上转型

  1. 本质:父类的引用指向了子类的对象

  2. 语法:父类类型 引用名 = new 子类类型();

  3. 特点:编译类型看看左边,运行类型看右边

    可以调用父类中的所有成员(需要遵守访问权限),

    不能调用子类中的特有成员;

    最终运行效果看子类的具体实现!

规则

  1. 可以调用父类中的所有成员(需遵守访问权限)
  2. 但是不能调用子类的特有成员
  3. 因为编译阶段,能调用那些成员,是由编译类型来决定的
  4. 最终运行效果看子类(运行类型)的具体实现,及调用方法时,按照从子类(运行类型)开始查找方法,然后调用,规则为前面的调用规则。

多态的向下转型

  1. 语法:子类类型 引用名 = (子类类型) 父类引用;
  2. 只能强转的引用, 不能强转父类的对象
  3. 要求父类的引用必须指向的是当前目标类型的对象
  4. 当向下转型后,可以调用子类类型中的所有的成员
// cat 的编译类型 Cat, 运行类型是 Cat
Cat cat = (Cat) animal;
cat.catchMouse();

注意事项

  1. 属性没有重写之说!,属性的值要看编译类型
  2. instanceOf比较操作符,用于判断对象的类型是否是为XX类型或XX类型的子类
BB bb = new BB();
System.out.println(bb instanceof BB);//true
System.out.println(bb instanceof AA);//true

AA aa = new BB(); 
System.out.println(aa instanceof BB);//true
System.out.println(aa instanceof AA);//true

Object obj = new Object();
System.out.println(obj instanceof AA);//false
String str = "hello";
System.out.println(str instanceof AA);//错误
System.out.println(str instanceof Object);//true

class AA {} //父类
class BB extends AA {}//子类

小测试

public static void main(Stringl] args){
double d = 13.4; //ok
long l = (long)d; //ok
System.out.println(:; 1/13int in = 5; l/ok
boolean b = (boolean)in;//不对,boolean -> int
Object obj = "Hello"; //可以,向上转型
String objStr = (String)obj;//可以,向下转型
System.out.println(objStr); // hello
Object objPri = new Integer(5)://可以,向上转型
String str = (String)objPri;//错误,指向Integer的父类引用,转成String
Integer str1 =(Integer)objPri;//可以,向下转型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zW9x6cCB-1654397259796)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1654262459738.png)]

动态绑定机制(非常非常重要)

1.当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
2.当调用对象属性时,没有动态绑定机制,哪里声明.那里使用

多态应用

多态数组

person类

package com.zzj.plolyarr;

public class person {//父类
    private String name;
    private int age;

    public person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String say() { //返回名字与年龄
        return name + "\t" + age;
    }

}

PloyArray类

package com.zzj.plolyarr;

public class PloyArray {
    public static void main(String[] args) {

        person[] peoples = new person[5];
        peoples[0] = new person("java" , 12);
        peoples[1] = new Student("java" , 13 , 20);
        peoples[2] = new Student("python" , 12 ,100);
        peoples[3] = new Teacher("java" , 77 , 2000);
        peoples[4] = new Teacher("java" , 82 , 12000);

        //循环遍历多态数组,调用say()
        for (int i = 0; i < peoples.length; i++) {
            System.out.println(peoples[i].say());//动态绑定机制
        }
    }
}

Student类

package com.zzj.plolyarr;

public class Student extends person {
    private int score;

    public Student(String name, int age, int score) {
        super(name, age);
        this.score = score;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public String say() {
        return super.say() + " 成绩=" + score;
    }
}

Teacher类

package com.zzj.plolyarr;

public class Teacher extends person{
    private int salary;

    public Teacher(String name, int age, int salary) {
        super(name, age);
        this.salary = salary;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    @Override
    public String say() {
        return super.say() + " 薪水=" + salary;
    }
}

改进版

package com.zzj.plolyarr;

public class PloyArray {
    public static void main(String[] args) {

        person[] peoples = new person[5];
        peoples[0] = new person("java" , 12);
        peoples[1] = new Student("c" , 13 , 20);
        peoples[2] = new Student("python" , 12 ,100);
        peoples[3] = new Teacher("c++" , 77 , 2000);
        peoples[4] = new Teacher("go" , 82 , 12000);

        //循环遍历多态数组,调用say()
        for (int i = 0; i < peoples.length; i++) {
            System.out.println(peoples[i].say());//动态绑定机制
            if (peoples[i] instanceof Student) { //判定peoples[i] 的运行内存是不是 Student
                Student student = (Student) peoples[i];//向下转型
                student.study();
                //((Student)peoples[i]).study();
            } else if (peoples[i] instanceof Teacher) {
                ((Teacher)peoples[i]).teach();
            }else if (peoples[i] instanceof person){
//                System.out.println("类型有误。");
            }else {
                System.out.println("类型有误。");
            }
        }
    }
}

package com.zzj.plolyarr;

public class person {//父类
    private String name;
    private int age;

    public person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String say() { //返回名字与年龄
        return name + "\t" + age;
    }
    public void study() {
        System.out.println("学生" + getName() + "正在学java。");
    }

}

package com.zzj.plolyarr;

public class Student extends person {
    private int score;

    public Student(String name, int age, int score) {
        super(name, age);
        this.score = score;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public String say() {
        return super.say() + " 成绩=" + score;
    }
    public void study() {
        System.out.println("学生" + getName() + "正在学java。");
    }
}

package com.zzj.plolyarr;

public class Teacher extends person{
    private int salary;

    public Teacher(String name, int age, int salary) {
        super(name, age);
        this.salary = salary;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    @Override
    public String say() {
        return super.say() + " 薪水=" + salary;
    }

    public void teach() {
        System.out.println(("老师" + getName() + "正在教java。"));
    }
}

多态参数

方法定义的形参类型为父类类型,实参类型允许为子类类型。

PloyParameter主类

package com.zzj.polparameter;

import com.zzj.poly.Master;

public class PloyParameter {
    public static void main(String[] args) {
        Worker zs = new Worker("张三", 3000);
        Manager zz = new Manager("小张", 4000, 1000);
        PloyParameter ployParameter = new PloyParameter();
        ployParameter.showEmpAnnual(zs);
        ployParameter.showEmpAnnual(zz);

        ployParameter.testWork(zs);
        ployParameter.testWork(zz);
    }
    public void  showEmpAnnual(Employee e) {
        System.out.println(e.getAnnual());
    }
    public void testWork(Employee e) {
        if(e instanceof Worker) {
            ((Worker)e).work();
        } else if (e instanceof Manager) {
            ((Manager)e).manage();
        }else {
            System.out.println("不做处理");
        }
    }
}

Employee父类

package com.zzj.polparameter;

public class Employee {
    private String name;
    private double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
    public double getAnnual() {
        return 12 * salary;
    }
}

Manager经理类

package com.zzj.polparameter;

public class Manager extends Employee{
    private double bonus;

    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
    public void manage() {
        System.out.println("经理:" + getName() + "正在管理。");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual() + bonus;
    }
}

Worker工人类

package com.zzj.polparameter;

public class Worker extends Employee{
    public Worker(String name, double salary) {
        super(name, salary);
    }
    public void work() {
        System.out.println("普通员工:" + getName() + "正在工作");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual();
    }
}

Object类详解

equals方法

== 和 equals 的对比

== 比较运算符

  1. ==:既可以判断基本类型,也可以判断引用类型
  2. ==:如果判断基本类型,判断的是值是否相等。
  3. ==:如果判断引用类型,判断的是地址是否相等,即判定是否是同一个对象

equals方法

  1. equals:是Object类中的方法,只能判断引用类型。
  2. 默认判断的是地址是否相等,子类中的往往重写该方法,用于判断内容是否相等。

String equals jdk原码

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
小练习

判断两个Person方法的内容是否相等。

package com.zzj.equals;

public class EqualsExercise01 {
    public static void main(String[] args) {
        Person person1 = new Person("张正杰", 21, '男');
        Person person2 = new Person("张正杰", 21, '男');

        System.out.println(person1.equals(person2));
    }
}
class Person {
    private String name;
    private int age;
    private char gender;

    public Person(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    @Override
    public boolean equals(Object obj) {
        //判断如果比较的两个对象是同一个对象,则直接返回ture
        if (this == obj) {
            return true;
        }
        //类型的判断
        if (obj instanceof Person) {
            //进行向下转型,我需要得到 obj 的所有属性
            Person p = (Person) obj;
            return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;

        }
        return false;
    }
}

hashCode()

  1. 提高具有哈希结构的容器的效率!
  2. 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!
  3. 两个引用,如果指向的是不同对象,则哈希值是不一样的
  4. 哈希值主要要根据地址号来的!,不能完全将哈希值等价于地址。
  5. 后面在集合,中hashCode 如果需要的话,也会重写

toString方法

基本介绍

默认返回:全类名(包名+类名)+@+哈希值的十六进制,子类往往重写toString方法,用于返回对象的属性信息

重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式。

当直接输出一个对象时,toString方法会被默认的调用。

//object的toString()源码
//(1)getClass().getName()类的全类名(包名+类名)
//(2)Integer.toHexString(hashCode())将对象的hashCode值转成16进制字符串
public String toString() {
return getClass() .getName() +"@" + Integer.toHexString(hashCode());
}

finalize方法

  1. 当对象被会收时,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作
  2. 什么时候被回收:当某个对象没有任何引用时,则jvm就会认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象前,会先调用finalize方法。
  3. 垃圾回收机制的调用,是由系统来决定,也可以通过System.gc()主动触发垃圾回收机制。

零钱通

过程编程

SmallChangeSys

package com.zzj.smallchange;


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import java.util.logging.SimpleFormatter;

public class SmallChangeSys {
    //化繁为简
    //1.先完成显示菜单,并可以选择菜单,给出对应提示
    //2.完成零钱通明细
    //3.完成消费入账
    //4.完成消费
    //5.完成完善退出
    //6.在消费入账和消费时,判断金额是否合理,并给出相应提示。


    public static void main(String[] args) {
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        String key = "";

        //1.零钱通明细
        //(1)吧收益入账和消费,保存到数组,(2)可以使用对象(3)简单的话可以使用String拼接
        String details = "-----------------零钱通明细-----------------";

        //2.消费入账
        //定义新的变量
        double money = 0;
        double banlans = 0;
        Date date = null; //表示日期
        SimpleDateFormat sqf = new SimpleDateFormat("yyyy-MM-dd HH-mm");//可以用于日期格式化

        //3.消费
        //定义新的变量,保存消费原因
        String note = "";


        do {

            System.out.println("\n-----------------零钱通菜单-----------------");
            System.out.println("\t\t\t\t1 零钱通明细");
            System.out.println("\t\t\t\t2 收益入账");
            System.out.println("\t\t\t\t3 消费");
            System.out.println("\t\t\t\t4 退出");
            System.out.print("请选择(1-4):");

            key = scanner.next();

            //使用switch,分支控制。
            switch (key){
                case "1" :
                    System.out.println(details);
                    break;
                case "2" :
                    System.out.println("收益入账金额:");
                    money = scanner.nextDouble();
                    //找出不正确的金额条件,然后给出提示,直接break
                    if (money <= 0) {
                        System.out.println("收益入账金额需大于0!");
                        break;
                    }
                    banlans += money;
                    //拼接入账信息到 details
                    date = new Date();
                    details += "\n收益入账\t" + money + "\t" +sqf.format(date) + "\t" + banlans;
                    break;
                case "3" :
                    System.out.println("消费金额:");
                    money = scanner.nextDouble();
                    //找出消费金额不正确的情况
                    if (money <= 0) {
                        System.out.println("消费金额需大于0!");
                        break;
                    }else if (money > banlans) {
                        System.out.println("消费金额不能大于所存金额" + banlans + "!");
                        break;
                    }
                    System.out.println("消费说明:");
                    note = scanner.next();
                    banlans -= money;
                    //拼接消费信息
                    date = new Date();
                    details += "\n" + note + "\t-" + money + "\t" +sqf.format(date) + "\t" + banlans;
                    break;
                case "4" :
                    //输入 y/n 确认退出。
                    //1.定义变量 choice ,接受用户的输入
                    //2.使用 while + break ,来处理输入的 y / n
                    //3.退出while后,再判断choice是y 还是 n,是否退出

                    String choice = "";
                    while(true){
                    System.out.println("你确定要退出吗?y/n");
                    choice = scanner.next();
                    if ("y".equals(choice) || "n".equals(choice)) {
                        break;
                    }
                }
                    //退出while后,进行判断
                    if ("y".equals(choice)){
                        loop = false;
                    }
                    break;
                default:
                    System.out.println("输入有误!请重新选择。");
            }

        }while (loop);

        System.out.println("-----------------退出了零钱通系统-----------------");
    }
}

面向对象编程

SmallChangeSysApp

package com.zzj.smallchange.smallchangeOOP;

/**
 * 这里直接调用SmallChangeSysOOP对象,显示主菜单即可
 */
public class SmallChangeSysApp {
    public static void main(String[] args) {
        new SmallChangeSysOOP().mainMenu();
    }
}

SmallChangeSysOOP

package com.zzj.smallchange.smallchangeOOP;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/**
 * 该类是完成零钱通各项功能的类
 * 使用OOP
 * 将各个功能对一个方法。
 */
public class SmallChangeSysOOP {

    //属性..
    boolean loop = true;
    Scanner scanner = new Scanner(System.in);
    String key = "";

    //1.零钱通明细
    //(1)吧收益入账和消费,保存到数组,(2)可以使用对象(3)简单的话可以使用String拼接
    String details = "-----------------零钱通明细-----------------";

    //2.消费入账
    //定义新的变量
    double money = 0;
    double banlans = 0;
    Date date = null; //表示日期
    SimpleDateFormat sqf = new SimpleDateFormat("yyyy-MM-dd HH-mm");//可以用于日期格式化

    //3.消费
    //定义新的变量,保存消费原因
    String note = "";


    //完成显示菜单,并可以选择
    public void mainMenu() {
        do {

            System.out.println("\n-----------------选择零钱通菜单(OOP)-----------------");
            System.out.println("\t\t\t\t1 零钱通明细");
            System.out.println("\t\t\t\t2 收益入账");
            System.out.println("\t\t\t\t3 消费");
            System.out.println("\t\t\t\t4 退出");
            System.out.print("请选择(1-4):");

            key = scanner.next();

            //使用switch,分支控制。
            switch (key){
                case "1" :
                    this.detail();
                    break;
                case "2" :
                    this.inocme();
                    break;
                case "3" :
                    this.pay();
                    break;
                case "4" :
                    this.exit();
                    break;
                default:
                    System.out.println("输入有误!请重新选择。");
            }

        }while (loop);
    }

    //完成零钱通明细
    public void detail() {
        System.out.println(details);
    }

    //完成收入入账
    public void inocme() {
        System.out.println("收益入账金额:");
        money = scanner.nextDouble();
        //找出不正确的金额条件,然后给出提示,直接break
        if (money <= 0) {
            System.out.println("收益入账金额需大于0!");
            return; //退出方法,不在执行后面的
        }
        banlans += money;
        //拼接入账信息到 details
        date = new Date();//获取当前时间
        details += "\n收益入账\t" + money + "\t" +sqf.format(date) + "\t" + banlans;
    }

    //完成消费
    public void pay() {
        System.out.println("消费金额:");
        money = scanner.nextDouble();
        //找出消费金额不正确的情况
        if (money <= 0) {
            System.out.println("消费金额需大于0!");
            return;
        }else if (money > banlans) {
            System.out.println("消费金额不能大于所存金额" + banlans + "!");
            return;
        }
        System.out.println("消费说明:");
        note = scanner.next();
        banlans -= money;
        //拼接消费信息
        date = new Date();
        details += "\n" + note + "\t-" + money + "\t" +sqf.format(date) + "\t" + banlans;
    }

    //完成退出
    public void exit() {
        //输入 y/n 确认退出。
        //1.定义变量 choice ,接受用户的输入
        //2.使用 while + break ,来处理输入的 y / n
        //3.退出while后,再判断choice是y 还是 n,是否退出

        String choice = "";
        while(true){
            System.out.println("你确定要退出吗?y/n");
            choice = scanner.next();
            if ("y".equals(choice) || "n".equals(choice)) {
                break;
            }
        }
        //退出while后,进行判断
        if ("y".equals(choice)){
            loop = false;
        }
    }
}

简易银行业务逻辑

要求:

  1. 类ChekingSccount对每次存款和取款都收取1手续费

  2. 扩展前一个练习的BankAccount类,新类SavingsAccoun每个月都有利息产生,(earnMonthlyLnterest方法被调用)并且有每月三次免手续费的存款或取款,在earnMonthlyLnterest方法中重置交易记录

HomeWork08

package com.zzj.practiseOOP.homework08;

import java.util.Scanner;

public class HomeWork08 {
    public static void main(String[] args) {
//        CheckingAccount checkingAccount = new CheckingAccount(1000);
//        checkingAccount.deposit(10);
//        checkingAccount.withdraw(50);
//        System.out.println(checkingAccount.getBalance());
        SavingsAccount savingsAccount = new SavingsAccount(1000);
        savingsAccount.deposit(100);
        savingsAccount.deposit(100);
        savingsAccount.deposit(100);
        savingsAccount.withdraw(1000);
        System.out.println(savingsAccount.getBalance());

        //月初,定时器自动调用一下 earnMonthlyInterest
        savingsAccount.warnMonthlyInterest();
        System.out.println(savingsAccount.getBalance());



    }
}

BankAccount

package com.zzj.practiseOOP.homework08;

public class BankAccount {
    private double balance;

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public BankAccount(double initialBalance) {
        this.balance = initialBalance;
    }

    public void deposit(double amount) {//存款
        balance += amount;
    }

    public void withdraw(double amount) {//取款
        balance -= amount;
    }

}

CheckingAccount

package com.zzj.practiseOOP.homework08;

public class CheckingAccount extends BankAccount{
    public CheckingAccount(double initialBalance) {
        super(initialBalance);
    }

    @Override
    public void deposit(double amount) {//存款
        //存款业务费1
        super.deposit(amount - 1  );
    }

    @Override
    public void withdraw(double amount) {//取款
        //取款业务费1
        super.withdraw(amount + 1);
    }
}

SavingsAccount

package com.zzj.practiseOOP.homework08;

/**
 * 每月都有利息
 * 并且每月有三册慢手续费(存款或取款)在earnMonthlyInterest方法中重置交易计数
 */
public class SavingsAccount extends BankAccount {
    private int count = 3;
    private double rate = 0.01;

    public SavingsAccount(double initialBalance) {
        super(initialBalance);
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public double getRate() {
        return rate;
    }

    public void setRate(double rate) {
        this.rate = rate;
    }

    @Override
    public void deposit(double amount) {//存款
        //判断是否是可以免手续费,如果不免需缴纳1手续费
        if (count > 0) {
            super.deposit(amount);
            count--;
        } else {
            super.deposit(amount - 1);
        }
    }

    @Override
    public void withdraw(double amount) {//取款
        //判断是否是可以免手续费,如果不免需缴纳1手续费
        if (count > 0) {
            super.withdraw(amount);
            count--;
        } else {
            super.withdraw(amount + 1);
        }

    }
    public void warnMonthlyInterest() {//每月初,统计上个月利息,同时将count=3
        count = 3;
        super.deposit(getBalance() * rate);
    }
}

HashMap

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。

HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。

HashMap 是无序的,即不会记录插入的顺序。

HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

类型

基本类型引用类型
booleanBoolean
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter

语法

import java.util.HashMap;

HashMap<Integer, String> Sites = new HashMap<Integer, String> ();

添加元素

HashMap 类提供了很多有用的方法,添加键值对(key-value)可以使用 put() 方法:

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        System.out.println(Sites);
    }
}
{1=Google, 2=Runoob, 3=Taobao, 4=Zhihu}

访问元素

我们可以使用 get(key) 方法来获取 key 对应的 value:

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        System.out.println(Sites.get(3));
    }
}
Taobao

删除元素

我们可以使用 remove(key) 方法来删除 key 对应的键值对(key-value):

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        Sites.remove(4);
        System.out.println(Sites);
    }
}
{1=Google, 2=Runoob, 3=Taobao}

删除所有键值对(key-value)可以使用 clear 方法:

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        Sites.clear();
        System.out.println(Sites);
    }
}
{}

计算大小

如果要计算 HashMap 中的元素数量可以使用 size() 方法:

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        System.out.println(Sites.size());
    }
}
4

迭代HashMap

可以使用 for-each 来迭代 HashMap 中的元素。

如果你只想获取 key,可以使用 keySet() 方法,然后可以通过 get(key) 获取对应的 value,如果你只想获取 value,可以使用 values() 方法。

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        // 输出 key 和 value
        for (Integer i : Sites.keySet()) {
            System.out.println("key: " + i + " value: " + Sites.get(i));
        }
        // 返回所有 value 值
        for(String value: Sites.values()) {
          // 输出每一个value
          System.out.print(value + ", ");
        }
    }
}
key: 1 value: Google
key: 2 value: Runoob
key: 3 value: Taobao
key: 4 value: Zhihu
Google, Runoob, Taobao, Zhihu,

java HashMap 方法

方法描述
clear()删除 hashMap 中的所有键/值对
clone()复制一份 hashMap
isEmpty()判断 hashMap 是否为空
size()计算 hashMap 中键/值对的数量
put()将键/值对添加到 hashMap 中
putAll()将所有键/值对添加到 hashMap 中
putIfAbsent()如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。
emove()删除 hashMap 中指定键 key 的映射关系
containsKey()检查 hashMap 中是否存在指定的 key 对应的映射关系。
containsValue()检查 hashMap 中是否存在指定的 value 对应的映射关系。
replace()替换 hashMap 中是指定的 key 对应的 value。
replaceAll()将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
get()获取指定 key 对应对 value
getOrDefault()获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
forEach()对 hashMap 中的每个映射执行指定的操作。
entrySet()返回 hashMap 中所有映射项的集合集合视图。
keySet()返回 hashMap 中所有 key 组成的集合视图。
values()返回 hashMap 中存在的所有 value 值。
merge()添加键值对到 hashMap 中
compute()对 hashMap 中指定 key 的值进行重新计算
computeIfAbsent()对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中
computeIfPresent()对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。

values() 方法。

// 引入 HashMap 类      
import java.util.HashMap;

public class RunoobTest {
    public static void main(String[] args) {
        // 创建 HashMap 对象 Sites
        HashMap<Integer, String> Sites = new HashMap<Integer, String>();
        // 添加键值对
        Sites.put(1, "Google");
        Sites.put(2, "Runoob");
        Sites.put(3, "Taobao");
        Sites.put(4, "Zhihu");
        // 输出 key 和 value
        for (Integer i : Sites.keySet()) {
            System.out.println("key: " + i + " value: " + Sites.get(i));
        }
        // 返回所有 value 值
        for(String value: Sites.values()) {
          // 输出每一个value
          System.out.print(value + ", ");
        }
    }
}
key: 1 value: Google
key: 2 value: Runoob
key: 3 value: Taobao
key: 4 value: Zhihu
Google, Runoob, Taobao, Zhihu,

java HashMap 方法

方法描述
clear()删除 hashMap 中的所有键/值对
clone()复制一份 hashMap
isEmpty()判断 hashMap 是否为空
size()计算 hashMap 中键/值对的数量
put()将键/值对添加到 hashMap 中
putAll()将所有键/值对添加到 hashMap 中
putIfAbsent()如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。
emove()删除 hashMap 中指定键 key 的映射关系
containsKey()检查 hashMap 中是否存在指定的 key 对应的映射关系。
containsValue()检查 hashMap 中是否存在指定的 value 对应的映射关系。
replace()替换 hashMap 中是指定的 key 对应的 value。
replaceAll()将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
get()获取指定 key 对应对 value
getOrDefault()获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
forEach()对 hashMap 中的每个映射执行指定的操作。
entrySet()返回 hashMap 中所有映射项的集合集合视图。
keySet()返回 hashMap 中所有 key 组成的集合视图。
values()返回 hashMap 中存在的所有 value 值。
merge()添加键值对到 hashMap 中
compute()对 hashMap 中指定 key 的值进行重新计算
computeIfAbsent()对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中
computeIfPresent()对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值