操作符

操作符

Java 的数据是通过操作符来操作的。几乎所有操作符都只能操作“基本类型”,但“=”、“==“和”!=“能操作所有对象。String支持”+“和”+=“。

操作符具有优先级,但建议使用括号明确规定计算顺序。

public static void main(String[] args) {
   int a = 1;
   int b = 2;
   String str = "123";
   //当一个String类型后紧跟一个非String类型,系统会尝试将非String类型转为String类型
   System.out.println(a + b);
   System.out.println(a + b + str);
   System.out.println(a + str + b);
}

赋值使用操作符”=“。将右值赋给左值,右值可以为任意常数、变量、表达式(能生成值),左值必须为已命名的变量(已声明为final类型的在某些情况下不行)。

基本类型的赋值是直接赋值,对象的赋值只是赋值了引用。对于方法中传参也符合这个规则,当然 String 是个特例,你可以把它看成是 char 的包装类就容易理解了。

public static void main(String[] args) {
   int a = 1;
   int b = 2;
   System.out.println("a=" + a + ";b=" + b);
   a = b;
   System.out.println("将b的值赋给a后,a=" + a + ";b=" + b);
   a = 3;
   System.out.println("修改赋值后的a,b值并未受影响,a=" + a + ";b=" + b);
   Person person1 = new Person(1);
   Person person2 = new Person(10);
   System.out.println("person1=" + person1.toString() + ";person2=" + person2);
   //将person2赋值给person1,person1的之前的引用不再被引用,过一段时间就会被垃圾回收器回收
   person1 = person2;
   System.out.println("将person2的引用赋值给person1,person1=" + person1.toString() + ";person2=" + person2);
   //修改person1的数据将影响person2,因为两者的引用指向同一个对象
   person1.setAge(100);
   System.out.println("修改person1的age将影响person2的age,person1=" + person1.toString() + ";person2=" + person2);
}

public static class Person {
   private int age;

   public Person(int age) {
       this.age = age;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   @Override
   public String toString() {
       return "Person{" +
               "age=" + age +
               '}';
   }
}

输出如下:

a=1;b=2
将b的值赋给a后,a=2;b=2
修改赋值后的a,b值并未受影响,a=3;b=2
person1=Person{age=1};person2=Person{age=10}
将person2的引用赋值给person1,person1=Person{age=10};person2=Person{age=10}
修改person1的age将影响person2的age,person1=Person{age=100};person2=Person{age=100}

++:称为自动递增操作符
--:称为自动递减操作符
++i称为前缀式,i++称为后缀式。前缀式先生成值再运算,后缀式先运算再生成值。

">"、"<"、">="、"<="、"=="、"!="是关系操作符。表达式为真则返回true,为假返回false。

其中 boolean 类型只适用"=="和"!="。

补充:”==“和”!=“用于比较对象的引用是否相等。重写 Object 类的 equals() 方法即可比较对象的值是否相等,但是 equals() 方法默认也是比较对象的引用。

逻辑操作符

”与(&&)“、”或(||)“、”非(!)“根据参数的逻辑关系生成一个布尔值。且只能应用于布尔值的表达式。”与(&&)“和”或(||)“具有”短路“现象。一旦能准确无误的判断表达式的值,就不再计算余下部分。

直接常量

L(l):long
F(f):float
D(d):double
0x(0X):十六进制,0-9、a-f
0:八进制,0-7

在 Java 中,可以调用 Integer 或者 Long 中相应的方法,将十进制数转化为二进制、八进制或者十六进制。

public static void main(String[] args) {
   int a = 16;
   //二进制
   System.out.println("Binary="+Integer.toBinaryString(a));
   //八进制
   System.out.println("Octal="+Integer.toOctalString(a));
   //十六进制
   System.out.println("Hex="+Integer.toHexString(a));
}

位运算符

位运算符有如下几种:
77c6a7efce1b9d1688c4b844f1deb48f8

  • 按位与”&“:只有对应的两个二进位均为1时,结果位才为1 ,否则为0。1&1=1,1&0=0,0&1=0,0&0=0
  • 按位或”|“:只要对应的二个二进位有一个为1时,结果位就为1。1&1=1,1&0=1,0&1=1,0&0=0
  • 按位异或”“:参与运算的两个值,如果两个相应位相同,则结果为0,否则为1。00=0,10=1,01=1,1^1=0。按位异或可以实现两个数的交换,而不必借助临时变量。
  • 取反”“:1=0,~0=1
  • 左移”<<“:地位插入0。
  • 右移”>>“:若符号为正,则高位插入0;若符号为负,则高位插入1。
  • 无符号右移“>>>”:无论正负,都在高位插入0。

以上为操作符,除按位异或“^”外,其余都可与“=”连用。

验证按位异或”^“可以实现两个数的交换:

public static void main(String[] args) {
   int a = 16;
   int b = 10;
   System.out.println("异或前,Binary,a=" + Integer.toBinaryString(a) + ";b=" + Integer.toBinaryString(b));
   a = a ^ b;
   b = b ^ a;
   a = a ^ b;
   System.out.println("异或后,Binary,a=" + Integer.toBinaryString(a) + ";b=" + Integer.toBinaryString(b));
}

输出如下:

异或前,Binary,a=10000;b=1010
异或后,Binary,a=1010;b=10000

这里我们来验证下异或运算的效率如何。

public static final int TIMES = 1000000000;

public static void main(String[] args) {
   exchange1();
   exchange2();
}

private static void exchange1() {
   long start = System.currentTimeMillis();
   int a = 16;
   int b = 10;
   for (int i = 0; i < TIMES; i++) {
       a = a ^ b;
       b = b ^ a;
       a = a ^ b;
   }
   System.out.println("执行" + TIMES + "次异或操作交换数据要" + (System.currentTimeMillis() - start) + "ms");
}

private static void exchange2() {
   long start = System.currentTimeMillis();
   int a = 16;
   int b = 10;
   int temp;
   for (int i = 0; i < TIMES; i++) {
       temp = a ;
       a = b;
       b = temp;
   }
   System.out.println("执行" + TIMES + "次使用临时变量交换数据要" + (System.currentTimeMillis() - start) + "ms");
}

输出如下:

执行1000000000次异或操作交换数据要1820ms
执行1000000000次使用临时变量交换数据要4ms

发现使用异或操作实现值得交换竟然没有使用临时变量来的高效。

三元操作符

三元操作符的表达式形如:

//若布尔表达式为真,则计算value1
//否则,计算value2
boolean-exp ? value1 : value2

类型转换

在 Java 中,基本类型的转换有两种方式:

  1. 扩展转换:低精度类型转换成高精度类型,编译器会自动执行,不需要显示申明。如,将 int 转换为 long 类型
  2. 窄化转换:将高精度类型转换为低精度类型,需要显示申明,因为窄化转换会丢失数据。如,将 long 转换为 int 类型。

Java 中的基本数据类型除 boolean 类型外,都允许类型转换。类也能实现转换,但仅限于同一类。

WechatIMG34

截尾和舍入

Java 中将浮点数转换为 int 或 long ,执行的是截尾操作。如需进行舍入操作,则需要使用 Math.round() 方法。

public static void main(String[] args) {
   float a = 1.6f;
   System.out.println("(int)a=" + (int) a);
   System.out.println("Math.round(a)=" + Math.round(a));
}

输出如下:

(int)a=1
Math.round(a)=2

以上就是《Java 编程思想》操作符这一章节的读书笔记~

posted @ 2016-10-16 11:29  登天路  阅读(288)  评论(0编辑  收藏  举报