运算符
算术运算符
- 参与算术运算的操作数必须是整数、浮点数或char
- 一元算术运算符:正负号+、-
int i=+5;
System.out.println(-i);
System.out.println(-(-i));
- 四则运算:+、-、*、/,注意乘除优先于加减
- 取余(取模):%
- 整数的除法运算结果一定是整数,小数部分会被直接舍弃
int a = 5;
int b = 2;
System.out.println(a/b);//2
System.out.println(a/b*1.0);//2.0
System.out.println(1.0*a/b);//2.5
- 取余结果的符号与做操作数一致,取余运算结果通常用于判定某一个数字是否是另一个数字的倍数。也常用于判断某个数字的奇偶性
- 在使用取余进行奇偶判定时,应该使用x%2==0为true时是偶数,为false时是奇数(使用偶判定,不使用奇判定)
x=10;
System.out.println(x%2==0);
x=11;
System.out.println(x%2==0);
x=-11;
System.out.println(x%2==0);
int a = 7;
int b = 4;
System.out.println(a%b);
System.out.println(a%-b);
System.out.println(-a%b);
System.out.println(-a%-b);
char='A';
System.out.println(c+32);//自动 类型提升 为int类型
System.out.println((char)c+32);//强制类型转换
- boolean类型不能参与算术运算
System.out.println(100+true);
- 自增:++(前缀、后缀两种形式);自减:--(前缀、后缀两种形式)
- 自增、自减运算是一元运算符,参与运算的操作数必须是变量
- 单独调用自增自减无论是前缀还是后缀形式,结果都是在原值的基础上加1或减1
int i=10;
i++;//i=i+1;
System.out.println("i="+i);
int i=10;
i--;//i=i-1;
System.out.println("i="+i);
int i=10;
++i;//i=i+1;
System.out.println("i="+i);
int i=10;
--i;//i=i-1;
System.out.println("i="+i);
- 自增自减运算如果是其他表达式的某一部分时,就要区分其前缀和后缀的不同
- 前缀形式是先运算,后用值(++i、--i)
- 后缀形式是先用值,后运算(i++、i--)
int i =10;
int j=i++;//j=i;i=i+1;
System.out.println("i="+i);
System.out.println("j="+j);
System.out.println("------------------------------------------------------");
i=10;
System.out.println(5+i++);
System.out.println(i);
i=10;
System.out.println(2*++i+i--);
System.out.println(i);
int a = 30;
i=10;
j=i++ +a- ++i*3;
System.out.println(i);
System.out.println(j);
- 当自增自减运算为某一表达式一部分时 其DOS命令所显示的相关计算即内部计算存储调用形式(原因)
public class Demo003{
public static void main(String[]args){
0:bipush 10
2:istore_1
3:iinc1,1
int i=10;
i++
0:bipush 10
2:is0tore_1
3:iinc1,1
int i=10;
++i;
0:bipush 10
2:istore_1
3:iload_1
4:innc1,1
7:istore_2
int i=10;
int j=i++;
0:bipush 10
2:istore_1
3:innc1,1
6:iload_1
7:istore_2
int i=10;
int j=++i;
}
}
关系运算符
- 关系运算符:又叫比较运算符,用于操作数之间的比较。
- 结果一定是true或false
- 关系运算符包括:==、!=、>、>=、<、<=
public class Demo005{
public static void main(String[]args){
int a=10;
int b=5;
int c=15;
System.out.println(a==5);
System.out.println((a+b)==c);
System.out.println(true==false);
System.out.println('a'=='A');
}
}
- 以下语句输入false,因为1.1-0.8=0.30000000000000004
System.out.println((1.1-0.8)==0.3);
System.out.println("-----------------------------------");
System.out.println(a<b);
System.out.println(a<c);
System.out.println(a<=(c-b));
System.out.println(a>=(c-b));
System.out.println("-------------------------------------");
System.out.println(a!=b);
System.out.println(a!=(c-b));
逻辑运算符
- 逻辑运算符只能操作boolean类型的数据,运算结果也是boolean类型的值
- 逻辑运算符有:
- !:逻辑非(一元)
- &:逻辑与
- |:逻辑或
- ^:异或
- &&:短路与
- ||:短路或
public class Demo006{
public static void main(String[]args){
boolean t=true;
boolean f=false;
System.out.println(t&f);
System.out.println(t|f);
System.out.println(t^f);
System.out.println(t&!f);
System.out.println(t|!f);
System.out.println(t^!f);
System.out.println(t&f);System.out.println(t^t);System.out.println(f^f);
}
}
- 异或特点:一个操作数异或另一个操作数两次,结果还是此操作数
a^b^b=>a
System.out.println(f^t^t);
System.out.println(t^f^f);
int x=10;
int y=20;
System.out.println((x>y)&&(x>10));
//闰年:能被400整除的年份是闰年或这能被四整除,但不能被100整除的年份也是闰年
int year=2000;
boolean isLeapYear=(year%400==0)||((year%4==0)&&(year%100!=o));
System.out.println(isLeapYear);
- 短路与 运算
- 当短路与运算的左操作数为false时,会忽略有操作数,直接返回false(右操作数如果是一个表达式,则不会对其进行运算)
- 如果左操作数是true,才会让做操作数参与运算,返回最终结果
- 左操作数应该选择false出现几率更多的表达式
- 逻辑与 和 短路与 的的异同
- 短路与 和 逻辑与 的运算规则相同,不同的是如果左边的结果为false 右边的表达式 短路与 不会进行运算
//逻辑与
int a=10;
int b=20;
boolean r=(++a>b)&(++b==21);
System.out.println("r="+r);
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println("------------------------------------");
//短路与
int a=10;
int b=20;
boolean r=(++a>b)&(++b==21);
System.out.println("r="+r);
System.out.println("a="+a);
System.out.println("b="+b);
- 短路或
- 当短路或运算的左操作数为true时,会忽略右操作数,直接返回true(右操作数如果是一个表达式,则不会对其进行运算)
- 如果左操作数是false,才会让右操作数参与运算,返回最终结果
- 左操作数应该选择true出现几率更多的表达式
//逻辑或 和 短路或
//逻辑或
int a=10;
int b=20;
boolean r=(++a<b)&(++b==21);
System.out.println("r="+r);
System.out.println("a="+a);
System.out.println("b="+b);
//短路或
int a=10;
int b=20;
boolean r=(++a<b)&(++b==21);
System.out.println("r="+r);
System.out.println("a="+a);
System.out.println("b="+b);
条件运算
- 条件运算是Java中唯一的三元运算
- 书写格式
- 表达式1?表达式2:表达式3;
- 表达式1:结果一定是一个布尔值,即结果返回true或false
- 当表达式1为true时,返回表达式2的结果
- 当表达式1为false时,返回表达式3的结果
- 条件运算符可以替代特定类型的if-else结构
int i=100;
int j=(i>=100)?i:-i;
System.out.println("i and j :"+i+"and"+j);
i=99;
j=(i>=100)?i:i;
System.out.println("i and j :"+i+"and"+j);
//[1,0)
double x= Math.random();//随机数
int y=(int)(x*10);
System.out.println(x);
System.out.println(y);
String str=y%2==o?"偶数":"奇数";
System.out.println(str);
位运算
- 可以应用在整数类型和char类型的数据上。
- 按位取反(一元):即把2进制形式的数字各个位反转,1变0,0变1。结果是比操作数的相反数小1的整数
- 例如:
~10变成-11;
~(-5)变成4
int a=10;//0000 1010
System.out.println(~a);//1111 0101;
a=-11;
System.out.println(~a);
- 按位与
- 作用:对左操作数中的某些位进行置0操作;写法:想让左操作数的哪位为0,就让又操作数的这位为0而有操作数的其它位都为1
int x = 42;//0010 1010
int y = 15;//0000 1111
//00101010
& 00001111
-------------
00001010
System.out.println(x&y);//10
- 按位或
- 作用:对左操作数中的某些位置进行置1操作
- 写法:想让左操作数的哪位为1,就让右操作数的这位为1,而右操作数的其它位都为0
// 00101010
|00001111
--------------
00101111
System.out.println(x|y);
- 按位异或
- 特点:一个操作数异或另一个操作数两次,结果还是此操作数
// a^b^b
// 00101010
^00001111
---------
00101010
System.out.println(x^y);
final int B=0b00000001;//1
final int I=0b00000010;//2
final int U=0b00000100;//4
int textStyle=0;
System.out.println(textStyle);
textStyle=B;
System.out.println(textStyle);
textStyle=textStyle|I;
System.out.println(textStyle);
textStyle=textStyle|U;
System.out.println(textStyle);
//0111
&1101
textStyle=textStyle&(~I);
System.out.println(textStyle);
- 复合状态变量(位域(bit field))和某一状态值相按位与。如果结果仍是被与的那个数字,则复合状态中包含此值表示的那种状态;如果是0,则复合状态中不包含此值表示的那种状态
//0101
//&0001
---------
// 0001
System.out.println((textStyle&B)==B);
// 0101
//&0010
----------
// 0000
System.out.println((textStyle&I)==I);
it x = 10;
System.out.println((x&1)==1?"奇数":"偶数");
- 左移 value<<bit
- 把value的2进制向左侧移动bit位,每次移动,高阶位会被移出并丢弃,低阶位补0,向左移一位相当于以对原值进行依次乘2操作。左移是乘以2的n次方的高效替代方案。但如果把1移动到最高阶的位,结果就不是我们期待的。
int a=1;//0000 0000 0000 0000 0000 0000 0001 1110
System.out.println(a<<1);
System.out.println(a<<2);
System.out.println(a<<27);
- 右移:value>>bit
- 把value的2进制值向右侧移动bit位。每次移动,低阶位会被移出并丢弃,高阶位补符号位。每右移一次,相当于以对原值进行一次除2操作。右移是除以2的n次方的高效替代方案
0000 0000 0000 0000 0000 0000 0000 1000
0000 0000 0000 0000 0000 0000 0000 0010
System.out.println(8>>2);
0000 0000 0000 0000 0000 0000 0000 1000
1111 1111 1111 1111 1111
1111 1111 0111
1111 1111 1111 1111 1111
1111 1111 1000 >>-8
System.out.println(-8>>2);
- 无符号右移: value>>>bit
- 把value的2进制值向右移动bit位,每次移动,低阶位会被移出并丢弃,高阶位补0,不常用
1111 1111 1111 1111 1111 1111 1111 1111//int e=-1;
0000 0000 0000 0000 0000 0000 1111 1111
System.out.println(e>>>24);
赋值运算符
- 通用赋值运算符:+
- 复合赋值运算符:+=、-=、*=、/=、%=、&=、|=、~=、^=、>>=、<<=、>>>=
- 通用赋值运算符是最常用的,复合赋值运算符可以被其替代。作用是把右侧表达式的结果赋值给左侧变量。赋值运算的顺序是从右向左
int i=5+8;
int a,b,c,d;
a=b=c=d=10/5;
把10/5的结果运算出来后,先赋值给d,然后再把d赋值给c,把c的值赋值给b,把b赋值给a(从右向左进行运算)
- 复合赋值运算符都是基于左侧变量的原始值,与右操作数进行特定运算,再将结果赋值给左侧变量。复合赋值运算比通用赋值运算要高效,但可读性略差。注意:如果字节码是通过Eclipse的EJC编译器编译的,则没有差异。EJC会对通用赋值运算进行编译优化
a+=10;//a=a+10;
System.out.println("a"+a);