关键字-》标识符-》注释-》常量和变量->数据类型-》数据类型转换-》运算符-》语句-》函数-》数组
关键字概述:---------------------------------------
被java语言赋予特定含义的单词
关键字特点
字母全部小写 例如class public void static double,int 等等都是关键字 main String 都不是
关键字注意事项
goto和const作为保留字存在,目前并不存在
标识符概述:------------------------------------------
就是给类,接口,方法,变量等起名字时使用的字符序列
组成规则:
英文大小写字母
数字字符
$和_
注意事项
不能以数字开头
不能是java中的关键字
区分大小写
常见的命名规则: 见名知意
举例:定义一个学生类
class Student{}
包:其实就是文件夹,用于把相同的类名进行区分
包名全部小写
单级 liuyi
多级 cn.itcast,com.baidu
类或者接口:
一个单词组成:单词的首字母必须大写
举例:Student,Dog
多个单词组成:每个单词的首字母必须大写
举例:HelloWorld,StudentName
方法或者变量:
一个单词:单词的首字母小写
举例:main,age
多个单词:从第二个单词开始,每个单词的首字母大写
举例:studentAge,showAllNames()
常量:
一个单词:全部大写
举例:PI
多个单词:每个字母都大写,用_隔开
举例:STUDENT_MAX_AGE
注释概述---------------------------------------------------
用于解释说明程序的文字
java中注释分类及格式
1.单行注释: //注释代码
2.多行注释:/*注释代码*/
注意:多行不可以嵌套使用,而单行是可以的
3.文档注释:/**是被javadoc工具解析生成一个说明书*/
注释的作用:
1.调试程序,可以用来排解程序中的错误
2.解释说明程序,提高了代码的阅读性
常量:----------------------------------------------------
在程序执行过程中,其值不可以发生改变的量
分类:
1.字面值常量
2.自定义常量
字面值常量
1.字符串常量 用双引号括起来的内容 例如“HelloWorld”
2.整数常量 所有的整数 举例:100,200
3,小数常量 所有的小数 10.23 10.11
4.字符常量 用单引号括起来的内容 举例‘a’
5.布尔常量 比较特殊 举例:true false
6.空常量 null
java针对整数常量提供了4中表现形式:
二进制 由0,1组成 以0b开头
八进制 0到7组成,以0开头
十进制 0到9组成 整数默认是十进制
十六进制 0到9,a到f(大小写均可)组成,以0x开头
进制:是一种进位的方式,X进制表示逢X进1
计算机的电子元器件的状态:开,关
那么,我们表达数据的时候,也是按照开,关的状态来表示的
如果我们表达数据仅仅是用这两种状态来表示,那么能够表达的数据是比较少的
而我们常见的数据:英文字母,数字,标点符号,这就很多了。
为了能够表示更多的数据,国际化标准组织就规定:用8个这样的信号来表示一个数据,这个数据的单位叫:字节
1byte = 8bit
1k = 1024byte
1m = 1024k
1g = 1024m
1t = 1024g
但是呢,用二进制表达数据的表现形式有点长,所以呢,我们就想要简化一下、
如何简化呢?
把二进制的数据,从右开始,每三位一组合,最左边不够的时候
补0,然后分别计算出对应的十进制数值,最后,在把每个十进制的数据组合起来,就是一个八进制数据
010 110 110
十进制 十进制 十进制
八进制
这种表现形式还不是最简单的,我们还有更简单的。
把二进制的数据,从右开始,每四位一组合,最左边不够的时候,补0,然后呢,分别计算出对应的十进制数值,最后把每个十进制的数据组合起来,就是一个十六进制的数据
1011 0110
十进制 十进制
十六进制
规则:进制越大,表现形式越短
不同进制的数据表现:
二进制:由0,1组成,以0b开头
八进制:由0到7组成,以0开头
十进制:由0到9组成,默认整数是十进制
十六进制:由0到9,a,b,c,d,e,f(大小写均可)以0x开头
有符号数据表示法
原码,反码,补码
为什么要掌握这么知识点?
因为计算机在操作的时候,都是采用数据对应的二进制的补码来计算的
我准备用原码,反码,补码来分别表示+7 和-7
首先我们得到7的二进制:111
原码:
正数的原码最高位是0
负数的原码最高位是1
其他的是数值位
符号位 数值位
+7 0 0000111
-7 1 0000111
反码
正数的反码和原码相同
负数的反码与原码符号位不变,数值位取反
符号位 数值位
+7 0 0000111
-7 1 1111000
补码:
正数的补码与原码相同
负数的补码是在反码的基础上加1
符号位 数值位
+7 0 0000111
1.已知某数的原码位10110100b。试求其补码和反码
符号位 数值位
原码 1 0110100
反码 1 1001011
补码 1 1001100
2已知某数的补码是11101110b 求原码
符号位 数值位
补码 1 1101110
反码 1 1101101
原码 1 0010010
--------------------------------------------------------------
java的数据类型
分为基本数据类型和引用数据类型
基本数据类型
整数类型(byte,short,int,long)
1 2 4 8
浮点类型(float,double)
4 8
字符型(char)
2
布尔型(boolean)
1
引用数据类型
类(class)
接口(interface)
数组(【】)
注意:整数默认是int
浮点数默认是double
长整数要加L或者l
单精度的浮点数要加F或者f
使用变量的时候要注意的问题:
1.作用域问题
变量定义在哪个大括号内,它就在这个大括号内有效,并且在同一大括号内 不能定义同名的变量
2.初始化值
没有初始化值得变量不能直接使用。你只要在使用前给值就行,不一定非要在定义的时候立即给值,但是推荐定义的时候就给值
3.在一行上建议只定义一个变量,可以定义多个,但是不建议。
数据类型的转换:
0.boolean类型不参与转换
1.默认转换
从小到大
byte,short,char--int--long--float--double
当byte,short,char类型默认转换的时候有int就转换成int,有long就要转换成long,同理后面也是,因为越是后面数据范围越大。
long:8个字节
float:4个字节
为什么float在long的后面,也就是说float的优先级更高呢?
他们的底层的存储结构不同
float表示的数据范围要比long的范围更大
byte,short,char之间不互相转换,直接转成int类型参与运算
2.强制转换
从大到小
可能会损失精度,一般不建议这样使用
格式:
目标数据类型 变量名 = (目标数据类型)被转换的数据
注意: 在定义Long或者Float类型变量的时候,要加L或者f
整数默认是int类型,浮点数默认是double类型
byte,short在定义的时候,他们接收的其实是一个int类型的值
这是直接做了一个数据的监测,如果不在范围内,就报错
byte的范围是:-128到127
思考题和面试题:
下面两种方式有区别吗?
float f1 = 12.345f;
float f2 = (float)12.345;
答:有区别,第一个的数据本身就是单精度类型
第二个数据本身是double类型,被强制转换成了单精度类型
第一题:
byte b1=3,b2=4,b;
b = b1 + b2;
b = 3 + 4;
哪句是编译失败的呢?为什么?
b = b1+b2; 是有问题的,会损失精度
因为变量相加,会首先看类型问题,最终把赋值的结果也会考虑类型问题,
也就是说b1+b2之后,会提升为int类型,
b = 3+4 是没有问题的
因为常量相加,先做加法,然后看结果是否在赋值的数据类型范围当中,如果不是,才会报错
第二题:
byte b = 130;有没有问题?如果我想赋值正确,怎么做?结果是多少?
提示可能损失精度,因为byte的范围是:-128到127
而130不在此范围,所以报错
我们可以使用强制类型转换
byte b = (byte)130;
分析过程:
我们想要知道结果是什么,就应该知道是如何计算的。
而我们都知道计算机中数据的运算都是补码进行的
而要得到补码,首先要计算出数据的二进制
1:获取130这个数据的二进制
00000000 00000000 00000000 10000010
这是130的原码,也是反码,还是补码
2.做截取操作,截成byte类型
10000010
这个结果是补码。
3.已知补码求原码。
符号位 数值位
补码: 1 0000010
反码 1 0000001
原码 1 1111110
所以结果是-126
第三题:
看程序,写结果;
System.out.println("hello"+'a'+1); helloa1
System.out.println('a'+1+"hello"); 98hello
System.out.println("5+5="+5+5); 5+5=55
System.out.println(5+5+"=5+5");10=5+5
运算符:
就是对常量和变量进行操作的符号
分类:算术运算符,赋值运算符,比较运算符,逻辑运算符,位运算符,三目运算符
算术运算符:
+ - * / % ++ --
注意事项:
1.整数相除只能得到整数,如果想得到小数,需把数据变化为浮点数
2./获取的是除法操作的商,%获取的是除法操作的余数
注意一个细节:
3/4 结果为0 为什么呢?因为整数相除只能得到整数,但是我就想得到小数,怎么办? 只需要把操作中的任意一个数据变为浮点数
++ -- 运算符的使用:
作用:就是对变量进行自增或者自减
单独使用:
放在操作数的前面和后面的效果是一样的
参与运算使用:
放在操作数的前面,先自增或者自减,然后在参与运算
放在操作数的后面,先参与运算,再自增或者自减
赋值运算符
基本的赋值运算符:=
把=右边的数据赋值给左边
扩展的赋值运算符:+=,-=,*=,/=,%=
面试题:
short s = 1;s = s + 1;
short s = 1; s + = 1;
上面的两行代码有没有问题,如果有,问题在哪里?
第一行中,short类型的s要参与运算要提成为int类型,右边的总结果是int类型,而左边是short类型,所以编译提示,可能损失精度
第二行中,是没有问题的,不会提示可能损失精度,为什么呢?
因为扩展的赋值运算符其实隐含了一个强制类型转换
s += 1;
不是等价于 s = s +1;
而是等价于 s = (s的数据类型)(s+1);
比较运算符:
==,=,>,>=,<,<=
特点:
无论你的操作是简单还是复杂,结果都是boolean类型
注意事项:
== 不能写成 =
逻辑运算符
&,|,^,!
&&,||
逻辑运算符用于连接boolean布尔类型的表达式或者值
表达式:就是用运算符把常量或者变量连接起来的符合java语法的式子
算术表达式:a+b 因为+是算术运算符,所以叫算术表达式
比较表达式:a ==b因为==是比较运算符,所以叫比较表达式
结论:
逻辑与:& 有false则false
逻辑或:| 有true则true
逻辑异或:^ 相同为false,不同为true
逻辑非:! 非false则true,非true则false
&& 和 &的区别?
1:最终结果一样
2.&&具有短路效果,左边是false,右边不执行
位运算符
&,|,^,~
<<,>>,>>>
注意:
要做位运算,首先要把数据转换为二进制
如题:
int a = 3;
int b = 4;
System.out.println(3 & 4);
System.out.println(3 | 4);
System.out.println(3 ^ 4);
System.out.println(~3);
分析:因为是位运算,所以我们必须把数据转换成二进制
3的二进制:11
00000000 00000000 00000000 00000011
4的二进制:100
00000000 00000000 00000000 00000100
---------------------------------
&位与运算:有0则0,此时跟逻辑&道理等同,
00000000 00000000 00000000 00000011
& 00000000 00000000 00000000 00000100
等于 00000000 00000000 00000000 00000000
结果是0
-----------------------------------
|位或运算:有1则1,此时跟逻辑|道理等同,
00000000 00000000 00000000 00000011
& 00000000 00000000 00000000 00000100
等于 00000000 00000000 00000000 00000111
结果是:7
---------------------------------------
^位异或运算:相同则0,不同则1
00000000 00000000 00000000 00000011
& 00000000 00000000 00000000 00000100
等于 00000000 00000000 00000000 00000111
结果是:7
---------------------------------------
System.out.println(~3);
~按位取反运算符:0变1,1变0
00000000 00000000 00000000 00000011
~ 11111111 11111111 11111111 11111100(补码)
补码:11111111 11111111 11111111 11111100
反码:11111111 11111111 11111111 11111011
原码:10000000 00000000 00000000 00000100
结果是:-4
警示:计算机中数据是以补码进行运算的,以原码进行显示给我们
整数的原码,反码,补码都是相同的
^位异或的特点:一个数据对另一个数据异或两次,该数本身不变。
int a = 10;
int b = 20;
System.out.println(a ^ b ^ b); 结果是10
System.out.println(a ^ b ^ a); 结果是20
面试题:
请自己实现两个整数变量的交换?
方法1: 使用第三方变量
int t = a;
a = b;
b = t;
方法2: 用位异或实现
左边:a,b,a
右边:a ^ b
a = a ^ b;
b = a ^ b; //a ^ b ^b = a
a = a ^ b; //a ^ b ^a = b
方法3:用变量相加的做法
a = a+b;
b = a-b;
a = a-b;
方法4:一句话搞定
b = (a+b) - (a=b);//b = 30-20=10,a=20
<<:左移 左边最高位丢弃,右边补齐0
>>:右移 最高位是0,左边补齐0;最高位是1,左边补齐1
>>>:无符号右移 无论最高位是0还是1,左边补齐0
如题:System.out.println(3 << 2);
首先要计算出3的二进制:11
00000000 00000000 00000000 00000011
(00)000000 00000000 00000000 0000001100 结果就是12
结论:<< 把<<左边的数据乘以2的移动次幂
也就是 3 * 2^2 = 12
>> 把>>左边的数据除以2的移动次幂
三目运算符:
格式:比较表达式?表达式1:表达式2;
比较表达式的结果是boolean类型。
----------------------------------------------
代码的流程结构有三种:顺序,选择,循环
选择结构也称之为分支结构
java语言提供了两种选择结构语句:if语句,switch语句
if语句有三种格式;
第一种:
if(比较表达式)
{
语句体
}
注意:比较表达式无论简单或者复杂,结果必须是boolean类型
语句体如果是一条语句,大括号可以省略;
如果是多条,不能省略。
第二种:
if(比较表达式)
{
语句体1;
}
else
{
语句体2;
}
注意:else后面是没有比较表达式的,只有if后面有
if语句和三目运算的区别?
三元运算符实现的,都可以用if语句实现,反之不成立
什么时候if语句实现不能用三元改进呢?
当if语句控制的操作是一个输出语句的时候就不能
因为三元运算符是一个运算符,运算符操作完毕就应该有一个结果,而不是一个输出
if语句的第三种格式
if(比较表达式1)
{
语句体1;
}
else if(比较表达式2)
{
语句体2;
}
。。。。
else
{
语句体N+1;
}
switch语句格式:
switch(表达式)
{
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
。。。
default:
语句体n+1;
break;
}
格式解释:
switch:表示这是switch选择结构
表达式:这个地方的取值是有限定的
byte,short,int,char
jdk5以后可以是枚举
jdk7以后可以是字符串
case:后面跟的是要和表达式进行比较的值
语句体:要执行的代码
break:表示中断,结束的意思,结束switch语句、
default:当所有的值都是表达式不匹配的时候,就执行default控制的语句
执行流程:
首先计算出表达式的值
其次,和case依次比较,一旦有对应的值,就会执行相应的语句,,在执行的过程中,遇到break就会结束,
最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。
面试题:byte可以作为switch的表达式吗/
long可以作为switch的表达式吗
String可以作为switch的表达式吗?
switch注意事项:
1.case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同
2.default是可以省略的,但是不建议省,因为它的作用是对不正确的情况作出提示
3.default的位置可以在任意位置,但是不建议。这个时候的流程顺序是
即使default在上面,但是依然先执行case,最后执行default
if语句和switch的区别?
if语句:
针对结果是boolean类型的判断
针对一个范围的判断
针对几个常量值得判断
switch语句:
针对几个常量值得判断
while循环和for循环的区别?
使用区别:如果在你想循环结束后,继续使用控制条件的那个变量,用while
因为变量及早的从内存中消失,可以提高内存的使用效率
其实还有一种场景的理解:
如果是一个范围,用for循环非常明确
如果不明确次数,用while循环比较合适
控制跳转语句:
break:中断
continue:继续
return:返回
break:中断的意思
使用场景:
1.switch语句中
2.循环语句中(循环语句中加入了if判断的情况)
注意:离开上面的两个场景,无意义。
如何使用呢?
1.跳出单层循环
2.跳出多层循环
要想实现这个效果,就必须在for循环的前面就一个标签然后加一个冒号
格式:标签名:语句
break的时候可以指定到那个语句
break:跳出单层循环
continue:跳出当前循环,进入下一次的执行
return:返回
return关键字不是为了跳出循环体,更常用的功能是结束一个方法
跳转到上层调用的方法。
for适用于一个范围的判断
while适合次数不明确的场景(存钱)
方法定义及格式:
格式:修饰符 返回值类型 方法名(参数类型 参数名1,参数类型,参数2。)
{
方法体语句;
return 返回值;
}
详细解释:
修饰符:目前就用 public static 后面我们再 详细讲解其他修饰符
返回值类型:就是功能结果的数据类型。
方法名:符合命名规则即可,方便我们调用。
参数:
实际参数:实际参与运算的
形式参数:方法定义上的,用于接收实际参数的
写函数要有两个明确:返回值类型要明确,参数类型要明确
注意事项: 方法与方法是平级关系,不能嵌套定义
方法调用的时候,实参前面不能带有数据类型
如果方法有明确的返回值,必须要有return带回一个值
void方法的调用,就直接写函数名(参数1,参数2)就可以了
方法重载:
在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数
或者参数类型不同即可
方法重载特点:
与返回值无关,只看方法名和参数列表
在调用时,虚拟机通过参数列表的不同来区分同名方法
数组概念:
数组是存储同一种数据类型多个元素的集合,也可以看成是一个容器
数组既可以存储基本数据类型,也可以存储引用数据类型
格式;
数据类型【】 数组名;
数据类型 数组名【】;
建议使用第一种,可读性强。
数组的初始化:
动态初始化:初始化时只指定数组长度,由系统为系统分配初始值
int [] arr = new int[3];
静态初始化:初始化时指定每个数组元素的值,由系统决定数组长度
java程序为了提高程序的效率,就对数据进行了不同空间的分配
具体是划分了5个内存空间
java中内存的分配:
栈:存放的是局部变量
堆:存放的是所有new出来的东西
方法区:
本地方法区(和系统相关)
寄存器(给cpu使用)
局部变量:在方法定义中或者方法声明上的变量都称为局部变量
int[] arr= new int[3];
System.out.println(arr);//地址值
System.out.println(arr[0]);// 0
System.out.println(arr[1]);//0
为什么打印arr显示的是地址值呢?而打印arr[0]却是0呢?
首先在栈区存放局部变量arr,而同时也在堆区new了存放三个数据的数组内存空间
而此时堆区的地址值指向了栈区的那个arr变量。
从而我们可以得出结论:
堆内存的特点:
1.每个new出来的东西都有地址值
2.每个变量都有默认值
btye,short,int,long 默认是0
float,double 默认是0.0
char ‘\u0000’
boolean默认是false
引用类型是null
3.使用完毕就变成垃圾,但是并没有立即回收。
栈内存的数据用完就释放掉,也就是脱离了它的作用域
数组的静态初始化:
格式:数据类型【】 数组名 =new 数据类型【】{元素1元素2.。。}
举例:int[] arr = new int[]{1,2,3};
简化格式:数据类型【】 数组名={元素1,元素2.。。}
举例:int[] arr = {1,2,3};
注意:不要同时动态和静态进行
如下格式:
int[] arr = new int[3]{1,2,3};//错误的
ArrayIndexOutOfBoundsException 数组越界异常
二维数组
其实二维数组就是一个元素为一维数组的数组
格式:
1.数据类型 [][] 数组名 = new 数据类型[m][n];
2.数据类型 [][] 数组名 = new 数据类型[m][];
3.数据类型 [][] 数组名 = new 数据类型[][]{{},{}...};
4.数据类型 [][] 数组名 ={{},{}...};//常用
格式1:
数据类型 [][] 变量名 = new 数据类型[m][n];
m表示这个二维数组有多少个一维数组
n表示每一个一维数组的元素个数
举例:
int[][] arr = new int[3][2];//常用
定义了一个二维数组arr
这个二维数组有3个元素,也就是3个一维数组,名称是arr[0],arr[1],arr[2]
每个一维数组有2个元素,可以通过arr[m][n]来获取
注意:
1.以下格式也可以表示二维数组
a.数据类型 数组名[][] = new 数据类型[m][n];
b.数据类型[] 数组名[] = new 数据类型[m][n];
定义一个二维数组:
int [][] arr = new int[3][2];
定义了一个二维素组arr
这个二维数组有3个一维数组的元素
每个一维数组有2个元素
格式3:
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};//常用
int [][] arr = {{1,2,3},{4,5},{6}};
练习题:
公司年销售额求和
某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44;
第二季度:77,33,88;
第三季度:25,45,65;
第四季度:11,66,99;
class QiuHe{
public static void main(String [] args)
{
int sum = 0;
int [][] arr = {{22,66,44},{77,33,88},{25,45,65},{11,66,99}};
for(int i=0;i<arr.length;i++)
{
for(int j = 0;j<arr[i].length;j++)
{
sum = sum + arr[i][j];
}
}
System.out.println("一年的销售额为:"+sum+"万元");
}
}
import java.util.Scanner;
class YangHui{
public static void main(String [] args)
{
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入数据:");
int n = sc.nextInt();
//定义二维数组
int [][] arr = new int[n][n];
//给这个二维数组任何一行的第一列和最后一列赋值为1
for(int i=0;i<arr.length;i++)
{
arr[i][0] = 1;
arr[i][i] = 1;
}
//从第三行开始,每一个数据都是它的上一行的前一列,和它的上一行的本列之和
for(int i=2;i<arr.length;i++)
{ //这里如果y<=x是有小问题的,就是最后一列的问题,因为已经有值了
//并且y也应该从1开始,因为第一列也是有值了
for(int j=1;j<=i-1;j++)
{
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
}
}
//遍历这个二维数组 内循环必须和九九乘法表类似
for(int i=0;i<arr.length;i++)
{
//注意,这里j不能小于arr[i].length,要去掉后半边
for(int j=0;j<=i;j++)
{
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
}
}
/*
某个公司采用公共电话传递数据信息,数据是小于8位的整数,为了确保安全,在传递过程中需要加密
加密规则如下:
首先将数据倒序,然后将每位数字都加上5,再用和除以10的余数代替该数字,
最后将第一位和最后一位数字交换,请任意给定一个小于8位的整数
然后,把加密后的结果在控制台打印出来,
题目要求:
1.数据是小于8位的整数
定义一个int类型的数据
int number = 123456;
2.加密规则:
1.首先将数据倒序
结果654321
2.然后将每位数字都加上5,再用和除以10的余数代替该数字
结果109876
3.最后将第一位和最后一位数字交换
结果 609871
3.把加密后的结果输出在控制台
通过简单的分析,我们知道如果我们有办法把这个数据变成数组就好了
而不是直接写成这个样子:int [] arr = {1,2,3,4,5,6};
如何转成数组呢?
1.定义一个数据
int number = 123456;
2.定义一个数组,这个时候问题就来了,数组的长度是多少呢?
int [] arr = new int[8];//不可能超过8
在赋值的时候,我用一个变量记录索引的变化
定义一个索引值是0;
int index = 0;
3.获取每个数据
int ge = number%10;
int shi = number/10%10;
int bai = number/10/10%10
arr[index] = ge;
index++;
arr[index] = shi;
*/
class JiaMi{
public static void main(String [] args)
{
//定义一个数据
int number = 123456;
//定义一个数组
int [] arr = new int[8];
//把数据中的每一位上的数据获取到后存储到数组中
/*int index = 0;
arr[index] = number%10;
index++;
arr[index] = number/10%10;
index++;
arr[index] = number/10/10%10*/
//通过观察代码,我们发现可以用循环来改进,
int index = 0;
while(number > 0){
arr[index] = number%10;
index++;
number/=10;
}
//然后将每位数字都加上5,再用和除以10代替该数字
for(int x = 0;x<index;x++)
{
arr[x] +=5;
arr[x] %=10;
}
//最后将第一位和最后一位交换
int temp = arr[0];
arr[0] = arr[index-1];
arr[index-1] = temp;
//输出数据
for(int x=0;x<index;x++)
{
System.out.print(arr[x]);
}
System.out.println();
}
}