Java编程思想(三)—— 操作符

一、赋值

        赋值使用操作符“=”,它是将右边的值赋值给左边,右值可以是任何的常数、变量、表达式,但左值必须是一个明确、已命名的变量。

1、基本类型赋值和对象赋值的区别

● 基本类型存储了实际的数值,在对其赋值时,是直接将一个地方的内容复制到另外一个地方,如下:

        int a = 10, b = 5;
        b = a;//a的内容复制给了b,然后修改b,a的值不受影响
        System.out.println(a + "==" + b);//10==10

● 对一个对象进行操作时,我们真正操作的是一个对象的引用,如果将一个对象赋值给另外一个对象,实际是将“引用”从一个地方复制到另外一个地方,如下:

class Number {
    int a;
}

public class AssignAction1 {
    public static void main(String[] args) {
        Number num1 = new Number();
        Number num2 = new Number();
        num1.a = 10;
        num2.a = 20;
        System.out.println(num1.a + "==" + num2.a);//10==20

        num1 = num2;
        System.out.println(num1.a + "==" + num2.a);//20==20
        System.out.println(num1 == num2);//true,num1和num2都指向原本num2指向的对象

        num1.a = 25;
        System.out.println(num1.a + "==" + num2.a);//25==25,num1和num2指向的对象相同,所以这里是一样的
    }
} 

二、自动递增和递减

递增和递减不仅改变了变量的值,并且以变量的值作为生成的结果。递增和递减,通常分为“前缀式和后缀式”,“前缀式”会先执行运算再生成值,“后缀式”是先生成值再执行运算,如下:

public static void main(String[] args) {
        int i = 1;
        int j = i++;//i先赋值再自增,所以j为1  
        if (i == (++j) && ((i++) == j)) {//i完成自增为2,j先完成自增再比对也为2,后面i先与j比对之后再完成自增
            i += j;//i完成第二次自增为3,j为2
            System.out.println("i=" + i);//5
        }
    }

三、关系操作符

        关系操作符生成的是一个布尔结果,它们计算的是操作数的值之间的关系。关系操作符包括:大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)、不等于(!=)。其中等于和不等于适用于所有的基本数据类型,而其他比较符不适用于boolean类型。

1、测试对象的等价性

示例1:

public class Example2 {
    public static void main(String[] args) {
        Integer num1 = new Integer(20);
        Integer num2 = new Integer(20);
        System.out.println(num1 == num2);//false,它们不是一个对象

        System.out.println(num1.equals(num2));//true,它们的值是相等的

        int num3 = 20;
        Integer num4 = 20;
        System.out.println(num1 == num3);//true,比较时先将num1调用intValue方法拆箱成基本数据类型,然后用拆箱后的int类型值和num3进行比较
        System.out.println(num1 == num4);//false,比较的是对象引用,一个是创建了新的对象,一个使用的是常量池中的对象

        Integer i = 20;
        Integer j = 20;
        System.out.println(i == j);//true,当没有明确要创建一个对象并且值在-128~127之间时,不会创建新的对象,会直接使用常量池中的Integer对象,所以为true

        Integer a = 128;
        Integer b = 128;
        System.out.println(a == b);//false,值超过128了,常量池中没有要创建新的对象
    }
}

示例2:

class Num {
    int val;

    public Num() {
    }

    public Num(int val) {
        this.val = val;
    }
}

public class Example3 {
    public static void main(String[] args) {
        Num num1 = new Num(20);
        Num num2 = new Num(20);
        System.out.println(num1.equals(num2));//false,这是由于Num类没有重写equals方法,java默认是比较引用
    }
}

四、逻辑操作符中的短路运算

public static void main(String[] args) {
        int i = 10, j = 0;
        System.out.println(i > 11 & i / j < 0);//非短路运算,报算术异常
        System.out.println(i > 11 && i / j < 0);//false
        /**
         * 短路运算,由于&&代表两个都为true,结果才为true,而i>11已经为false了,结果自然就是false,
         * 因而&&后面的内容并没有参与逻辑运算,||是一样的
         */
    }

五、直接常量

@Test
    public void example1() {
        int i = 0xffff;//十六进制
        System.out.println(i);//10进制为65535
        System.out.println(Integer.toBinaryString(i));//转换为二进制为1111-1111-1111-1111

        int j = 0777;//八进制
        System.out.println(j);//十进制为0777
        System.out.println(Integer.toBinaryString(j));//转换为二进制为111-111-111

        float f = 3.15F;//默认为double,如果不加F会报错

        long l = Integer.MAX_VALUE + 1L;//和long类型的值进行运算会自动提升类型,所以结果为2147483648
        long l2 = 2147483648L;//默认为int,已经超出int的最大范围,如果不加后缀L会报错
    }

六、指数计数法

保留两位小数参考:Java保留两位小数的几种写法总结

