Java开发手册
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.2 关系与逻辑运算

关系运算总是生成boolean型结果,其计算的是操作数之间的关系。如果关系描述是正确的,则返回true;否则,返回false。Java中的关系运算符如下所示。

· “==”:等于。

· “!=”:不等于。

· “>”:大于。

· “>=”:大于或等于。

· “<”:小于。

· “<=”:小于或等于。

3.2.1 等于/不等于运算

“==”(等于)与“!=”(不等于)适用于所有基本数据类型以及引用类型,对于基本数据类型,比较两个值是否相等(不等);对于引用类型,比较引用的是否是(不是)同一个对象。本小节主要介绍对基本数据类型的操作。

1.“==”运算符

“==”运算符是用于测试两个操作数是否相等的运算符。若相等则返回true,否则返回false,例如:

    1   boolean a=(true==false);  //返回结果false并将其赋给a
    2   boolean b=(15.0==15.0);   //返回结果true并将其赋给b
    3   boolean c=(a==b);         //返回结果false并将其赋给c

要注意的是,“==”运算符不但可以对类型相同的值进行比较;对于类型不同的值只要具有可比性,也可以进行比较,例如,所有的数值型值之间可以相互比较。

    1   boolean b=(12.0==12);
    2   b=('a'==97.0);

2.“!=”运算符

与等于运算符“==”一样,不等于运算符“!=”也是用来测试两个操作数是否相等的运算符,不同的是若相等则返回false,否则返回true,例如:

    1   boolean a=( true!=false); //返回结果true并将其赋给a
    2   boolean b=(15.0!=15L);    //返回结果false并将其赋给b
    3   boolean c=( a!=b);        //返回结果true并将其赋给c

与“==”一样,“!=”也可以对类型不同的值进行比较,例如:

    1   boolean b=(12.0!=12);
    2   b=('a'!=97.0);

提示:不同类型的数据进行比较,要有可比性,否则编译报错。对八种基本数据类型来说,boolean型只能与boolean型比较,其他七种则可以相互比较。

3.无穷大与“NaN”的比较

Java中浮点运算的结果可能产生正负无穷大与“NaN”,同样可以用等于(不等于)运算来判断运算的结果是否是它们,例如:

    1   //代码实现
    2   public class Sample3_6
    3   {
    4        public static void main(String args[])
    5        {
    6            System.out.println((12.0/0)==Double.POSITIVE_INFINITY);
    7            System.out.println((-12.0/0)==Double.NEGATIVE_INFINITY);
    8            System.out.println((12.0%0));
    9            System.out.println((12.0%0)==Double.NaN);
    10       }
    11  }

编译运行如上代码,结果如图3-8所示。

图3-8 Sample3_6的编译运行结果

从图3-8中可以看出:

· “(12.0/0)”的结果是正无穷大,所以打印“true”。

· “(−12.0/0)”的结果是负无穷大,所以也打印“true”。

· “(12.0%0)”的结果是“NaN”。

· “(12.0%0)==Double.NaN”的结果为“false”。因为“NaN”表达的意思是“不知道”,“不知道”并不一定等于“不知道”,所以Java中规定两个“NaN”相比返回“false”。

3.2.2 比较大小运算

比较大小运算符可以用来比较数值型数据的大小。在八种基本数据类型中,除了boolean型外都可以相互进行比较。在Java中,比较大小运算符包括四种,如下所示。

· “>”:大于。

· “>=”:大于或等于。

· “<”:小于。

· “<=”:小于或等于。

下面的代码说明了其具体使用方法。

    1   boolean a=(700>200);      //返回结果true并将其赋给a
    2   boolean b=('a' >97.0);    //返回结果false并将其赋给b,“a”的Unicode编码为97
    3   boolean c=(700>=200);     //返回结果true并将其赋给c
    4   boolean d=(300<100L);     //返回结果false并将其赋给d
    5   boolean e=(15.0<=16L);    //返回结果true并将其赋给e

提示:比较大小运算符还可以用来对无穷大、“NaN”进行比较。将数值与无穷大进行比较是有意义的,而与“NaN”进行比较没有意义,Java中规定任何数值与“NaN”进行大小比较永远返回“false”。

