Java数据类型与语句结构
数据类型与数据类型的转换
🐤数据类型概念
- Java是
强类型
语言。- 对于每一种数据,都定义了明确的数据类型。
- 不同的数据类型,在内存当中分配的空间大小是不一样的。
数据类型分类
✨基本数据类型
- 数值型:整数(byte、short、int、long、不同的整数类型在内存占用的内存空间大小是不一样的)、小数(float、double)
- 字符型:char。
- 布尔型:boolean。
🐱🐉引用数据类型
- 类。
- 接口。
- 数组。
🦧数据类型占用内存空间的大小
常用的数据类型
🐸整数类型
- byte、short、int、long。
- 相同点都是存放
整数类型
的数据,不同点开辟的内存空间大小
不一样。- Java 语言的整型常量默认是
int
类型。- 声明 long 类型变量需要在值后面加上一个
l
或L
。- 因小写的
l
容易和数字1
相混淆,建议使用大写L
。
public class Test {
public static void main(String[] args) {
// 8位
byte b = 30;
// b = 128;
// 16位
short c = 32767;
// 32位
int d = 324;
// 64位
long e = 68978L;
// 默认是int类型
System.out.println(100);
}
}
🐱🏍布尔类型
- 通常用于逻辑运算 和 程序流程控制(条件选择 / 循环)
- 该类型的值只能是
true
或false
,表示 真 或者 假。- 不可以使用
0
或非0
的整数来代替false
和true
。
🐱👤小数类型
- float、double。
- float 表示
单精度
类型。- double 表示
双精度
类型。- 浮点类型的字面量默认是
double类型
,若要声明一个常量为 float 类型,则需在常量后加上f
或F
,double 类型常量后面的 D 或 d 可以省略不写。
public class Test {
public static void main(String[] args) {
// 小数(float double)
double money = 100.5;
// 相同点都是存放小数类型的数据,不同点开辟的内存空间大小不一样
// 默认情况下,小数默认类型是属于double
System.out.println(80.5);
// float money2 = 80.5; 此行错误
float money2 = 80.5f;
}
}
🤳字符类型
- 计算机只能表示
0
和1
两个数,于是人们使用一个数字
去表示一个特定的字符。- char 类型:表示 16 位的无符号整数或者 Unicode 字符。
- Unicode 收集了世界上所有语言文字中的符号,是一种跨平台的编码方式,Java 的字符占
两个字节
,可以表示一个汉字。
char 常量有 3 种表示形式
- 直接使用
单个字符
来指定字符常量,格式如 '◆'、'A'、'7'。- 直接作为十进制整数数值使用,但是数据范围在 [0-65535],格式如:97,但是打印出来的值依然是 ASCII 码表对于的符号,如 97 打印出来是字符 a。
- 和 2 一样,只不过表示的是 16 进制的数值,格式如:'\uX',X 表示 16 进制的整数,如:97 的 16 进制是
61
。- 以上的 3 种表示形式不太清除的可以看看我下方给出的示例:
🦎ASSCII表
public class Test {
public static void main(String[] args) {
System.out.println('A');
// 编码 0 1字符类型
// ASSIC
char BNTang = 97;
System.out.println(BNTang);
// 直接输出的是int类型
System.out.println(97);
}
}
🐱🐉基本数据类型的转换
- 8 个基本数据类型分别占用内存空间大小。
🐱数据类型的转换概念
- 把一种数据类型赋值给另外一种数据类型。
- 一种数据类型变换为另外一种数据类型。
🐔数据类型的转换
- 在运算过程当中,如果不同的数据类型进行运算,可能运行的结果会发生错误。
- 把一种数据类型赋值给另一种数据类型也会发生错误,有的情况不会报错我下方一一说明。
- 所以在运行之前,把类型进行统一。
🐹数据类型转换的原则
- boolean 不属于
数值类型
,不参与转换。- 系统可以完成
自动类型转换
。- 不能(直接)把一个大的数据类型赋值给一个小的数据类型。
🐏自动类型转换
- 当把一个小的数据类型的数值或变量赋给一个大的数据类型的变量,系统就会自动帮我们进行转换,如下是自动类型转换的示例
short num = 10;
int max = num;
🕊强制类型转换
- 当把一个大数据类型的数值或变量赋给一个小的数据类型变量时,此时系统不能自动完成转换,需要加上
强制转换符
。- 但这样的操作可能造成
数据精度
的降低或溢出,所以使用时要格外注意,如下是强制类型转换的示例:
public class Test {
public static void main(String[] args) {
int num = 20 + (int)30.5;
System.out.println(num);
}
}
🐳自动类型提升
- 当一个算术表达式中包含了多个基本数据类型(boolean 除外)的值时。
- 整个算术表达式的数据类型将在数据运算时出现类型自动提升。
- 所有的 byte、short、char 类型会被自动提升到
int
类型。- 整个表达式的最终结果类型会被提升到表达式中类型最高(最大)的数据类型。
- 小的数据类型与大的数据类型运算时,会指定的提升为大的数据类型。
public class Test {
public static void main(String[] args) {
short num = 30;
// 自动提升为了int
int max = 20 + num;
}
}
运算符
算术运算符
用来处理四则运算的符号
加号
- 在操作数值、字符、字符串时其结果是不同的,当两个字符相加得到的是 ASCII 码表上对应的值。
- 当两个
字符串
相加时表示将两个字符串连接在一起,从而组成新的字符串。
public class Test {
public static void main(String[] args) {
System.out.println('a' + 'A');
System.out.println("abc" + "efg");
}
}
除号
- 整数在使用除号操作时,得到的结果仍为整数(小数部分忽略)
- 如果想要两个整数相除得到小数就可以把一方强制
转换浮点数
(也就是小数)- 当整数
除以0
的时候,会引发算术异常
。- Exception in thread "main" java.lang.ArithmeticException: / by zero
public class Test {
public static void main(String[] args) {
System.out.println(3 / 2);
System.out.println(3 / 0);
}
}
取模(求余数)
- 模数的符号忽略不计,结果的正负取决于
被模数
。- 符号的正负是看左边,左边是负就为负,左边是正就为正。
public class Test {
public static void main(String[] args) {
System.out.println(10 % -3);
}
}
自增++ 与 自减--
- ++表示当前操作的变量自己
累加1
。- --表示当前操作的变量自己
减去1
。- 前置++(++result)表示对 result 加 1 之后的结果进行运算,也就是 result 加了 1 之后,拿着加了 1之后的 result 结果进行运算(使用累加之后的值进行运算)
- 后置++(result++)表示对 result 变量加 1 之前的值(原始值)进行运算(使用变量的原始值进行运算)
如果不参与运算的话,它们是没有任何区别的
。- 自增++ 与 自减-- 表示当前操作的变量自己累加1 或 累减1。
- 无论是前面还是后面,都会对当前的变量的值进行累加或累减。
💻写在后面(使用变量的原始值进行运算)
public class Test {
public static void main(String[] args) {
int num1 = 10;
int num2 = 10;
int res = num1++ + num2;
System.out.println(res);
System.out.println(num1);
}
}
📝写在前面(使用累加之后的值进行运算)
public class Test {
public static void main(String[] args) {
int num1 = 10;
int num2 = 10;
int res = ++num1 + num2;
System.out.println(res);
System.out.println(num1);
}
}
赋值运算符
- 就是将符号右边的值,赋值给左边的变量。
public class Test {
public static void main(String[] args) {
int a = 10;
// a = a + 1;
a += 1;
// a = a - 1;
a -= 1;
// a = a * 2;
a *= 2;
// a = a / 5;
a /= 5;
// a = a % 2;
a %= 2;
System.out.println(a);
short s = 5;
// 整数默认是int,如果是 s = s + 1, 需要进行强制类型转换(int > short)
s = (short)(s + 1);
// s = (short)(s + 5);
s += 5;
}
}
比较运算符
- 用于比较两个变量或常量之间的关系,比较运算符的结果是
boolean
数据类型。- 格式为:boolean result = 表达式A 比较运算符 表达式B。
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 11;
// true
System.out.println(a == a);
// false
System.out.println(a > b);
// true
System.out.println(a < b);
// true
System.out.println(a <= a);
// true
System.out.println(b >= a);
// false
System.out.println(a != a);
}
}
逻辑运算符
- 是用来连接两个布尔类型结果的运算符,运算结果都是布尔值
true
或者false
。
与(&)
- 格式:逻辑表达式1 & 逻辑表达式2。
- 如果两个表达结果有一个为
false
那么与的结果就为false
。- 两个表达式的结果都为
true
,那么与的结果才为true
。
public class Test {
public static void main(String[] args) {
// false
System.out.println(true & false);
// true
System.out.println(true & true);
// false
System.out.println(false & false);
}
}
或(|)
- 格式:逻辑表达式1 | 逻辑表达式2。
- 如果两个表达式结果有一个为
true
,那么结果就为true
。- 只有当两个结果都为
false
时,那么或的结果才为false
。
public class Test {
public static void main(String[] args) {
// true
System.out.println(true | false);
// true
System.out.println(true | true);
// false
System.out.println(false | false);
}
}
非(!)
- 格式:!布尔类型。
- 对一个布尔类型
取反
操作。- 也就是说如果为 true 取反就变成了 false,反而言之就为
true
。
public class Test {
public static void main(String[] args) {
// true
System.out.println(!false);
}
}
异或(^)
- 格式:逻辑表达式1 ^ 逻辑表达式2。
- 表达式结果相同为
false
,不同时为true
。
public class Test {
public static void main(String[] args) {
// true
System.out.println(false ^ true);
// false
System.out.println(false ^ false);
}
}
短路与(&&)
- 格式:逻辑表达式1 && 逻辑表达式2。
- 只要发现了为
false
,就不会再去执行后面的表达式。- 如果下方的代码没有抛出异常即可证明这一点,因为为
false
后面的就不会在执行了。
public class Test {
public static void main(String[] args) {
// false
System.out.println(false && 1 == 1/0);
}
}
短路或(||)
- 格式:逻辑表达式1 || 逻辑表达式2。
- 只要发现了有
true
,就不会再去执行后面的表达式,验证逻辑和上面一样的。
public class Test {
public static void main(String[] args) {
// true
System.out.println(true || 1 == 1/0);
}
}
位运算符
- Java提供了
4
种位运算符。- 位与运算符(bitwise and operator)&。
- 位或运算符(bitwise inclusive or operator)|。
- 位异或运算符(bitwise exclusive or operator)^。
- 位取反运算符(bitwise invert operator)~。
- 这些运算符是在
二进制补码
上进行操作的,二进制补码不熟悉的可以看看我之前的文章有做详细的解释。
public class Test {
public static void main(String[] args) {
byte a = 15;
byte b = -15;
// 1
System.out.println(a & b);
// -1
System.out.println(a | b);
// -2
System.out.println(a ^ b);
// -16
System.out.println(~a);
// 14
System.out.println(~b);
}
}
- 一个
字节
数占8
位,将 a、b 转换为二进制为如下:- a = 0000 1111。
- b = 1111 0001。
- 位与运算符:当两个操作数,同一下标的值均为 1 时,结果才为 1(相同时为 1,不同时为 0)
- a & b = 0000 1111 & 1111 0001 = 0000 0001(补)= 0000 0001(原)= 1
- 位或运算符:只要两个操作的数同一下标的值有一个为 1 时,结果就为 1
- a | b = 0000 1111 & 1111 0001 = 1111 1111(补)= 1000 0001(原)= -1
- 位异或运算符:只有两个操作的数同一下标的值不相等时,结果才为 1,相等为 0
- a ^ b = 0000 1111 ^ 1111 0001 = 1111 1110(补)= 1000 0010(原)= -2
- 位取反运算符:按位取反每一位
- ~a = ~0000 1111 = 1111 0000(补)= 1001 0000(原)= -16
- ~b = ~1111 0001 = 0000 1110(补)= 0000 1110(原)= 14
三元运算符
- 表达式:执行指定的运算,能够得出某一个特定的值。
- 我们称这个式子为表达式,得出的值为数值,是算术表达式,如果得出的值是
boolean
,称它是逻辑表达式。
三元运算符格式
- 数据类型 变量名 = 布尔类型表达式 ? 结果1 : 结果2。
三元运算符的计算方式
- 布尔类型表达式结果是
true
,三元运算符整体结果为结果1
,然后将结果1
的值赋值给变量。- 布尔类型表达式结果是
false
,三元运算符整体结果为结果2
,然后将结果2
的值赋值给变量。
public class Test {
public static void main(String[] args) {
int num = 3;
String res = num % 2 == 0 ? "偶数" : "奇数";
System.out.println(res);
}
}
移位运算
- Java提供了
3
种移位运算符
- 左移运算符(left shift operator)<<。
- 左移几位,就在最低位补几个0。
- 左移几位,就是该数乘以 2 的几次方。
public class Test {
public static void main(String[] args) {
System.out.println(3 << 2);
System.out.println(3 << 4);
System.out.println(3 * 16);
}
}
- 右移运算符(right shift operator)>>。
- 对于高位出现的空位,原来高位是什么,就拿什么来补。
- 右移几位,就是该数除以 2 的几次方。
public class Test {
public static void main(String[] args) {
System.out.println(3 >> 2);
System.out.println(6 >> 2);
System.out.println(6 / 4);
}
}
运算符的优先级
顺序结构
- 顺序执行,根据编写的顺序,从上到下的进行逐个运行 。
if
执行流程
- 首先判断关系表达式看其结果是 true 还是 false。
- 如果是 true 就执行语句体。
- 如果是 false 就不执行语句体。
- 如果
{}
当中只有一条语句,那么{}
可以省略不写。
public class Test {
public static void main(String[] args) {
if(true) System.out.println("真");
}
}
- 当逻辑表达式(关系表达式)的值为 true 才会去执行里面的语句体。
public class Test {
public static void main(String[] args) {
if(true) System.out.println("真");
}
}
if-else
执行流程
- 首先判断关系表达式看其结果是 true 还是 false。
- 如果是 true 就执行
语句体1
。- 如果是 false 就执行
语句体2
。- 两者必须得要做一个选择。
public class Test {
public static void main(String[] args) {
boolean isMan = false;
if(isMan) {
System.out.println("去男厕所");
}else {
System.out.println("去女厕所");
}
}
}
if-else-if...else
执行流程
- 首先判断关系
表达式1
看其结果是 true 还是 false。- 如果是 true 就执行
语句体1
。- 如果是 false 就继续判断关系表达式2看其结果是 true 还是 false。
- 如果是 true 就执行
语句体2
。- 如果是 false 就继续判断关系表达式看其结果是 true 还是 false。
- 如果已经满足条件了,那么后面的语句就不会再去帮你执行。
- 如果没有任何关系表达式为 true,就执行
语句体n+1
。
public class Test {
public static void main(String[] args) {
int day = 1;
if(day == 1) {
System.out.println("今天是星期1");
} else if(day == 2){
System.out.println("今天是星期2");
} else if(day == 3){
System.out.println("今天是星期3");
}else if(day == 4){
System.out.println("今天是星期4");
}else if(day == 5){
System.out.println("今天是星期5");
}else if(day == 6){
System.out.println("今天是星期6");
}else if(day == 7){
System.out.println("今天是星期日");
}else {
System.out.println("你想要星期几啊");
}
}
}
switch
执行流程
- 首先计算出表达式的值。
- 其次,和 case 依次比较,一旦有对应的值,就会执行里面相应的语句,在执行的过程中,遇到
break
就会结束。- 最后,如果所有的 case 都和表达式的值不匹配,就会执行
default
语句体部分,然后程序结束掉。
public class Test {
public static void main(String[] args) {
int day = 8;
switch(day) {
case 1:System.out.println("星期1");break;
case 2:System.out.println("星期2");break;
case 3:System.out.println("星期3");break;
case 4:System.out.println("星期4");break;
case 5:System.out.println("星期5");break;
case 6:System.out.println("星期6");break;
case 7:System.out.println("星期日");break;
default:System.out.println("你想要星期几啊");break;
}
}
}
case 穿透
- 在 switch 语句中,如果 case 的后面不写
break
,将出现穿透现象。- 也就是不会在判断下一个 case 的值,直接向后运行,直到遇到
break
,或者整体 switch 结束。
public class Test {
public static void main(String[] args) {
int day = 1;
switch(day) {
case 1:System.out.println("星期1");
case 2:System.out.println("星期2");
case 3:System.out.println("星期3");
case 4:System.out.println("星期4");break;
case 5:System.out.println("星期5");break;
case 6:System.out.println("星期6");break;
case 7:System.out.println("星期日");break;
default:System.out.println("你想要星期几啊");break;
}
}
}
- 在
JDK1.5
的时候表达式的值只能是整数(byte、short、int、long)- 在
JDK1.7
开始,就可以支持 String 字符串类型了。
循环结构
- 循环语句可以在满足循环条件的情况下。
- 反复执行某一段代码,这段被重复执行的代码被称为
循环体语句
。- 当反复执行这个循环体时,需要在合适的时候把循环判断条件修改为
false
。- 从而结束循环,否则循环将一直执行下去,形成
死循环
。
while
执行过程
- 先判断表达式,若为 true 就执行循环体,否则跳过循环体。
public class Test {
public static void main(String[] args) {
int count = 0;
while(count < 5) {
System.out.println("BNTnag");
count++;
}
}
}
do-while
执行流程
- 先执行一次循环体,再判断表达式,若为 true 就执行循环体,否则,跳过循环体。
- 也就是说 do-while 是先执行后在判断条件,即使判断条件为 false,该循环至少会执行一次。
public class Test {
public static void main(String[] args) {
int count = 0;
do {
System.out.println("BNTang");
count++;
}while( count < 5);
}
}
for
执行流程
- 初始化语句:表示对循环进行初始化,只在循环开始时执行一次,定义一个变量,并赋值。
- boolean 表达式:表达式为 false 时,循环终止,为 true,才执行循环体。
- 循环后的操作语句:循环每次迭代之后都会调用该语句,一般该语句都是递增或递减操作。
public class Test {
public static void main(String[] args) {
for (
// 1.初始化语句
int count = 0;
// 2.逻辑表达式
count < 5;
// 3.循环之后的操作语句
count++
)
{
// 4.循环体
System.out.println("BNTang");
}
for(int num = 1; num <= 10; num++) {
System.out.println(num);
}
}
}
死循环
- 也就是循环中的条件永远为
true
,死循环是永不结束的循环。
while 死循环
do-while 死循环
for 死循环
控制循环结构
break 语句
- 终止当前所在的循环。
- break 之后的语句执行不了,所以不能在 break 后面继续编写代码了。
public class Test {
public static void main(String[] args) {
int count = 0;
for(int i = 1; i<=100; i++) {
if(i % 2 == 0) {
System.out.println(i);
count++;
}
if(count == 5) {
break;
}
}
}
}
continue 语句
- 跳过当前的循环,进入下一次的循环操作。
public class Test {
public static void main(String[] args) {
for (int i = 0; i <= 20; i++) {
if(i % 3 == 0){
continue;
}
System.out.println(i);
}
}
}
return 语句
- 表示结束循环所在的方法,方法都结束了,循环结构自然也就结束了。
public class Test {
public static void main(String[] args) {
for (int i = 0; i <= 10; i++) {
if(i == 5){
return;
}
System.out.println(i);
}
System.out.println("end");
}
}
嵌套循环
- 一个循环的循环体又是另一个循环,比如 for 循环里面还有一个 for 循环。
public class Test {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 3; j++) {
System.out.println(i);
}
}
}
}
水仙花数
- 打印 100 到 1000 之间的水仙花数。
- 水仙花数是指一个
3
位数。- 它的每个位上的数字的 3 次幂之和等于它本身,就是水仙花数。
个十百位算法
- 求个位:153 % 10 = 3。
- 求十位:153 / 10 % 10 = 5。
- 求百位:153 / 100 = 1。
- 实现方案①,算法实现。
public class Test {
public static void main(String[] args) {
for (int i = 100; i < 1000; i++) {
int bw = i / 100;
int sw = i / 10 % 10;
int gw = i % 10;
if(bw * bw * bw + sw * sw * sw + gw * gw *gw == i){
System.out.println(i);
}
}
}
}
- 实现方案②,使用一个
Math类
中的一个求几次幂的pow方法
(Math.pow(value1, value2),求 value1 的 value2次幂)
public class Test {
public static void main(String[] args) {
for (int i = 100; i < 1000; i++) {
int bw = i / 100;
int sw = i / 10 % 10;
int gw = i % 10;
if (Math.pow(bw,3) + Math.pow(sw,3) + Math.pow(gw,3) == i) {
System.out.println(i);
}
}
}
}
打印长方形
public class Test {
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 5; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
打印直角三角形
public class Test {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
打印等边三角形
- 空格个数算法:总行数 - 当前行号。
- 星(*)的算法:当前行号 * 2 - 1。
public class Test {
public static void main(String[] args) {
int totalRows = 5;
for (int row = 1; row <= totalRows; row++) {
for (int col = 1; col <= totalRows-row; col++) {
System.out.print(" ");
}
for (int i = 0; i < row * 2 - 1; i++) {
System.out.print("*");
}
System.out.println();
}
}
}
九九乘法表
public class Test {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i + "*" + j + "=" + i * j + "\t");
}
System.out.println();
}
}
}
控制外层循环
- 就是在循环前面添加一个标签,就是给某个循环起的别名,不过该别名得满足标识符的规范,标识符的规范我在前面已经介绍过了,不知道的可以回去看看
- 若要控制外层循环,就在 break 或 continue 后面跟上循环的标签名称即可例子如下:
public class Test {
public static void main(String[] args) {
outter : for(int count= 1; count <= 5; count++) {
inner : for(int i = 0; i < count;i++) {
if(count == 3) {
break outter;
}
System.out.print("*");
}
System.out.println();
}
}
}