2-3-1算术运算符
算数运算符是用来进行数值计算的。
类型 | 运算方法 |
---|---|
+ 加 | 加 |
- 减 | 减 |
* 乘 | 乘 |
/ 除 | 除 |
% 取余 | 求余数 |
注意:
- 当参与除法(/)运算的俩个操作数都是整数时,/表示整数除法,如果结果有小数 ,直接舍去,例 3 / 2 = 1。
- 0 / 整数 会产生一个异常。
- 0 / 浮点数 会得到一个无限大或NaN结果。
NaN:表示未定或者不可表示的值。
public class pta {
public static void main(String[] args) {
int a = 10;
int b = 2;
int c = 3;
int add = a + b; // 10 + 2 = 12;
int sum = a - b; // 10 - 2 = 8;
int mult = a * b;// 10 * 2 = 20;
int div1 = a / b; // 10 / 2 = 5;
int div2 = a / c; // 10 / 3 = 3;
int rem1 = a % b; // 10 % 2 = 0;
int rem2 = a % c; // 10 % 3 = 1;
System.out.println(add + " " + sum + " " + mult + " " + div1 + " " + div2 + " " + rem1 +" " + rem2);
}
}
输出结果为:12 8 20 5 3 0 1
以上为基本的算术运算符的运算。
2-3-2数学函数Math类
Math类中提供了各种各样的数学函数。
sqrt:计算一个数的平方根。**注意:sqrt返回的值为double类型,形参虽然可以用int等类型,但不是说用的是int等类型,只是java本身有的自动类型转换将其他类型转为double类型了。**函数为public static double sqrt(double a)
pow:完成幂运算的运算符。double z = Math.pow(x,y); z的值为x的y次幂即 xy 。函数为public static double pow(double a, double b)
pow和sqrt一样返回的类型是double类型。
三角函数:Math.sin Math.cos Math.tan Math.atan Math.atan2
指数函数及其反函数:Math.exp Math.log Math.log10
常量 :Math.PI Math.E
在源文件最上面加上 import static java.lang.Math.;就可以不用写Math.了。
下段代码是Math类的简单使用
import static java.lang.Math.*;
public class pta {
public static void main(String[] args) {
double a = 4;
double b = 10;
double c = 2;
double x = sqrt(a); //平方根
System.out.println(x); //4的平方根为2,输出为2.0
double z = Math.sqrt(a);//如果没有导包,则需要这么写
double y = pow(b, c); //幂运算
System.out.println(y); //10的2次幂为100,输出为100.0
}
}
输出结果为:
2.0
100.0
返回值为double类型,所以有是100.0而不是100;
2-3-3数值类型之间的转换
上图为数值类型之间转换的关系。
- 在某些情况下,低精度的类型会自动转换成高精度的类型,但高精度的类型不能转换成低精度。
- 图中的黑色箭头表示箭头尾部类型可以转换为箭头指向类型,且无信息丢失(没有损失精度)
- 图中的红色箭头同样表示箭头尾部类型可以转换为箭头指向类型,但会产生精度损失。
自动类型转换
当用一个二元连接符连接俩个值时(例如x = n + f,n是整数,f是浮点数,x是浮点数),较低精度的类型会自动转换成较高的精度,然后再进行计算。
简单的理解就是俩个数值如果因为符号连接在一起,较低类型的数据类型会自动转为较高类型的数据类型。
2-3-4强制类型转换
从2-3-3我们学到了自动类型转换,那有自动就有非自动,即强制类型转换。虽然这可能会丢失一些信息。 但在有些必要的时候,我们需要将double型转换成int类型,在java中,我们可以手动的进行这种转换。
强制类型的语法格式是在括号中指定想要转换的目标类型,后面紧跟着待转换的变量名。例:double a = 3.6;(int)a;
public class pta {
public static void main(String[] args) {
double a= 3.6;
System.out.println((int)a);
}
}
输出结果为3。
如果想舍入一个浮点数到最接近的整数,可以用Math.round的方法
public class pta {
public static void main(String[] args) {
double a= 3.6;
System.out.println((int)Math.round(a));
}
}
输出结果为4。
注意:如果试图讲一个数从一个类型转换到另一个类型,而又超出了目标类型的表示范围,结果就会截断成一个完全不同的值。
例如(byte)300实际会得到的值为44,我们可以理解一个随机值。
public class pta {
public static void main(String[] args) {
int a = 300;
System.out.println((byte)a);
}
}
输出结果为44。
2-3-5赋值运算符
赋值运算符用于给变量或常量一个值或在赋值的过程中伴随着一些简单操作的运算符。有=、+=、-=、/=等。
public class day0916 {
public static void main(String[] args) {
int a = 10; //将10赋给a
int b = 2; //将2赋给b
int c;
c = b; //将b的值赋给c
c += a; //c = c + a的简要写法,即将c和b的和赋给c;
System.out.println(c);
}
}
输出的值为12。
**注意:**如果赋值运算符左右数据类型不同,就会发生强制类型转换,转换的数据类型为左边的数据类型。
public class day0916 {
public static void main(String[] args) {
int a = 10;
a += 1.7;
System.out.println(a);
}
}
输出结果为11,结果为(int)(a + 1.7)。
2-3-6自增自减运算符
自增运算符和自减运算符的数值改变大小均为1,增(++)就是加1,减(–)就是减1.
1.前置运算符
前置运算符的顺序是先运算后执行语句。先对数值就行自增自减运算,后执行语句。有点抽象,我们直接看代码。
public class day0916 {
public static void main(String[] args) {
int a = 0;
if((++a) == 0) {
System.out.print("表达式的值为0 ");
}
else {
System.out.print("表达式的值不为0 ");
}
System.out.println(a);
}
}
输出为:表达式的值不为0 1。(print就是不换行输出)
先看a的值,从0变1,自增了1。再看if语句,if语句没有执行,可以看出if语句的条件不成立。原因是++a让a的值变为了1,if语句返回的结果为false。
2.后置运算符
后置运算符的顺序是先执行语句后运算。先执行语句,后进行自增自减运算。看代码。
public class day0916 {
public static void main(String[] args) {
int a = 0;
if((a++) == 0) {
System.out.print("表达式的值为0 ");
}
else {
System.out.print("表达式的值不为0 ");
}
System.out.println(a);
}
}
输出为:表达式的值为0 1
a的值因为自增运算符从0变为1。再看if语句,if语句成功执行,那么if语句的条件成立,诶,他不是++了吗,为什么会成立呢,这是因为后置运算符在本段代码的顺序为 先执行a == 0的判断语句,再执行++的自增运算。
从上俩段代码可以看出,前置和后置只有一点不同,即自增或自减运算与执行语句之间的先后。
2-3-7关系运算符
关系运算符是用来判断运算符俩侧值的关系,若值的关系与运算符所表示的关系相同返回一个布尔类型的true,反之则返回false。
常见的有 ==(相等)、!=(不相等)、<(小于)、>(大于)、<=(小于等于)、>=(大于等于)
例 3 == 5 ,俩值的关系为不等,返回的结果为false。
public class day0916 {
public static void main(String[] args) {
if(3 == 5) {
System.out.println("条件1返回值为true");
}
else {
System.out.println("条件1返回值为false");
}
if(3 == 3) {
System.out.println("条件2返回值为true");
}
else {
System.out.println("条件2返回值为false");
}
}
}
输出为:
条件1返回值为false
条件2返回值为true
2-3-8逻辑运算符
逻辑运算符的俩边类型为布尔类型,逻辑运算符返回的值是一个布尔类型。
1.逻辑与
逻辑与,符号&&。形式:expression1 && expression2。
三种情况:
- expression1、expression均为真,返回真。
- expression1、expression2一假一真,返回假。(1 、 2互换也成立)。
- expression1、expression均为假,返回假。
public class day0916 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
boolean result1 = a && b; //true和false
boolean result2 = a && c; //true和true
boolean result3 = b && d; //false和false
System.out.println(result1 + " " + result2 +" " +result3);
}
}
输出结果为false true false。
2.逻辑或
逻辑或,符号||。形式:expression1 || expression2。
- expression1、expression均为真,返回真。
- expression1为假,expression2为真,返回真。(1 、 2互换也成立)。
- expression1、expression均为假,返回假。
public class day0916 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
boolean result1 = a || b; //true和false
boolean result2 = a || c; //true和true
boolean result3 = b || d; //false和false
System.out.println(result1 + " " + result2 +" " +result3);
}
}
输出结果为true true false。
逻辑与和逻辑或有短路性质。如果逻辑与中的一个条件为假,则返回假,且后续条件不再进行判断即不再进行符号右边的的运算,逻辑非同理。
3.逻辑非
逻辑或,符号!。形式:!(expression),真变假,假变真。
例:!(1 == 1)为假,1等于1是事实为真,真的逻辑非是假。
public class day0916 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean result1 = !a;
boolean result2 = !b;
System.out.println(result1 + " " + result2);
}
}
输出结果为false true。
4.逻辑异或
逻辑异或,符号^ 。形式:expression1 ^ expression。运算符俩侧,如果布尔值相同返回false,反之如果不同返回true。
例:1 == 1 ^ 2 == 2。结果为flase。1 == 2 ^ 2 ==2 结果为true。
public class day0916 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
boolean result1 = a ^ b; //true和false
boolean result2 = a ^ c; //true和true
boolean result3 = b ^ d; //false和false
System.out.println(result1 + " " + result2 +" " +result3);
}
}
输出结果为true false false。
5.&和|
&和&&的功能、|和||的功能几乎想同,唯一的不同是&&和||有短路性,无论是什么情况&和|都会执行玩逻辑语句,而&&和||不会(详情看上面)。
public class day0916 {
public static void main(String[] args) {
boolean a = false;
boolean b = true;
int num1 = 0;
int num2 = 0;
if(a && (num1++) > 0) {
System.out.println("条件语句1成立");
}
if(a & (num2++) > 0) {
System.out.println("条件语句2成立");
}
System.out.println(num1 + " " + num2);
}
}
上述代码的输出为0 1。
从输出可以看出,俩个if条件语句都没有执行,这是因为逻辑与运算符俩侧只要有一个为假,结果就是假。而他们相对的值不同的原因是,条件语句1是&&,有短路性,当运算符左侧的条件为假时,该条件的结果就是假了,得出结果就不孕算了,后面的自加(num1++)没有执行,而条件语句2没有短路性,num2++执行了。所以num1 = 0,num2 = 1。逻辑非同理。
2-3-9条件运算符:三目运算符
condition ? expression1 : expression2;
语句意为如果条件condition成立,则该语句的返回值为expression1,否则返回值为expression2.
public class day0916 {
public static void main(String[] args) {
int a = 1 > 2? 3 : 4;
System.out.println(a);
}
}
输出为4。
int a = 1 > 2? 3 : 4;
首先判断1 > 2是否成立,1 > 2不成立,返回整形4,a接收到的值为4。
2-3-10 switch表达式
当我们需要在俩以上的值中做出选择时,可以使用switch表达式。
case的标签可以是数字、字符串和枚举型常量,并且可以为case提供多个标签用逗号分隔。
public class day0916 {
public static void main(String[] args) {
int seasonCode = 2;
String seasonNmae = switch(seasonCode) { //数值
case 0 -> "String";
case 1 -> "Summer";
case 2 -> "Fall";
case 3 -> "Winter";
default -> "???";
};
System.out.println(seasonNmae); //字符串
String a = "沈阳师范大学";
String schoolNum = switch(a) {
case "沈阳师范大学" -> "0001";
case "沈阳工业大学" -> "0010";
case "沈阳大学" -> "0011";
case "沈阳航空航天大学" -> "0100";
default -> "其他大学";
};
System.out.println(schoolNum); //一个case对应多个标签
String b = "纸";
String thing = switch(b) {
case "纸","磨","笔","砚" -> "文房四宝";
default -> "其他";
};
System.out.println(thing);
}
}
输出结果为:
Fall
0001
文房四宝
注意:使用整数或String操作数的switch表达式必须有一个default,因此不论操作数值是什么,这个表达式都必须生成一个值。但操作数为枚举类型不需要写fault,因为每一个可能的值都对应一个case。
!!!枚举的会在后面讲枚举再写。
2-3-11位运算符(简单讲几个常见的)
类型 | 举例 |
---|---|
<< 左移运算符 | 3 << 2 = 12 |
>> 右移运算符 | 12 >> 2 = 3 |
>>> 无符号右移运算符 | 12 >>> 2 = 3 |
& 与运算 | 6 & 3 = 2 |
| 或运算 | 6 | 3 = 7 |
^ 异或运算 | 6 ^ 3 = 5 |
1.左移运算符(<<)
x << y
先将符号左侧的十进制数(x)转换为二进制数,左移y位,就在二进制数的最右侧加y个0,最后转为10进制数输出。
例:3 << 2 = 12 先将3转换为二进制数。
0000 0000 0011 左移俩位
0000 0000 0011 00 -------->12
方便计算:左移n位,得出的结果就是 2n * 左操作数
2.右移运算符(>>)
x >> y
先将符号左侧的十进制数(x)转换为二进制数,看二进制的最高位,如果最高位为1,在二进制数的最左侧加y个1,如果最高位为0,就y个0,右侧多出来的去掉。
例 12 >> 2 = 3先将12转为二进制数,因为最高位为0,在最左侧补0,看上下俩个二进制数,00多出来了,删去。
0000 0000 0000 1100
0000 0000 0000 0011 00 ------->3
3.无符号右移运算符(>>>)
无符号右移运算符即不需要考虑符号位的右移运算符,无论二进制的最高位是0还是1,都补0,其他与右移运算符完全相同。
4.逻辑与、逻辑或和逻辑异或
直接看例题理解
例1:6&3 先将操作数换算为二进制
6: 0000 0000 0110
3: 0000 0000 0011
可以把0看成false,把1看成true,对应的位置按照逻辑与的关系得出结果。(均为1为1,其他为0)
0000 0000 0010 ------>2
例2:6|3
6: 0000 0000 0110
3: 0000 0000 0011
对应位置按逻辑或的关系得出结果(一个为1,即为1)
0000 0000 0111 ----->7
例3:6^3
6: 0000 0000 0110
3: 0000 0000 0011
对应位置按逻辑异或的关系得出结果(同为0,异为1)
0000 0000 0101 ------->5
逻辑非不会,以后写计算机组成原理时候写。
2-3-12括号与运算符级别
同一级别的运算符按从左到右依次运算,不同级别的运算符按优先级的先后进行运算。
运算符 | 结合性 |
---|---|
() [] {} | 从左向右 |
一元运算符! + - ()强制转换 new | 从右向左 |
* / % | 从左向右 |
二元运算符 + - | 从左向右 |
<< >> >>> | 从左向右 |
< <= >= instanceof | 从左向右 |
== != | 从左向右 |
& | 从左向右 |
^ | 从左向右 |
| | 从左向右 |
&& | 从左向右 |
|| | 从左向右 |
?: | 从右向左 |
= += -= *= /= %= *= &= |= ^= <<= >>= >>>= | 从右向左 |