Java基础_运算符

来源:互联网 发布:美图搜索软件 编辑:程序博客网 时间:2024/06/05 14:17

Java基础_运算符

标签(空格分隔): java基础


Java核心+Java编程思想学习手记

运算符简介

在Java中,使用算术运算符表示加减乘除,其中除法(/),在运算符两侧都是整数时,代表整数除法,否则代表浮点运算

这里需要注意,整数除以0会产生一个异常( java.lang.ArithmeticException: / by zero),而浮点数除以0则会得到无穷大(Infinity)或NaN(Not a Number)
如果将无穷大进行强制类型转换为int之后,则会得到整型的最大值,还是挺有意思的

Integer num = (int) (1.0/0);System.out.println(num);//结果:2147483647

Java特性之一:可移植性,同样的运算在不同的JVM上应当得到相同的结果,不过这一点对于double类型的浮点运算貌似没那么容易。double类型的浮点使用64位存储一个数值,而有些处理器使用80位浮点寄存器:这就使得不同的处理器得到的结果可能会不一样(计算过程中使用处理器的精度,最后再对结果进行64位截断)。
如果想要使用严格的浮点精度,需要使用关键字strictfp来标记需要使用严格浮点计算的方法(Intel处理器有可能会溢出,不过对于大部分程序来说,浮点溢出不是问题)

//定义一个严格进行64位浮点截断的方法    public strictfp Double getResult(double x,double y) {        return x/y;    }

数学函数与常量

在Math类中,包含了各种数学用到的方法以及函数,例如计算一个数值的平方根,可以使用sqrt方法

double x = 9;double y = Math.sqrt(x);System.out.println(y); // 3.0

另外,在Java中没有幂运算,我们使用Math类中的pow方法

double y = Math.pow(10,2);

pow方法的两个参数都是double类型,结果也是,上式相当于

y=102

floorMod方法用于解决一个整数余数的问题:
n%2,如果n是偶数,结果是0,如果n是奇数,结果是1;不过,如果n是负奇数,结果就是-1,这就扯到了小学数学的一个常识,余数不能是负数:
比如 -4/3 = -2….2,结果是负二余二,嗯,没毛病
说回floorMod,它的方法是Math.floorMod(int x,int y)Math.floorMod(long x,long y),它可以无论x的值是正是负,它得到的结果总是在0~y之间的取余值。

Math方法中还提供了一些常见的三角函数

Math.sinMath.cosMath.tanMath.atanMath.atan2

还有指数,对数

Math.expMath.logMath.log10

以及表示πe这种数学常量的近似值

Math.PIMath.E

补充:为了达到最快的性能,Math类中使用的所有方法都是使用计算机处理器默认的例程,如果获取一个可以预测的结果比运算速度更为重要的话,需要使用StrictMath类,它使用fdlibm实现算法,确保了在所有平台上得到相同的结果有关这些算法的源代码

留个坑:关于Math类的详解


数值类型转换

Java实际使用中经常需要将一种数值类型转换为另一种关系图.png-13.5kB
如图所示:其中实心箭头表示数据转换时不会发生精度损失,而空心箭头代表会发生精度损失


强制类型转换

上图中代表了自动类型转换,不需要特意地去注明,Java会自动帮我们进行转换,不过,有些情况我们需要将高精度的数值转换为低精度的数值,如double转换为int类型,这种情况下会丢失数据,需要通过强制类型转换进行转换。

double x = 9.998;int n = (int)x;//n的结果是9

强制类型转换是直接将小数点后面的值截掉而得到整型,不过更多的时候,我们更希望得到近似数值,这时又需要用到Math类中的方法

double x = 9.998;int n = (int)Math.round(x);

发现使用了round方法依然需要进行强制类型转换,这是因为round方法的返回值是long类型,因此还需要强制类型转换。

如果试图将一个数值从一个类型强制转换为另一个类型,而超出了目标的表示范围,则会得到完全不同的值


结合赋值和运算符

Java对所有的算术运算符都提供了二元运算

x+=4;

等价于

