目录
前言
本文介绍了Java的运算符、标识符、二进制和位运算。
一、运算符
1、运算符介绍
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
2、算术运算符
对数值类型的变量进行运算的
正负号(+ -)
加减乘除(+ - * /)
/ 的用法(取整)
public class Main{
public static void main(String[] args){
System.out.println(10 / 4);
System.out.println(10.0 / 4);//10.0为double类型精度提升
double d = 10 / 4;//10/4等于2,又因要赋值给double类型,将2转为2.0
System.out.println(d);
}
}
运行结果:
2
2.5
2.0
取模(取余):11 % 9 == 2
public class Main{
public static void main(String[] args){
//%取余的本质:公式为a % b = a - a / b * b
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
1
-1
自增自减(前后):可作为独立语句使用(前自增与后自增等价),也可作为表达式使用
public class Main{
public static void main(String[] args){
int a = 2;
int b = a++;
System.out.println("a = "+a+","+" b = "+b );
a = 2;
int c = ++a;
System.out.println("a = "+a+","+" c = "+c );
a = 2;
int d = a--;
System.out.println("a = "+a+","+"d = "+d );
a = 2;
int e = --a;
System.out.println("a = "+a+","+"e = "+e );
}
}
运 行结果:
a = 3, b = 2
a = 3, c = 3
a = 1,d = 2
a = 1,e = 1
字符串相加(+)
例题:
1、
int i =1;
i = i++;//规则使用临时变量(1)temp = i(2)i = i + 1(3)i = temp
System.out.println(i);//1
结果为1
2、
int i = 1;
i = ++i;//使用临时变量,(1)i = i + 1;(2)temp = i;(3)i = temp;
System.out.println(i);//结果为2
3、关系运算符(比较运算符)
- 关系运算符的结果都是一个boolean值,为true或false
- 关系表达式通常用在if结构的条件中或循环结构的条件中
- 关系运算符组成的表达式为关系表达式
==相等
!= 不相等
大于、小于、大于等于、小于等于
instance of():检查是否是类的对象
public class Main{
public static void main(String[] args){
int a = 9;
int b = 8;
System.out.println(a > b);
System.out.println(a < b);
System.out.println(a == b);
System.out.println(a >= b);
System.out.println(a <= b);
System.out.println(a != b);
boolean flag = a > b;
System.out.println(flag);
}
}
运行结果:
true
false
false
true
false
true
true
4、逻辑运算符
- 用于连接多个条件(多个关系表达式),最终的结果也是一个boolean值
- 包含逻辑与(& 或 &&)、逻辑或(| 或 ||)、逻辑非(!)、逻辑异或(^)
- 逻辑与两个条件都为真,结果才为真;逻辑或两个都为假,结果才为假。
- 具有短路特性:短路与(&&)、短路或(||)
- 短路特性:短路与(&&)为有一个false即为false;短路或(||)为有一个true即为true。意即前一个条件为假(真),则不再执行判断第二个条件,提高了程序效率,避免了不必要的计算
- 开发中通常使用短路与和短路或
public class Main{
public static void main(String[] args){
int a = 9;
int b = 8;
boolean flag1 = (a < b) && (a++ == b);//短路与
System.out.println(a);
boolean flag2 = (a < b) & (a-- == b);//非短路与
System.out.println(a);
System.out.println(flag1);
System.out.println(flag2);
}
}
运行结果:
9
8
false
false
public class Main{
public static void main(String[] args){
int a = 9;
int b = 8;
boolean flag1 = (a > b) || (a++ == b);//短路或
System.out.println(a);
boolean flag2 = (a > b) | (a-- == b);//非短路或
System.out.println(a);
System.out.println(flag1);
System.out.println(flag2);
}
}
运行结果:
9
8
true
true
public class Main{
public static void main(String[] args){
//取反操作
System.out.println(60 > 20);//T
System.out.println(!(60 > 20));//F
// 逻辑异或,两边结果相异时为true
boolean b = (10 > 1) ^ (3 < 5);
System.out.println("b = "+b);
}
}
运行结果:
true
false
b = false
5、赋值运算符(=)
- 将某个运算后的值赋给指定的变量
- 分类:基本赋值运算符(=);复合赋值运算符(+=,-=,/=,*=,%=)
- a += b => a = a + b;a -= b => a = a - b
- 特点:(1)运算顺序从右往左(2)赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值(3)复合赋值运算符会进行类型转换:byte b = 2;b += 3;b++;
public class Main{
public static void main(String[] args){
int n = 10;
n+=4;
System.out.println(n);
n/=3;
System.out.println(n);
}
}
运行结果:
14
4
public class Main {
public static void main(String[] args) {
//复合赋值运算符的类型转换
byte b = 2;
b += 3;//b = (byte)(b+3)
b++;//b = (byte)(b+1)
}
}
6、三元运算符
- 基本语法:条件表达式 : 表达式一 ? 表达式二
- 若条件为true,则结果为表达式一;若为false,则结果为表达式二。
- 表达式一和二必须为可以赋值给接收变量的类型(或者可以自动转换或者强制转换)
- 三元运算符可以转为if-else语句
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 20;
int result = a > b ? a++ : --b;
System.out.println(result);//结果为19
}
}
public class Main {
public static void main(String[] args) {
//表达式一和二必须为可以赋值给接收变量的类型(或者可以自动转换或者强制转换)
int a = 10;
int b = 20;
int c = a > b ? (int)1.1 : (int)3.4;
double d = a > b ? a : b + 3;//满足int => double自动转换
System.out.println(c);//3
System.out.println(d);//23.0
}
}
public class Main {
public static void main(String[] args) {
//三元运算符求三个数最大值
int a = 10;
int b = 8;
int c = 30;
//1、先得到a、b中最大数保存到max1
//2、再求max1与c中的最大数,保存到max2
int max1 = a > b ? a : b;
int max2 = c > max1 ? c : max1;
System.out.println(max2);
}
}
//一条语句实现
int max = (a>b?a:b) > c ? (a>b?a:b) : c;
二、运算符优先级
运算符具有不同的优先级,即表达式运算中的运算顺序。
只有单目运算符(对单个数进行操作)、赋值运算符是从右向左运算的。
来源:https://www.runoob.com/java/java-operators.htmlhttps://www.runoob.com/java/java-operators.html
三、Java的标识符
1、命名规则和规范
标识符概念:
- Java中对各种变量、方法、类等命名时使用的字符序列叫做标识符
- 凡是自己取名字的地方即为标识符
命名规则(必须遵守):
- 英文字母的大小写、数字、_(下划线)、$
- 数字不可作为开头
- 不可以使用关键字和保留字,但可以包含
- Java严格区分大小写,无长度限制
- 标识符不能包含空格
标识符的命名规范(提倡,更专业):
- package包名:多单词组成时,所有字母小写 //com.abc.java
- 类名、接口名:多单词组成时,所有单词的首字母大写 //XxxYyy
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写 //xxxYyyZzz(驼峰命名法)
- 常量名:所有字母都大写,多单词时每个单词间用下划线连接 //TAX_RATE
2、关键字和保留字
关键字:被Java语言赋予了特殊含义,用作专门用途的字符串(关键字的字母均为小写)
保留字:在 Java 中,保留字是具有特定用途和含义,被编程语言保留,不能用作标识符(如变量名、方法名、类名等)的单词。
3、键盘输入语句
接受用户输入:Scanner扫描器(对象)
- 导入该类所在的包
- 创建该类的对象
- 调用里面的功能
import java.util.Scanner;
//Scanner类表示一个简单的文本扫描器
public class Main {
public static void main(String[] args) {
//new创建Scanner类的对象sc
Scanner sc = new Scanner(System.in);
System.out.println("Enter number: "+sc.nextInt());
}
}
四、二进制和位运算
1、进制
二进制:0、1 0b或0B开头
八进制:0-7 以数字0开头
十进制:0-9
十六进制:0-9 A(10)-F(15) 以0x或0X开头,A-F不区分大小写
2、进制的转换
第一组:(转十进制:从最右边开始,将每个位上的数提取出来,乘以2(8、16)的位数减一次方)
二进制转十进制
0b1011 => 1 * 2^0+1 * 2^1+0 * 2^2+1 * 2^3 = 11
八进制转十进制
0234 => 4 * 8^0+3 * 8^1+2 * 8^2 = 156
十六进制转十进制
0x23A => 10 * 16^0+3 * 16^1+2 * 16^2 = 10+48+512 = 570
第二组:
十进制转二进制(将该数不断除以二,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制)
34 => 0b00100010
十进制转八进制(同上,除以八)
131 => 0203
十进制转十六进制(除16)
237 => 0xED
第三组:
二进制转八进制(8 = 2^3)
将二进制数从低位开始,每三位分为一组,转为对应八进制数即可
0b11010101 => 0325
二进制转十六进制(16 = 2^4)
将二进制数从低位开始,每四位分为一组,转为对应十六进制数即可
0b11010101 => 0xD5
第四组
八进制转二进制
将八进制的每一位转为三位的二进制数(二转八进制的逆操作)
0237 => 0b10011111
十六进制转二进制
将十六进制的每一位转为四位的二进制数
0x23B => 0b001000111011
3、位运算
原码、反码、补码
对有符号数而言:
1、二进制最高位是符号位,0代表正,1代表负
2、正数的原码、反码、补码均相同
3、负数的反码 = 它的原码符号位不变,其他位取反
4、负数的补码 = 它的反码+1,负数的反码 = 负数的补码-1
5、0的反码补码都是零
6、Java中的数都是有符号的
7、计算机在运算中,都是以补码形式运算的
8、看真正的运算结果时,要看原码
按位取反(~)0变1,1变0(连同符号位)
按位与(&)两位都为1,结果为1,否则为0
按位或(|)两位有一个为1即为1
按位异或(^)两位一个1一个0,结果为1
public class Main {
public static void main(String[] args) {
//2的补码:00000000 00000000 00000000 00000010
//3的补码:00000000 00000000 00000000 00000011
//2&3 00000000 00000000 00000000 00000010 =2
System.out.println(2&3);//2
//-2的原码:10000000 00000000 00000000 00000010
//-2的反码:11111111 11111111 11111111 11111101
//-2的补码:11111111 11111111 11111111 11111110
//~-2:00000000 00000000 00000000 00000001
System.out.println(~-2);//1
//00000000 00000000 00000000 00000011
System.out.println(2|3);//3
//00000000 00000000 00000000 00000001
System.out.println(2^3);//1
}
}
位运算符:
>>算术右移:低位溢出,符号位不变,并用符号位补溢出的高位
<<算术左移:符号位不变,低位补零
>>>逻辑右移也叫无符号右移,运算规则:低位溢出,高位补零
没有<<<符号
public class Main {
public static void main(String[] args) {
int a =1>>2;
int b =1<<2;
System.out.println(a);//0
System.out.println(b);//4
System.out.println(15>>2);//15/2/2 = 3
System.out.println(3>>>2);//0
System.out.println(-1<<2);//-4
System.out.println(-1>>2);//-1
}
}
补充:
计算机在运算中以补码形式进行运算主要有以下几个重要原因:
- 简化运算:将减法运算转化为加法运算,从而简化了计算机硬件中运算电路的设计。在补码系统中,减去一个数可以通过加上该数的补码来实现,这样就可以利用已有的加法器电路来完成减法运算,而无需单独设计减法器,提高了运算效率。
- 统一处理符号位:补码可以将符号位和数值位一起进行运算,无需单独处理符号位,降低了运算的复杂度。在原码和反码系统中,符号位需要单独考虑,增加了运算的复杂性。
- 解决零的表示问题:在原码和反码中,零有两种表示方式(+0和-0),这会给计算机的逻辑判断带来一些问题。而在补码中,零只有一种表示形式,消除了这种二义性,使计算机的运算和逻辑判断更加清晰和准确。
- 便于表示负数:补码可以更方便地表示负数,并且能够表示的负数范围比原码和反码更大。这对于处理有符号数的运算非常重要,尤其是在需要表示较小的负数时。
- 提高运算的可靠性:补码的运算规则相对简单,并且对于溢出等情况有较好的处理机制,能够提高运算的可靠性和稳定性。
总结
重要知识点:
- 逻辑运算符中的短路与、短路或
- 标识符命名规范
- 进制转换