逻辑运算符能够对逻辑值进行逻辑运算,产生一个boolean型的结果,其操作数只能是boolean型。Java中的逻辑运算符包括与运算、或运算、非运算,下面将对这三种逻辑运算进行介绍。

3.2.3 “与”运算

“与”运算的规则是:当两个操作数全部为true时,返回true;否则返回false。在Java中,与运算符有两种,分别为:

· 短路与“&&”。

· 非短路与“&”。

1.短路与“&&”

“&&”运算符的特点体现为它不在无意义的计算上浪费时间,有时也称其为“聪明”与。“&&”运算符先计算左边的操作数。如果该操作数解析为false,则“&&”运算符不再关心右边的操作数,而直接返回false。因为左边操作数为false,则其整个结果必为false,没有必要再进行计算。

下面的例子说明了其工作过程,请读者考察如下代码。

    1   //代码实现
    2   public class Sample3_7
    3
    4        public static void main(String args[])
    5        {
    6            int a=3;
    7            int b=4;
    8            boolean m=(++a>5) && (++b>5);
    9            System.out.println("a="+a+", b="+b);
    10       }
    11  }

将上述代码编译运行,其结果如图3-9所示。

图3-9 Sample3_7的编译运行结果

从图3-9中可以发现变量b并没有进行自增运算,这说明操作符“&&”之后的语句没有执行。因为操作符之前的操作数“(++a>5)”的结果为false。

2.非短路与“&”

“&”不是短路运算符,所以总是计算其两边的内容,这样,其计算效率便会下降。

若将代码“Sample3_7”中的第8行改为:

    boolean m=(++a>5)& (++b>5);

编译运行后,其结果将如图3-10所示。

图3-10 Sample3_7修改后的运行结果

从图3-10中可以发现,两个变量都做了自增运算,说明两边都执行了。

3.2.4 “或”运算

“或”运算的规则是:当两个操作数全部为false时,返回false;否则返回true。其与“与”运算一样有两种,如下所示:

· 短路或“||”。

· 非短路或“|”。

1.短路或“||”

“||”运算符的特点和“&&”运算符一样,即体现为不在无意义的计算上浪费时间。“||”运算符先计算左边的操作数,如果该操作数解析为true,则“||”运算符不再关心右边的操作数。因为左边操作数为true,则其整个结果必为true。

下面的例子说明了其工作过程,请读者考察如下代码。

    1   //代码实现
    2   public class Sample3_8
    3   {
    4        public static void main(String args[])
    5        {
    6            int a=3;
    7            int b=4;
    8            boolean m=(++a<5) || (++b<5);
    9            System.out.println("a="+a+", b="+b);
    10       }
    11  }

将上述代码编译运行,其结果如图3-11所示。

图3-11 Sample3_8的编译运行结果

从图3-11中可以发现,变量b并没有进行自增运算,说明操作符“||”之后的语句没有执行。因为操作符之前的操作数“(++a>5)”返回结果为true。

2.非短路或“|”

“|”与“&”一样,不是短路运算符。因此,总是计算其两边的内容,这样,其计算的效率便会下降。将代码“Sample3_8”中的第8行改为:

    boolean m=(++a<5) | (++b<5);

编译运行后,其结果将如图3-12所示。

图3-12 Sample3_8改后的编译运行结果

从图3-12中可以发现,两个变量都做了自增运算,说明两边都执行了。

提示:在日常开发中没有特殊的需要一般应该采用短路逻辑运算,这样可以大大提高运算效率。但在使用短路逻辑运算时要注意,最好不要在逻辑表达式中修改变量的值,因为有时执行,有时不执行,可能会带来意想不到的bug。

3.2.5 “非”运算

“非”运算的规则是:若操作数的值为true,则返回false;否则返回true。其用符号“!”标记,例如:

    1   boolean a=!(200>100);     //结果将返回false
    2   boolean b=!(20<10);       //结果将返回true

读者会发现,括号内解析出的布尔值,经过“!”运算后,结果全部取反。