x=x+4;

对于+-*/%都适用

如果运算符得到的值和左侧的值数据类型不同,则会发生强制类型转换

int x = 0;x+=3.5;//等价于 x=(int)(x+3.5);

+号和-号在表示加减号的同时还可以表示数值的正负值变化
编译器肯定会根据自己的规则进行识别,但是在使用时最好使用括号或者空格表示清楚以提高代码的可读性

关于自增运算符和自减运算符

++以及
写在变量的前面或后面,两种形式都会是变量加一或减一,但写在前面所得到的值是+1之后的值,写在后面所得到的值是+1之前的值;
这种东西在考试或者语言学习中算是考点吧,但是在实际开发中感觉也就是循环当中能够见到它,使用可以,但不要过于频繁使用,会导致代码的可读性降低。


关系操作符

关系操作符会得到一个boolean类型的结果,根据关系,如果为真,则boolean值为true,否则为false,关系运算符包括==,!=,>,<,>=,<=;其中==和!=可以操作所有的基本数据类型,而其他运算符不可以操作boolean类型

关系操作符与对象

刚才说了关系操作符合基本数据类型的关系,那么他们能否操作对象呢?
其中关系操作符==!=也可以操作对象(所有基本数据类型以及对象,万用)
然而操作对象时和操作基本类型时有所不同,操作基本类型时对比的是真正的内容,而操作对象对比的是对象的引用

        Integer i = new Integer(50);        Integer j = new Integer(50);        int x = 50;        int y = 50;        System.out.println(i==j);//false        System.out.println(x==y);//true

如果想要操作对象的实际内容需要使用所有对象都有的方法equals(),对于该方法而言,它默认对比的还是引用,我们需要通过覆写方式来定义equals()的对比规则。Java的类库中很多都默认实现了equals方法,比如刚才的Integer中

        Integer i = new Integer(50);        Integer j = new Integer(50);        System.out.println(i.equals(j));//true

三元运算符

很多程序都有三元运算符的存在,可以在某种意义简化代码,代替简单的if…else…的逻辑语句
语法为

(boolean)?result1:result2;

括号中填入一个boolean表达式(得出的结果是true或false),如果是true的话,执行result1的位置;如果是false的话,执行result2。
当然可以进行嵌套,不过依然要以代码的可读性,不要使用太多层嵌套..个人感觉最好不要使用,阅读性有点低。

逻辑操作符

和其他语言一样,逻辑运算符有三种,与(&,&&)或(|,||)非(!)

逻辑运算符的短路现象

如果一个表达式能够得出明确的结果,那么表达式便不再对之后的运算符进行判断。其中能产生短路的就是短路与(&&),以及短路或(||),在与运算中,只要有一个表达式的boolean为false,则该式子就为false,后面的表达式便不继续执行;在或运算中,只要有一个表达式为true,则整个表达式就为true,后面的表达式就不再执行。使用短路的话能够提高运算性能,避免bug
如:

        String str = null;        if(str!=null&&str.equals("ww")) {        }else{            System.out.println("避免了空指针异常");        }

位运算符

位运算符是用来操作基本数据类型中的bit,二进制。位运算汇编执行速度很快,根据cpu性能,至少也会比乘除法的速度快几倍以上。
位运算符包括:
&("and") |("or") ^("xor") ~("not")

可以把二进制的0以及1看做假和真,这样理解起来位运算就会更简单一些,
按位与操作符 & :左右两边都是1,结果为1,否则是0
按位或操作符 | : 左右两边都是0,结果为0,否则是1
按位异或操作符 ^ : 某一位是1,但不全是1,则得到1,否则是0
按位非操作符(取反操作符) ~ : ps:补码是源码取反+1

将windows自带的计算器调成程序员模式,就可以很直观的看到位运算的规律

移位操作符

null


字符串操作符

前面已经提过了+以及+=,他们还有另一个十分常用的用途——用来拼接字符串;
要注意,如果一个表达式用字符串开头,那么后面所有的操作数都会自动转换为字符串类型

原创粉丝点击