@Test
    public void example2() {
        float f = 3.15e2f;
        System.out.println(f);//315.0,默认保留一位小数
        System.out.println(String.format("%.2f", f));//315.00,.2代表小数点后保留的有效位数

        double d = 3.3335e3;
        System.out.println(d);//3333.5,默认保留一位小数
        BigDecimal decimal = new BigDecimal(d);
        BigDecimal decimal1 = decimal.setScale(2);
        System.out.println(decimal1);//3333.50,保留两位小数

        double d2 = 12345e-4;
        System.out.println(d2);//1.2345

    }

七、按位操作符

        按位操作符用来操作整数基本数据类型中的单个比特,即二进制位,它会对两个参数中对应的位执行布尔代数运算,最终生成一个结果。

@Test
    public void example3() {
        System.out.println(1 & 1);//1
        System.out.println(1 & 0);//0
        System.out.println(0 & 0);//0

        System.out.println(1 | 1);//1
        System.out.println(1 | 0);//1
        System.out.println(0 | 0);//0

        System.out.println(1 ^ 1);//0
        System.out.println(1 ^ 0);//1
    }

按位“非 ~“,也称为取反操作符,它属于一个一元操作符,只对一个操作符进行操作(其他的操作符都是二元的)。

        System.out.println(10 & 5);//1010 & 0101 结果:0000
        System.out.println(10 | 5);//1010 | 0101 结果:1111 ,10进制就是15
        System.out.println(10 ^ 6);//1010 ^ 0110 结果:1100 ,10进制就是12

我们可以执行按位的"与"、按位"或"、按位"异或"运算,但不能执行按位"非"的运算。按位操作符也可以进行逻辑运算,只是不具备短路运算的功能。在移位表达式中,不能使用布尔运算。

八、移位操作符

public class Example7 {
    @Test
    public void example1() {//左移:按照操作符右侧指定的数位将操作符左边的数向左移,在低位补0
        int i = 5 << 3; //结果:左边的数*2^右边的数,这里是5*2^3=5*8=40
        /**
         * 分析:
         * 5在二进制中是110
         * 110往左移3位就是101000
         * 101000在转换成十进制就40
         */
        System.out.println(i);//40
    }

    @Test
    public void example2() {//右移:按照操作符右侧指定的数位将操作符左边的数向右移,符号为正在高位插入0,符号为负在高位插入1
        int i = 40 >> 3; //结果:左边的数/2^右边的数取模,这里是40/2^3=40/8=5(只限正数)
        /**
         * 分析:
         * 40在二进制中是0010 1000,往右移3位就是0000 0101
         * 101在十进制中是5
         */
        int k = 1 >> 3; //0
        System.out.println(i);//5
        System.out.println(k);//0
        int n = -1 >> 3;//-1
        /**
         * 分析:
         * 1在二进制中是0000 0001
         * -1在二进制中是1的反码+1,即1111 1110 + 1 = 1111 1111
         * 1111 1111往右移三位,高位插1,结果还是1111 1111,即-1
         */
        int m = -5 >> 5;//5是0000 0101,-5是1111 1011,往右移5位高位插1还是1111 1111,即-1
        System.out.println(n);//-1
        System.out.println(m);//-1

        //注:int其实是32位的,这里偷懒了哈
    }

    @Test
    public void example3() {//无符号右移无论正负,高位都是插0
        int i = -1 >>> 3;//-1在二进制中是1111 1111 1111 1111 1111 1111 1111 1111,往右移三位高位插0
        System.out.println(i);//536870911  0001 1111 1111 1111 1111 1111 1111 1111
    }

    @Test
    public void example4() {//移位与=组合使用,左边只能是已经赋值的变量
        int i = 3;
        i <<= 3;
        System.out.println(i);//24
    }
}
        如果对char、byte、short类型的值进行移位处理,那么在移位之前,它们会转换成int类型,并且得到的结果也是一个int类型的值。只有数值右端低5位才有用,这样可以防止我们移位超过int型值所具有的位数。

九、三元操作符

 @Test
    public void example5() {
        int i = 3 > 2 ? 5 : 10;
        System.out.println(i);//5

        boolean b = false;
        int j;
        j = b ? 20 : 30;
        System.out.println(j);//30

        String s = "test";
        s = s.equals("001") ? "yes" : "no";
        System.out.println(s);//no
    }

十、类型转换

@Test
    public void example1() {
        byte b = 5;
        int i = b + 6;
        System.out.println(i);//11,byte类型自动提升了

        int j = 10;
        short s = (short) (j - 6);
        System.out.println(s);//4,计算之后将结果强制转换成short,损失精度

        float f = 20.7f;
        int k = (int) f;
        System.out.println(k);//20,将float强制转换成int,对数字进行示截尾
        System.out.println(Math.round(f));//21,四舍五入
    }


猜你喜欢

转载自blog.csdn.net/alexshi5/article/details/79796812