一、不同类型之间的转换(总框架和总体规则)
总框架:不同数据类型的转换可分为两类,第一类是小类型转为大类型;第二类是大类型转为小类型
总体规则:1.小转大:可以自动提升,小类型和大类型进行数学运算时,首先会将小类型提升为大类型后进行数学运算,举例如下:
int a = 10;
long b = a + 1L;//int + long -> long + long
System.out.println(b);
2.大转小:大类型转为小类型需要强制类型转换,可能会丢失精度。(部分数据丢失)
(1)int 与 long 之间的类型转换
前提:程序执行代码都是从右向左执行的,以此来判断到底是大类型转为小类型,还是小类型转为大类型
小类型转换为大类型,示例如下:
int a = 10;
long b = 20L;
//a = b;此时为long类型转为int类型,需要进行强值转换
b = a;//此时为int转为long类型,可自动提升,编译通过
大类型转换为小类型:示例如下:
long b = 20L;
int a = (int)b;
System.out.println(a);//输出结果为整型,20
关于数据溢出:(易错点)
int a =Integer.MAX_VALUE;
long b = a + 1;//a + 1=int + int=int,先进行的是a+1,已经溢出了,把一个溢出值让long b接收,并不是long放不下,而是存储了一个溢出的值
System.out.println(b);
(2)int与double类型的转换:
小类型转换为大类型:示例如下
int a = 1;
double b = 2;//int变为double类型,2变为2.0
System.out.println(a/b);//int/double->double/double,最终结果为0.5
大类型转换为小类型,可能会造成精度丢失:示例如下
double b = 2.035009999999; int a = (int)b; System.out.println(a);
(3)int和byte之间的转换:
int a = 10; byte b = (byte) a;//强制转换 int c = b;//自动提升
易错点:
byte a = 10; byte b = 20; byte c = a + b;//此时会报错,因为前两句需要提升为int类型保存,byte,char和short,CPU在读写数据时,都是以四字节为单位进行读取和写入的 System.out.println(c);
那么该如何实现byte类型的相加呢?
final byte b = 10;//被final修饰的变量除了数据值不能改,类型也不能提升,final byte a = 10;存储时,仍然为byte类型!!! final byte a = 20; byte c = a + b; System.out.println(c);
(4)int和char类型的转换:
char a = 'a'; int b = a;//自动提升 System.out.println(b); int c = 97; char d = (char)c;//强制转换 System.out.println(d);
补充:字符和正行之间的相互转换是非常重要且常用的~,字符A的的集合为'a''b''c',字符B的集合为'b''a''c',A和B中的元素为异位词,那么我们如何知道A和B的集合保存字符是相同的呢?因为除了元素顺序不同,组成都是相同的
(5)int和String类型的转换:(与之前基本类型的转换有所不同)
int转换为String类型:
int num = 10; //int -> String //第一种方法,使用String的valueOf的方法 String str1 = String.valueOf(num); //第二种方法,使用String对象 + 的方法 String str2 = "" + num; System.out.println(str1); System.out.println(str2);
String转换为int类型:
String str = "123"; int a = Integer.parseInt(str);//调用int包装类Integer.parseInt()的方法 System.out.println(a);
当字符串包含了非数字时会转换出错:
String str = "1a2b3";//由于此时str中包含了非数字,调用这个方法时就会报错 int a = Integer.parseInt(str); System.out.println(a);
(6)在Java中,所有数据类型都有默认值,定义之后没有赋值,会有默认值(只存在于类变量中,方法中的局部变量不存在默认值)示例如下:
public class whileDemo { int a; double b; char c; boolean d; String str; public static void main(String[] args) { //new 后面跟类名 System.out.println(new whileDemo().a);//0 System.out.println(new whileDemo().b);//0.0 System.out.println(new whileDemo().c);//空格 System.out.println(new whileDemo().d);//false System.out.println(new whileDemo().str);//null } }
二、运算符
(1)加减乘除取模:
注意事项:相同数据类型进行数学运算,得到的值仍然是本类型
小类型和大类型进行数学运算,先把小类型提升为大类型然后进行运算
除法中,0不能作为除数
%称为取模运算,取余运算,求余数,不仅可以用于整数,也可以用于小数(重点)
举例:153如何利用取模运算得到个位十位和百位?
个位= 153%10=3 十位=153/10%10=15%10=5 百位:153/100 = 1
小练习:(示例如下)
double a = 11.5; int b = 2; System.out.println(a % b);//double % int -> double % double,先将b换为2.0,然后取余,结果为1.5
(2)增量运算符:+= /= %= *= -=
a+=1; 和a = a+1;等价 a=1; 和a = a1;等价
(3)自增和自减运算符:
a ++ :先取a的值然后进行自增操作 ++a:先自增再取a的值 --a和a--同理
(4)关系运算符:运算之后得到的都是布尔值
== != < > <= >=
(5)逻辑运算符:
逻辑与:&&,两个操作数都为true,返回true,有一个false就返回false
逻辑或:||,两个操作数都为false返回false,否则有一个为true,就返回true
取反:! 操作数为true返回false,操作数为false返回true
其中,&&和||都属于短路操作符,当使用多个条件逻辑与时,有一个表达式返回false,剩下的表达式就不再判断了,当使用多个条件逻辑或时,有一个表达式返回true,剩下的表达式就不再判断了,示例如下:
int a = 10; int b = 20; System.out.println(a > b && a/0 == 0);//false,不看第二个语句 System.out.println(a < b || a/0 == 0);//true,不看第二个语句
而, &和|不满足短路操作符,所有条件都会判断(了解),示例如下:
int a = 10; int b = 20; System.out.println(a > b & a/0 == 0);//报错,第二句除数为0 System.out.println(a < b | a/0 == 0);//报错,第二句除数为0
(6)位运算符(了解):直接在二进制为上进行操作的运算符
例如:10&20 10->01010,第一位是符号位;20->10100,按位与(&)都真则真,结果为00000
按位或(|)同理,两个二进制位,有一个1就返回1,都为0才返回0
按位取反(~):该位为0,转为1,该位为1,转为0,运行结果就是相反数-1,示例如下:
int a = 10; int b = -20; System.out.println(~a);//-11 System.out.println(~b);//19
按位异或(^):两个二进制相同返回0,不同返回1
小练习:一组数中,只有一个数出现一次,其余的数都出现两次,如何快速找到这个只出现了一次的数字? 例如10 20 10 20 30 40 50 50 40 解:10^=20^=10^=20 = 0 40^=50^=50^=40 = 0 即 0^=30^=0 = 30
(7)移位运算符:(了解)
10 << 1 二进制左移1位,相当于原数字*2(二进制由1010变为10100)
10 >> 1 二进制右移1位,相当于原数字/2 (二进制由1010变为101)
>>>表示无符号右移,但没有<<<运算符
(8)三目运算符(条件运算符):表达式1?表达式2:表达式3 当表达式1为true时取表达式2的值,否则取表达式3的值(示例如下)
int a = 10; int b = 20; int Max = a > b?a:b; int Min = a < b?a:b; System.out.println("最大值是" + Max); System.out.println("最小值是" + Min);
(9)运算符的优先级:建议不用刻意去记忆,需要先运算的,加个括号即可
System.out.println((10 < 20) && (20 < 30));
(10)关于注释的写法:
单行注释:一般用在方法中,给某一行做特殊说明(//) 快捷键为ctrl + /
多行注释: /* */
文档注释:一般用在方法和类的声明之前,告知用户该方法和类的使用规则/** */
三、程序结构
(1)顺序结构:单线程下按照代码的书写顺序一行一行向下执行
(2) if else分支:(语法和示例内容如下)
第一种类型 if(布尔表达式){
//满足该分支的代码块(只有if语句的情况)
}
第二种类型:if(布尔表达式){
//满足该分支的代码块
}else{
//条件不满足时执行的代码
}
第三种类型:if(布尔表达式){
//满足该分支的代码块(多分支语句的情况)
}else if(布尔表达式){
//满足该分支的代码块(多分支语句的情况)
}else{
//上述所有分支都不满足的情况
}
int num = 10; if (num % 2 == 0){ //利用if else语句判断是否为奇偶数 System.out.println(num + "是个偶数");//结果为10是个偶数 }else{ System.out.println(num + "是个奇数"); }
int num = 0; //利用多分支语句实现判断正负 if ( num < 0){ System.out.println(num + "是个负数"); }else if ( num > 0){ System.out.println(num + "是个正数"); }else{ System.out.println(num); }
(3)if分支语句的嵌套及注意事项:
经典练习:判断年份是否为闰年?(示例如下)
int year = 2000;
if (year % 100 == 0){
//说明此时的年份一定是100的倍数,判断是否为世纪闰年
if (year % 400 ==0){
System.out.println( year + "是世纪闰年");
}else {
System.out.println( year + "是普通年");
}
}else {
if (year % 4 ==0){
System.out.println(year + "是闰年");
}
else {
System.out.println(year + "是普通年");
}
}
注意事项:假设有一个两位数num,请统计当前这个num中9出现的次数?
int num = 99;
int count = 0;
//双if语句,可以统计出表达式1和表达式2同时满足的情况,而不同于if elseif表达式1和表达式2是互斥关系,一行代码只能走分支if或者else if
if (num % 10 == 9){
count ++;
}
if (num / 10 == 9){
count ++;
}
System.out.println("9一共出现了" + count + "次");
注意事项2:悬垂if else问题
int x = 10;
int y = 20;
//一段不规范代码,根据就近匹配原则else与 if (y == 20)匹配,所以没有任何输出,正确写法应使用大括号进行分隔
if (x != 10)
if (y == 20)
System.out.println("aaa");
else
System.out.println("bbb");
注意事项3:Java中分支的规范写法
if(表达式1){
}else if(表达式2){
}else{
}
注意事项4:高级编程语言中,一个分号代表一行语句的结束,要细心,编译出现问题时,不妨先擦亮眼睛好好看清楚,示例如下:
int x = 10;
if (x == 20);{
System.out.println("aaa");
}
(4)switch语句:(示例如下)
int day = 4;
//()内只能是int、char、String和enum类型的值或变量
//switch语句表示多重选择,应用较为局限,不如if else灵活
switch (day){
case 1:
System.out.println("星期一");
//当case不加break时,会从第一个case分支开始一直向下执行直到break为止或者把剩余的分支全部执行结束
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");//输出结果是星期四
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
default:
System.out.println("星期日");
}
(5)循环结构:(重点!!!)
while循环:示例如下,打印1-10
int num = 1; //表达式为true时,循环体代码就会执行,知道表达式返回false,循环体代码就不再执行 while (num <= 10 ){ System.out.println(num); num ++; }
小练习:使用while循环打印1-10的和
int num = 1; int ret = 0; //计算1-10的和,ret用于存储结果 while (num <= 10){ ret += num; num ++; } System.out.println(ret);
小练习:使用while循环计算10!
int num = 1; int ret = 1; while(num <= 10){ ret*=num; num++; } System.out.println(ret);
小练习:利用while循环,求1!+2!+3!+4!+5!(重点!!!)
int num = 1;
//计算每个阶乘的和
int ret = 0;
//表示num当前走到哪个数了
while (num <= 5){
//每次循环记录当前num的阶乘值,这个地方需要定义两个变量
int tempret = 1;
int tmp = 1;
while (tmp <= num){
tempret *= tmp;
tmp ++;
}
//此时tempret就存储了当前num的阶乘值
ret +=tempret;
num ++;
}
System.out.println(ret);
while的分号问题:示例如下:
int num = 0; while(num <= 10);{ System.out.println(num);//结果会陷入死循环 num ++; }
在循环中,break表示终止当前循环,continue表示跳过本次循环,继续下一次循环
小练习:找出100-200之间所有3的倍数
int num =100; while (num <= 200){ if (num %3 !=0 ){ num ++; continue; } System.out.println(num + "是3的倍数"); num ++; }
若此时需要跳出本次循环的通识跳出外层循环。return//终止当前方法的调用 或者使用break label
int num =100; label: while (num <= 200){ int a = 1; while (a <= 10){ if (a %3 == 0){ System.out.println(a); break label; } a ++; } } System.out.println("两次循环都终止了");//当a=3的时候,两次循环都终止了
for循环:for(初始化条件1;循环终止条件2;更新循环变量3){
//循环体代码4 执行顺序:1243243243……
}
小练习:用for循环打印1-10 和 for循环的拆解模式
for (int i=1;i<=10;i++){ System.out.println(i); } //其中快捷键fori课快捷生成for循环,循环变量是j,快捷键也是fori
int i = 1; for (;;){ if (i > 10){ break; } System.out.println(i); i ++; }
小练习:使用for循环求5!
int ret = 1; for (int i=1;i<=5;i++){ ret*=i; } System.out.println(ret);//120
小练习:使用for循环求1!+2!+3!+4!+5!(重点!!!)
int ret = 0; for (int i = 1; i <=5; i++) { int tmp = 1; for (int j = 1; j <=i; j++) { tmp*=j; } ret += tmp; } System.out.println(ret);
(6)系统输出:
System.out.println();//输出一个字符串,带换行 System.out.print();//输出一个字符串,不带换行 System.out.printf();//格式化输出,类似于c的printf
for (int i = 1; i<=10; i++){ System.out.print(i + "");//print输出一个字符串,不带换行 }
(7)系统输入:要使用Scanner类,必须要产生Scanner的对象,Scanner in = new Scanner(System.in);
Scanner scanner = new Scanner(System.in); //从键盘获取字符串输入 System.out.println("请输入您的姓名:"); String name = scanner.nextLine(); //从键盘获取一个整型 System.out.println("请输入您的年龄:"); int age = scanner.nextInt(); //从键盘获取一个小数 System.out.println("请输入您的工资:"); double salary = scanner.nextDouble(); System.out.println("您输入的信息如下:"); System.out.println("姓名:" + name +",年龄:" + age +",工资:" + salary);
从键盘循环读入数字:
Scanner scanner = new Scanner(System.in); int ret = 0; //从键盘读取的是一个整数才继续循环 while (scanner.hasNextInt()){ //若不是一个整数,hasNextInt->false int i = scanner.nextInt(); ret += i; } System.out.println(ret);