一、语言基础---2.类型和运算
(一)变量和常量
026、字面量和常量
常量:在程序中固定不变的值
//需求常量的讲解
public class ConstDemo
{
//主方法:程序的入口
public static void main(String[] args)
{
/*
字面值常量:比如整数常量1,2,3,小数常量3.14,布尔常量false、true等
字面量,直接给出的值(可以是整数、小数、true、false),直接量
*/
System.out.println(123); //打印出常量:123
System.out.println(1.23);
System.out.println(true);
}
}
定义的final变量:
027、引出变量
//引出变量
public class ExportVarDemo
{
public static void main(String[] args)
{
/*
需求,求两个操作数6和3的和,差,积,商
*/
int x = 6;
int y = 3;
System.out.println(x + y);
System.out.println(x - y);
System.out.println(x * y);
System.out.println(x / y);
//开发中唯一在变化的是需求一直在变
/*
需求,求两个操作数8和5的和,差,积,商
*/
x = 8;
y = 5;
System.out.println(x + y);
System.out.println(x - y);
System.out.println(x * y);
System.out.println(x / y);
}
}
028、变量的定义和基本使用
变量:表示存储空间,可用来存放某一类型的常量,没有固定的值,可重复使用,可存储某种类型的未知数据
变量的特点:
1)占据着内存中的某一块存储区域
2)有自己的名称(变量名)和类型(数据类型)
3)可以被重复使用
4)该区域的数据可以在同一类型范围内不断变化
//变量操作
public class VarDemo
{
public static void main(String[] args)
{
/*
变量的定义格式:
1)数据类型 变量名;
如:int age
2)给变量赋值(初始化)
变量名 = 声明变量类型的值;
如:age = 17
3)在声明变量的时候,并做初始化
如:int age = 17
变量必须初始化(赋值)之后才能使用,初始化才是真正的在内存分配空间
*/
int age; //定义一个int类型的变量,变量名为age
age = 17; //把17赋值给age
System.out.println(age); //打印的是该变量当前所赋予的值
age = 18; //把17赋值给age
System.out.println(age); //打印的是该变量当前所赋予的值
//同时定义多个变量
int a,b,c;//不推荐
/*
int a;
int b;
int c;
*/
}
}
029、变量的分类-作用域-使用规则
//变量操作
public class VarDemo2
{
static int age = 17; //成员变量/字段
public static void main(String[] args)
{
/*
变量的分类;
根据定义的位置:
1.成员变量/字段:直接定义在类的{}中的变量(方法外)
VarDem2.java:15: 错误: 无法从静态上下文中引用非静态 变量 age
现在定义成员变量,都使用static修饰
2.局部变量:定义在方法内的变量
除了成员变量的都是局部变量
变量的作用域:可以起作用的领域,根据变量所在的{}来判断
1.成员变量/字段:在所定义的类中起作用
2.局部变量:从定义的那一个地方开始到紧跟着结束的}之间
*/
int age = 18;
System.out.println(age); //打印的是18,就近
}
}
变量使用规则:
1)变量必须先声明,并且初始化后才能使用
2)声明变量必须有数据类型
3)同一作用域内变量不能重复定义
使用局部变量:先声明,再初始化,最后使用,可以重复使用
030、Java表达式
表达式(expression):由数字、运算符、数字分组符号()、常量、变量等以能求得结果的有意义排列的组合
class ExpressinDemo
{
public static void main(String[] args)
{
System.out.println(1 + 2 + 3);
System.out.println("...............");
int result = 1 + 2 + 3;
System.out.println(result);
System.out.println("...............");
int a = 1;
int b = 13;
int c = 7;
int result2;
result2 = (a + b)/c;
System.out.println(result2);
}
}
(二)数据类型
031、数据类型和分类
在Java中数据类型分为两大类
1)基本(原生)数据类型(共8个):
1.数值型:
整数类型:byte,short,int,long
不同的整数类型在内存占用的内存空间大小是不一样的
小数类型:float,double
2.字符型:char:字母/符号
3.布尔型:boolean:true,false
2)引用(对象)数据类型:类、接口、数组
一个字节8位,最高位是符号位
032、布尔类型(boolean)
布尔类型(boolean):通常用于逻辑运算和程序流程控制(条件/选择/循环)
该类型的值只能是true或false,表示真或假。不能用0和1表示
//boolean数据类型
public class BooleanDemo
{
public static void main(String[] args)
{
//boolean类型的常量:true、false
System.out.println(true); //打印出:true
System.out.println(false); //打印出:false
//boolean类型的变量
boolean isMan = true;
System.out.println(isMan); //打印出:true
//给isMan变量重新赋值
isMan = false;
System.out.println(isMan); //打印出:false
//isMan = 1; BooleanDemo.java:15: 错误: 不兼容的类型: int无法转换为boolean
}
}
033、整数类型byte-short-int-long
byte-short-int-long唯一的不同就是存储空间的容量大小不一样,根据具体需要存储的数据去选择合适的数据类型
java整型常量默认是int型,默认情况下一个整型的字面量默认是int类型
//整数类型byte-short-int-long
public class IntegerDemo
{
public static void main(String[] args)
{
/*
1.二进制整数:0B或0b开头(java7的新特性),如:int a = 0b110;
2.八进制整数:要求以0开头,如:int a = 012;
3.十进制整数:如: int a = 17;
4.十六进制整数:要求0X或0x开头,如:int a = 0x12;
*/
//表示10进制的常量
System.out.println(110);
//表示2进制的常量
System.out.println(0b01101110); //byte的常量
System.out.println(0b00000000_01101110); //short的常量
System.out.println(0b00000000_00000000_01101110); //int的常量
//表示8进制的常量
System.out.println(0156);
//表示16进制的常量
System.out.println(0x6E);
//整数的变量
//整数类型 变量 = 整数值的常量
//byte age = 128; //IntegerDemo.java:23: 错误: 不兼容的类型: 从int转换到byte可能会有损失
byte age = 127;
System.out.println(age);
//long型变量后加上“l”或“L”,建议使用“L”
long day = 127L;
System.out.println(day);
}
}
034、小数类型float-double
小数类型又称为浮点类型,float表示单精度小数,double表示双精度小数,两者都不能表示精确的小数
BigDecimal可以表示任意精度的数据
//float、double类型:
public class DecimalDemo
{
public static void main(String[] args)
{
//小数常量(默认是double类型)
System.out.println(3.14); //double类型的常量
System.out.println(3.14F); //float类型的常量后面要加“f”或“F”
System.out.println(3.14E2); //科学计数法 //314.0
//小数变量
double pi = 3.14;
//float pi2 = 3.14; //DecimalDemo.java:13: 错误: 不兼容的类型: 从double转换到float可能会有损失
float pi2 = 3.14F;
double a = 1.00000000000000123;
double b = 1.00000000000000123000001;
System.out.println(a + b); //打印结果2.0000000000000027,与实际结果是不一样的
}
}
035、字符类型-char
char类型(字符、字母、符号):表示16位的无符号整数或Unicode字符,Java对字符采用Unicode字符编码,[0,65535]
Unicode收集了世界上所有语言文字中的符号,Java的字符占2个字节,可以表示一个汉字
什么是编码?
计算机只能表示0和1两个数,规定使用一个数字表示一个特定的字符,比如:a用97表示
char前256个字符和ASCII码中的字符重复
ASCII码表:
char常量有3种表示形式
① 直接使用单个字符来指定字符常量,格式如'◆'、'A'、'7':此时得用单引号直接表示符号
② 直接作为十进制整数数值使用,但是数据范围在[0,65535],格式如97,但是打印出来的值依然是ASCII码表示
③ 和②一样,只不过表示的是16进制的数值,格式如'\uX',X表示16进制整数:如97的16进制是61。表示为'\u0061'打印出来也是a
//字符
public class CharDemo
{
public static void main(String[] args)
{
//char的常量
char c1 = 'A'; //直接表示符号
System.out.println(c1); //A
char c2 = 65; //表示符号对应的10进制顺序
System.out.println(c2); //A
char c3 = '\u0041'; //表示符号对应的16进制顺序,表示16进制时,需要补全4位
System.out.println(c3); //A
}
}
036、最常用的应用类型-String
String是一个类,表示字符串,字符串要用"",连接字符串用“+”符号
字符串与任意数据类型连接在一起都是字符串类型
//字符串
public class StringDemo
{
public static void main(String[] args)
{
//String的常量
System.out.println("Hello"); //Hello
//String的变量
String name = "龙17"; //表示3个符号
System.out.println("name=" + name); //name=龙17
//输出“hello”
System.out.println("\"Hello\""); //要用转义符
name = "我是"+"lh"+"今年17";
System.out.println(name); //我是lh今年17
System.out.println("Hello"+7+8); //Hello78
System.out.println("Hello"+(7+8)); //Hello15
}
}
(三)基本数据类型转换
037、数据过大和溢出
溢出:要表示的数据超出数据类型的临界范围,溢出发生后程序没有做数据范围检查,会出现数据紊乱的情况
int(有4个字节),intMax=2147483647
//溢出紊乱
public class OverFlowDemo
{
public static void main(String[] args)
{
int intMax = 2147483647;
System.out.println("int最大值:"+ intMax);
intMax = intMax + 1; //让intMax变量的值加1后,再赋值给intMax
System.out.println(intMax); //-2147483648
/*
数据紊乱的原因:
二进制:0b01111111_11111111_11111111_11111111
0b00000000_00000000_00000000_00000001
--------------------------------------------
0b10000000_00000000_00000000_00000000
*/
int intMin = -2147483648;
System.out.println("int最小值:"+ intMin);
intMin = intMin - 1; //让intMax变量的值加1后,再赋值给intMax
System.out.println(intMin); //2147483647
}
}
数据紊乱的原因:
038、基本类型的自动转换
boolean类型不属于数值类型,不参与转换
不同类型的数据类型看成是不同容量的容器
byte是1个字节,short是2个字节
自动类型转换(隐式类型转换):把小数据范围类型的数值或变量赋值给另一个大数据范围类型变量,系统可以完成自动类型转换
039、基本类型的强制转换
强制类型转换(显式类型转换):加上强制类型转换符,可能会造成数据精度的降低或溢出
040、表达式类型的自动提升
表达式中包含多个基本数据类型(boolean除外)的值时,整个算术表达式的数据类型会在运算时出现类型自动提升
说有的byte、short、char被自动提升成int类型
String和任意数据使用+连接起来都是String类型
//类型转换
public class TypeConvertDemo
{
public static void main(String[] args)
{
/*
byte的二进制: 00000101
short的二进制:00000000_00000101
int的二进制: 00000000_00000000_00000101
*/
byte b1 = 5;
short s1 = b1; //小转换成大
int i1 = s1;
long L1 = i1;
float f1 = L1;
double d1 = f1;
System.out.println(d1); //5.0
//char c1 = s1; //TypeConvertDemo.java:19: 错误: 不兼容的类型: 从short转换到char可能会有损失
//一般byte、short、char不参与转换,直接把byte、short、char付给int类型
//-------------------------------------------------------------
double pi = 3.14;
int i2 = (int)pi;
System.out.println(i2); //3
//整数常量默认是int类型,小数常量默认是double类型
byte b2 = 125; //编译器发现125在byte的范围内,底层偷偷地转换了
//改成128就不可以了,TypeConvertDemo.java:25: 错误: 不兼容的类型: 从int转换到byte可能会有损失
byte b4 = 25; //编译时检查
b4 = b4 + 3; //运行时计算,TypeConvertDemo.java:28: 错误: 不兼容的类型: 从int转换到byte可能会有损失
}
}
(四)运算符
041、算术运算符
加号(+):两个字符相加得到的是ASCII码表值,两个字符串相加表示将两个字符串连接在一起,组成新的字符串
//算术运算符
public class ArithmeticOperationDemo
{
public static void main(String[] args)
{
//操作数
System.out.println(10 + 2);
System.out.println(10 - 2);
System.out.println(10 * 2);
System.out.println(10 / 2);
System.out.println("--------------------------");
//操作字符
System.out.println("A" + "B"); //AB
System.out.println('A' + 'B'); //131
System.out.println(10 / 3); //3
System.out.println(10 / 9 * 9); //9 整数在使用除号操作时,得到的结果仍为整数(小数部分忽略)
//当整数除以0,会引发算术异常
//System.out.println(10 / 0); //Exception in thread "main" java.lang.ArithmeticException: / by zero
System.out.println(10.0 / 0); //Infinity,正无穷大
System.out.println(-10.0 / 0); //-Infinity,负无穷大
System.out.println(0.0 / 0.0); //NaN,Not a Number ,自己都不等于自己
int a = 5;
System.out.println(a == a); //true
double b = 0.0 /0.0;
System.out.println(b == b); //false
//取模%,模数的符号忽略不计,结果的正负取决于被模数
System.out.println(10 % 3); //1
}
}
042、++和--
++和--都只能操作变量,不能操作常量
//++和--
public class ArithmeticOperationDemo2
{
public static void main(String[] args)
{
//++前置:++a,表示a变量自身先加1,再运算
int a1 = 5;
int b1 = ++ a1; //a1=a1+1, "="是赋值
System.out.println("a1="+a1+",b1="+b1); //a1=6,b1=6
System.out.println("=========================");
//++后置:a++,表示a变量自身先加1,把递增之前的值(原始值)拿去做运算
int a2 = 5;
int b2 = a2++; //a2(5) +1
System.out.println("a2="+a2+",b2="+b2); //a2=6,b2=5
}
}
043、自增面试题分析
//面试题分析
public class ArithmeticOperationDemo3
{
public static void main(String[] args)
{
//面试题一
/*
int num1 = 1;
num1 = num1 ++; //原始值是1,后置是把原始值赋给num1
System.out.println(num1); //1
int num2 = 1;
num2 = ++ num2; 原始值是1,前置是把运行结果赋给num1
System.out.println(num2); //2
*/
//面试题二
int i = 5;
i ++;
System.out.println("i="+i); //i=6
++ i;
System.out.println("i="+i); //i=7
int a = ++ i;
System.out.println("i="+i+",a="+a); //i=8,a=8
int b = i ++;
System.out.println("i="+i+",b="+b); //i=9,a=8
}
}
044、赋值运算符
//赋值运算
public class AssignmentOperationDemo
{
public static void main(String[] args)
{
// = 给变量赋值
String name;
name = "lh"; //赋值
//1.声明一个int类型变量age;2.在内存中存储常量数据17;3.把17赋予age变量
int age = 17; //声明一个int类型变量,并设置初始值为17
System.out.println("----------------");
// += 加等;中间不能打空格,自带隐式类型转换
int a = 10;
a += 5; //等价于a=(int)a + 5;
System.out.println(a); //15
short s = 30;
//s = s + 5; //AssignmentOperationDemo.java:17: 错误: 不兼容的类型: 从int转换到short可能会有损失
s +=5; //等价于s = (short)(s + 5);
System.out.println(s); //35
// -= 减等
int b = 10;
b -= 5; //等价于b=b-5
System.out.println(b); //5
// *= 乘等
int c = 10;
c *= 5; //等价于c=c*5
System.out.println(c); //50
// /= 除等
int d = 10;
d /= 5; //等价于d = d / 5
System.out.println(d); //2
// %= 模等
int e = 10;
e %= 3; //等价于e = e % 3
System.out.println(e); //1
}
}
045、比较运算符
比较运算符:比较两个常量或变量之间的关系,结果是boolean类型
//比较运算符
public class ComparisonOperationDemo
{
public static void main(String[] args)
{
// == 相等于
boolean b1 = 4 == 4;
System.out.println(b1); //true
// != 不等于
boolean b2 = 4 != 4;
System.out.println(b2); //false
// < 小于
boolean b3 = 4 < 4;
System.out.println(b3); //false
// > 大于
boolean b4 = 4 > 4;
System.out.println(b4); //false
// >= 大于等于
boolean b5 = 4 >= 4;
System.out.println(b5); //true
// <= 小于等于
boolean b6 = 4 <= 4;
System.out.println(b6); //true
}
}
046、三元运算符
//比较运算符
public class TernaryOperationDemo
{
public static void main(String[] args)
{
//给出一个小数,求出四舍五入后的结果
/*
1.先获取3.49的整数部分
2.再获取小数部分:3.49-3=0.49
3.把0.49和0.5作比较,小于则取整数部分,大于则取整数部分加1
三元(三目)运算符:
数据类型 变量=boolean表达式 ? 值1 :值2
如果:boolean表达式结果为true,三元运算表达式的结果就是值1;
boolean表达式结果为false,三元运算表达式的结果就是值2;
*/
double num = 3.49;
int num1 = (int)num; //整数部分
double num2 = num - num1; //小数部分
int result = num2 >= 0.5 ? num1 + 1 :num1; //判断大小关系不要用减法,因为可能会存在数据溢出的情况
System.out.println(result); //3
//两个数求最大值/最小值
int a = 20;
int b = 10;
int max = a >= b ? a : b;
System.out.println("max:" + max); //max:20
int min = a <= b ? a : b;
System.out.println("min:" + min); //min:10
//判断奇偶数,只需要判断除以2之后的余数是否为0,是0就是偶数;不能直接判断余数是否为1
int c = 7;
String ret = c % 2 == 0 ? "偶数" : "奇数";
System.out.println(ret); //奇数
}
}
047、分页业务逻辑算法
//三元运算符在分页业务逻辑中的使用
public class PageDemo
{
public static void main(String[] args)
{
//一共有46条数据,每页最多10条,计算一共多少页
int totalCount = 46;
int pageSize = 10;
//总页数
int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize +1;
System.out.println(totalPage); //5
int currentPage = 5; //当前页
//上一页,注意边界问题
int prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;
System.out.println(prevPage); //4
//下一页
int afterPage = totalPage - currentPage > 1 ? currentPage + 1 : currentPage;
System.out.println(afterPage); //5
}
}
048、逻辑运算符
//逻辑运算
public class LogicOperationDemo
{
public static void main(String[] args)
{
/*
Boolean表达式A 与 Boolean表达式B,只要其中一个表达式为false,结果就是false
& AND位与,并且,如果A表达式为false,也会判断B表达式,再返回false,操作二进制时用
&& AND短路与,如果A表达式为false,则不再判断B表达式,直接返回false,效率更高
*/
System.out.println(true & true); //true
System.out.println(false & true); //false
System.out.println(true & false); //false
System.out.println(false & false); //false
System.out.println("---------------------");
//System.out.println(false & (1 / 0 == 1)); //Exception in thread "main" java.lang.ArithmeticException: / by zero,有错误,证明(1 / 0 == 1)执行了
System.out.println(false && (1 / 0 == 1)); //false ,正常返回结果,证明没有再执行(1 / 0 == 1)
/*
Boolean表达式A 或 Boolean表达式B,只要其中一个表达式为true,结果就是true
| OR或 如果A表达式为true,也会判断B表达式,再返回true
|| OR短路或 如果A表达式为true,则不会再判断B表达式,直接返回true,效率更高
*/
System.out.println(true | true); //true
System.out.println(false | true); //true
System.out.println(true | false); //true
System.out.println(false | false); //false
System.out.println("---------------------");
//System.out.println(true | (1 / 0 == 1)); //Exception in thread "main" java.lang.ArithmeticException: / by zero
System.out.println(true || (1 / 0 == 1)); //false
// ! Not 非,取反
System.out.println(! false); //true
System.out.println(!! false); //false
System.out.println(! true); //false
System.out.println(!! true); //true
System.out.println("---------------------");
// ^ XOR异或 ,两个表达式相同则为true,相反则为false
System.out.println(true ^ true); //false
System.out.println(true ^ false); //true
System.out.println(false ^ true); //true
System.out.println(false ^ false); //false
}
}
049、位运算符
位运算符:操作二进制位
boolean的true和false在底层使用一位的1和0来表示
//位运算符
public class BitOperationDemo
{
public static void main(String[] args)
{
/*
& 按位与 参与运算的两个数,若相应位数的值都是1,则该结果值是1,否则都为0
| 按位或 参与运算的两个数,若相应位数的值只要有一个1,结果就是1
^ 异或 参与运算的两个数,若相应位数的值相同结果为0,否则为1
~ 取反 表示把每个二进制位的1换成0,把0换成1
例如:3的二进制 00000011
5的二进制 00000101
00000011
00000101
----------------------
& 00000001 =1
| 00000111 =1+2+4=7
^ 00000110 =0+2+4=6
5的二进制 00000101
----------------------
~5 11111010 ??????
*/
System.out.println(3 & 5); //1
System.out.println(3 | 5); //7
System.out.println(3 ^ 5); //6
System.out.println(~ 5); //-6
}
}
050、移位操作
//移位操作
public class BitOperationDemo2
{
public static void main(String[] args)
{
/*
<< 左移位 将操作数整体左移指定位数,左移之后的空用“0”补充
>> 右移位 将操作数整体右移指定位数,右移之后的空用“符号位”补充
若是正数用“0”补充,是负数用“1”补充(操作负数:取反,求补,操作,取反,求补)
>>> 无符号移位 将操作数整体右移指定位数,右移之后的空用“0”补充
*/
/*
2的二进制 00000000_00000000_00000000_00000010
------------------------------------------------
2 << 3 00000_00000000_00000000_00000010000 =2的4次方=16
16 >> 3 00000000_00000000_00000000_00000010
-16 >>3
-16的原码:10000_00000000_00000000_00000010000
反码:11111_11111111_11111111_11111101111
补码;11111_11111111_11111111_11111110000 (补码=反码+1)
右移三位: 11111111_11111111_11111111_11111110 (-2的补码)
*/
System.out.println(2 << 3); // 16 2左移3位
System.out.println(16 >> 3); //2
System.out.println(-16 >> 3); //-2
System.out.println(-16 >>> 3); //536870910
}
}
051、交换两个变量值练习
//交换两个变量的值
public class SwapVarDemo
{
public static void main(String[] args)
{
//法1:增加一个临时变量
int a = 10;
int b = 20;
System.out.println("a="+ a +",b="+ b); //a=10,b=20
int temp = a; //把a的值赋给临时变量temp
a = b; //把b的值存储到a中
b = temp;
System.out.println("a="+ a +",b="+ b); //a=20,b=10
//不使用第三个变量,交换两个变量的值
/*
//法2:算术运算,通过数轴上,距离
int a = 5;
int b = 7;
a = b - a;
b = b - a;
a = b + a;
System.out.println("a="+ a +",b="+ b); //a=7,b=5
*/
/*
//法3:位运算,通过异或运算使数据中的某些位翻转,其他位不变(任意一个数与任意一个给定的值连续异或两次,值不变)
int a = 9;
int b = 7;
a = b ^ a;
b = b ^ a;
a = b ^ a;
System.out.println("a="+ a +",b="+ b); //a=7,b=9
*/
}
}
052、运算符的操作优先级
053、小结