第二章 Java关键字与运算符(知识点与企业真题)

1.1 关键字、保留字

  • 关键字:被java赋予特殊含义的字符串。
  1. 官方规范中有50个关键字
  2. true、false、null虽然不是关键字,但是可以当做关键字来看待。
  • 保留字:goto、const

1.2 标识符

  • 标识符:凡是可以自己命名的地方,都是标识符。
  1. 比如:类名、变量名、方法名、接口名、包名、常量名等。
  • 记住:标识符命名的规则(必须要遵守的,否则编译不通过)

        >有26个英文字母大小写,0-9,_或$组成
        >数字不可以开头。
        >不可以使用关键字和保留字,但能包含关键字和保留字。
        >Java中严格区分大小写,长度无限制。
        >标识符不能包含空格。

  • 标识符的命名规范(建议遵守。如果不遵守,编译和运行都能正常执行。只是容易被人鄙视)

        >包名:多单词组成时所有字母都小写:xxxyyyzzz。
         例如:java.lang、com.atguigu.bean

        >类名、接口名:多单词组成时,所有单词的首字母大写;XxxYyyZzz
         例如:HelloWorld,String,System等

         >变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
          例如:age,name,bookName,main,binarySearch,getName

         >常量名:所有字母都大写。多单词时每个单词用下划线连接:xxx_yyy_zzz
          例如:MAX_VALUE,PI,DEFAULT_CAPACITY

  • "见名知意"
/*
1.什么是标识符?Java中变量、方法、类等要素命名时使用的字符序列,称为标识符。
技巧:凡是自己可以起名字的地方都叫标识符。比如:类名、方法名、变量名、包名、常量名等

2.标识符的命名规则(必须遵守!!否则,编译不通过)

3.标识符的命名规范

说明:大家在定义标识符时,要注意"见名知意"
*/

class Identifier
{
	public static void main(String[] args){
		int abc =12;
		int age =12; //age:标识符
		int myAge =12;
		char gender = '男';
		//不推荐写法
		//int myAge =12;
		System.out.println(myAge);
	}
	public static void main1(String[] args){
	
	}
}

class _a$b
{
}

class 1_ab{
}

class public
{
}

class publicstring
{
}

1.3 变量的基本使用(重点)

  • 1.变量的理解:

        内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化

  • 2.变量的构成包含三个要素:

        数据类型、变量名、存储的值

  • 3.Java中变量声明的格式:

        数据类型 变量名 = 变量值

  • 4.定义变量时,变量名要遵守标识符命名的规则和规范。
  • 5.说明:

        ① 变量都有其作用域。变量只在作用域内是有效的,出了作用域就失效了。
        ② 在同一个作用域内,不能声明两个同名的变量。
        ③ 定义好变量以后,就可以通过变量名的方式对变量进行调用和运算。
        ④ 变量值在赋值时,必须满足变量的数据类型,并且在数据类型有效的范围内变化。

class VariableTest {
	public static void main(String[] args) {
		//定义变量的方式1:
		char gender; //过程1:变量的声明
		gender = '男'; //过程2:变量的赋值(或初始化)

		gender = '女'; 

		//定义变量的方式2:声明与初始化合并
		int age = 10;

		System.out.println(age);
		System.out.println("age = " + age);
		System.out.println("gender = " + gender);

		//在同一个作用域内,不能声明两个同名的变量
		//char gender = "女";

		gender = '男';
		System.out.println("gender = " + gender);

		//由于number前没有声明类型,即当前number变量没有提前定义。所以编译不通过。
		//number = 10

		byte b1 =127;
		//b1超出了byte的范围,编译不通过
		//b1 = 128

	}
	public static void main123(String[] args){
	//变量gender超出了作用域 -==-
	//System.out.println("gender = " + gender);
	}
}

1.4 基本数据类型变量的使用(重点)

  • 1.Java中的变量按照数据类型来分类:

            基本数据类型(8种):
                整形:byte \ short \ int \ long\
                浮点型:float \ double
                字符型:char
                布尔型:boolean
    
            引用数据类型:
                类(class)
                数组(array)
                接口(interface)

                枚举(enum)
                注解(annotation)
                记录(record)

1.5 基本数据类型变量间的运算规则(重点)

1.5.1 自动类型提升

  • 测试基本数据类型变量间的运算规则
  1. 这里提到可以做运算的基本类型有7种,不包含boolean类型。
  2. 运算规则包括:

      ①自动类型提升
      ②强制类型转换

  3. VariableTest.java用来测试自动类型提升
  • 规则:

           当容量小的变量与容量大的变量做运算时,结果自动转换为容量大的数据类型。

           byte、short、char ----> int ----> long ----> float -----> double

           特别的:byte、short、char类型的变量之间做运算,结果为int类型

           说明:此时容量或大或小,并非指占用的内存空间的大小,而是指表示数据的范围的大小。
           long(8字节)表示数据范围小于float(4字节)

class VariableTest3 {
	public static void main(String[] args) {
		
		int i1 = 10;

		int i2 = i1;

		long l1 = i2;

		float f1 = l1;

		byte b1 = 12;

		byte b2 = 12;

		int i3 = b1 + i1;

		//不兼容的类型: 从int转换到byte可能会有损失
		//byte b2 = b1 + i1;
		

		//****************************************
		//特殊情况1:byte、short、char之间做运算,默认为int类型做运算

		//不兼容的类型: 从int转换到byte可能会有损失
		//byte b3 = b1 + b2;

		byte b3 = 12;
		short s1 = 12;
		//不兼容的类型: 从int转换到byte可能会有损失
		//byte b4 = b3 + s1;

		int i4 =b3 + s1;

		//特殊情况2:char
		char c1 = 'a';
		//不兼容的类型: 从int转换到char可能会有损失
		//char c2 = c1 + b1;

		//****************************************
		//练习1:
		long l2 = 123L;
		long l3 = 123;// 编译可以通过,理解为自动类型提升 (int ------>long)

		//错误: 整数太大,理解为int类型,因为超出了int范围,所以会报错。
		//long l4 = 123123123123;

		long l5 = 123123123123L;//此时的123123123123L就是使用8个字节存储的long类型的值

		//练习2:

		float f2 = 12.3F;
		
		//不兼容的类型: 从double转换到float可能会有损失,默认的浮点数为double类型
		//float f3 = 12.3;

		//练习3:
		//规定:整形常量,默认规定是int类型。
		byte b4 = 10;
		
		//不兼容的类型: 从int转换到byte可能会有损失
		//byte b5 = b4 + 1;

		//规定2:浮点型常量,默认规定是double类型。

		double d1 = b4 + 12.3;

		//练习4:说明为什么不允许变量名是数字开头的。为了"自洽"
		
		//错误: 不是语句
		/*
		int 123L  = 23;
		long l6 = 123L;
		*/

		
	}
}

1.5.2 强制类型转换

  • 规则:
  1. 如果需要将容量达到变量的类型转换为容量小的变量的类型,需要使用强制类型转换
  2. 强制类型转换需要使用墙砖符:()。
  3. 强制类型转换过程中,可能导致精度损失。
class VariableTest4{
	public static void main(String[] args){
		double d1 = 12;

		int i1 = (int)d1;
		System.out.println(i1); //打印12
		
		long l1 =123L;
		short s1 = (short)l1;
		System.out.println(s1);//打印123

		//练习
		int i2 = 12;
		float f1 = i2;//(自动类型提升)
		System.out.println(f1);//打印12.0

		float f2 = (float)i2;//编译可以通过,只不过可以省略()。

		//精度损失的例子1:
		double d2 = 12.9;
		int i3 = (int)d2;
		System.out.println(i3);//截断,不是四舍五入,打印12

		//精度损失的例子2:
		int i4 = 128;
		byte b1 = (byte)i4;
		System.out.println(b1);//打印-128

		//实际开发举例:
		byte b2 =12;//int num = b2;自动类型提升
		method(b2);//打印num + 12

		long l2 = 12L;
		method((int)l2);//打印num + 12


	}

	public static void method(int num){

		System.out.println("num + " + num);
	
	}
}

1.6 String类的使用、与基本数据类型变量间的运算

  • String的认识:字符串。使用一对""表示,内部包含0个、1个或多个字符。
  • String与8种基本数据类型变量间的运算:+ (连接)。运算的结果是String类型。
  • 一、关于String的理解
  1. String类,属于引用数据类型,俗称字符串。
  2. String类型的变量,可以使用一对""的方式进行赋值。
  3. String声明的字符串内部,可以包含0个,1个或多个字符。
  • 二、String与基本数据类型变量间的运算
  1. 这里的基本数据类型包含boolean在内的8种。
  2. String与基本数据类型变量间只能做连接运算,使用"+"表示
  3. 运算的结果是String类型。
class  StringTest{
	public static void main(String[] args) 	{
		String str1 = "Hello World!";
		System.out.println("str1"); //打印 str1
		System.out.println(str1); //打印 Hello World!

		String str2 = "";
		String str3 = "a";//与char c1 = 'a';的区别,一个是引用数据类型,一个是基本数据类型。除了是a,没有共同点

		//测试连接运算
		int num1 = 10;
		boolean b1 = true;
		String str4 = "hello";

		System.out.println(str4 + b1);// 打印hellotrue

		String str5 = str4 + b1;
		String str6 = str4 + b1 + num1;
		System.out.println(str6);//打印hellotrue10

		//思考:如下的声明编译能通过吗?
		//String str7 = b1 + num1 +str4;//基本数据类型能做运算的只有7种,不包含boolean类型。当boolean类型+int类型时,这里的"+"不是连接的作用,是运算的作用,连接作用只在String类型的运算中。

		//如何将String类型的变量转换为基本数据类型?
		String str8 = "abc";//不能考虑转换为基本数据类型的。

		int num2 = 10;
		String str9 = num2 + "";//"10"
		//不兼容的类型: String无法转换为int
		//int num3 = (int)str9;

		//如何实现呢?使用Integer类。
		int num3 = Integer.parseInt(str9);
		System.out.println(num3 + 1);//打印11

	}
}
  • 练习1:
  • 要求填写自己的姓名、年龄、性别、体重、婚姻状况(已婚用true表示,单身用false表示)、联系方式等等。
/*
要求填写自己的姓名、年龄、性别、体重、婚姻状况(已婚用true表示,单身用false表示)、联系方式等等。
*/

class StringExer{
	public static void main(String[] args) 	{
		String name = "油条不是老油条";
		int age = 23;
		char gengder = '女';
		double weight = 98.3;
		boolean isMarried = false;
		String phoneNumber = "154282824399";
		System.out.println("name = " + name + ";age = " + age + ";gengder = " + gengder + ";weight = "+ weight + ";isMarried = " + isMarried);
	}
}
  • 练习2:
class StringExer1{
	public static void main(String[] args) 	{
		//练习1:
		//String str1 = 4;			//这里String类型要加"",没有加就会报错
		String str2 = 3.5f + "";
		System.out.println(str2);   //打印3.5,因为3.5f表示float类型,所以不会打印3.5f
		System.out.println(3 + 4 + "Hello!"); //打印 7Hello!
		System.out.println("Hello!" + 3 + 4); //打印Hello!34
		System.out.println('a' + 1 + "Hello!"); //打印98Hello!
		System.out.println("Hello" + 'a' + 1); //打印Helloa1

		//练习2:
		System.out.println("*	*");			//输出*    *
		System.out.println("*\t*");				//输出*    *
		System.out.println("*" + "\t" + "*");   //输出*    *
		System.out.println('*' + "\t" + "*");   //输出*    *
		System.out.println('*' + '\t' + "*");   //输出51*
		System.out.println("*" + '\t' + '*');   //输出*    *
		System.out.println('*' + "\t" + '*');   //输出*    *
		System.out.println("*" + "\t" + '*');   //输出*    *
		System.out.println('*' + '\t' + '*');   //输出93
	}
}

1.7 常识:进制的认识

  • 熟悉:二进制(以0B或0b开头)、十进制、八进制(以0开头)、十六进制(以0x或0X开头)的声明方式。
  • 二进制的理解
  1. 正数:原码、反码、补码三码合一。
  2. 负数:原码、反码、补码不相同。以1开头的一定是补码。了解三者关系,原码取反为反码,反码+1为补码。
  3. 计算机的底层是以补码的方式存储数据的。
  • 熟悉:二进制与十进制之间的转换
  • 了解:二进制与八进制、十六进制间的转换
class BinaryTest{
	public static void main(String[] args) 	{
		int num1 = 123;
		int num2 = 0b1010;
		int num3 = 0123;
		int num4 = 0x123;
		System.out.println(num1);
		System.out.println(num2);
		System.out.println(num3);
		System.out.println(num4);
	}
}

1.8 运算符(较常用的是重点)

1.8.1算术运算符

  1. +   -   *   /   %   (前)++   (后)++    (前)--    (后)--     +(连接)

class AriTest{
	public static void main(String[] args) 	{
		//********************************
		//除法:
		int m1 = 12;
		int n1 = 5;
		int k1 = m1 / n1;
		System.out.println(k1);//输出2(截断)
		System.out.println(m1 / n1 * n1);//输出10

		//********************************
		//取模(或取余):%
		System.out.println(m1 % n1);//输出2

		//开发中,经常用来判断某个数num1能整除另外一个数num2。num1 % num2 == 0
		//比如:判断num1是否是偶数:num1 % 2 == 0

		//结论:取模以后,结果与被模数的符号相同
		int m2 = 12;
		int n2 = 5;
		System.out.println(m2 % n2);//输出2

		int m3 = -12;
		int n3 = 5;
		System.out.println(m3 % n3);//输出-2

		int m4 = 12;
		int n4 = -5;
		System.out.println(m4 % n4);//输出2

		int m5 = -12;
		int n5 = -5;
		System.out.println(m5 % n5);//输出-2

		//********************************
		//(前)++ :先自增1,后运算
		//(后)++ :先运算,后自增1
		int a1 = 10;
		int b1 = ++a1;
		System.out.println("a1 = " + a1 + ",b1 = " + b1); //输出a1 = 11,b1 = 11

		int a2 = 10;
		int b2= a2++;
		System.out.println("a2 = " + a2 + ",b2 = " + b2); //输出a2 = 11,b2 = 10

		//练习1:
		int i = 10;
		//i++;
		++i;//这两种方法相同
		System.out.println("i = " + i); //输出i = 11

		//练习2:
		short s1 = 10;
		//方式1:
		
		//s1 = s1 + 1;
		s1 = (short)(s1 + 1);
		System.out.println(s1); //输出s1 = 11

		//方式2:
		s1++;
		System.out.println(s1); //输出12

		//********************************
		//(前)-- :先自减1,在运算
		//(后)++ :先运算,再自减1

		//结论:++或--运算,不会改变变量的数据类型

		//+ :连接符,只使用于String与其他类型的变量间的运算,而且运算的结果也是String类型。
	}
}
  • 练习1:
随意给出三位数的整数,打印显示它的个位数,十位数,百位数的值。
格式如下:
数字XXX的情况如下:
个位数:
十位数:
百位数:

例如:
数字153的情况如下:
个位数:3
十位数:5
百位数:1
class  AriExer{
	public static void main(String[] args) 	{
		int num1 = 153;
		int ge = num1 % 10;
		int shi = num1 /10 % 10;
		int bai = num1 /100;

		System.out.println("个位数是" + ge);
		System.out.println("十位数是" + shi);
		System.out.println("百位数是" + bai);
	}
}
  • 练习2:
class AriExer1{
	public static void main(String[] args) 	{
		int hours = 89;
		int day = hours / 24;
		int hour = hours % 24;

		System.out.println("共奋战了" + day + "天零" + hour + "小时");

		//额外的练习1:
		System.out.println("5+5=" + 5 + 5); //输出5+5=55
		System.out.println("5+5=" + (5 + 5)); //输出5+5=10

		//额外的练习2:
		byte bb1 = 127;
		bb1++;
		System.out.println("bb1 = " + bb1); //-128

		//额外的练习3:
		int i = 1;
		int j = i++;
		System.out.println(j); //i-->1,i-->j,i-->2,最后输出1

		//额外的练习3:
		int m = 1;
		m= m++;
		System.out.println(m); //m-->1,m-->m,m-->2,m-->1最后输出1
	}
}

1.8.2 赋值运算符

  1. =  +=  -=  *=  \=  %=
  2. 说明:

        ①当"-"两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理。
        ②支持连续赋值。
        ③+=  -=  *=  \=  %= 操作,不会改变变量本身的数据类型。

class SetValTest{
	public static void main(String[] args) 	{
		//******************************
		int i = 5;

		long l = 1;//自动类型转换

		byte b = (byte)i;//强制类型转换

		//操作方式1:
		int a1 = 10;

		int b1 = 10;

		//操作方式2:
		int a2;
		int b2;
		//或合并: int a2,b2; //也是可以通过的
		a2 = b2 = 10;
		System.out.println(a2+","+b2);

		//******************************
		//说明 += 的使用
		int m1 = 10;
		m1 += 5;//类似于m1 = m1 + 5;
		System.out.println(m1);

		byte by1 = 10;
		by1 += 5;//by1 = by1 + 5操作会编译报错,因为将int型赋值给byte型。应该写为:by1 = (byte)(by1 + 5);
		System.out.println(by1);

		int m2 = 1;
		m2 *= 0.1;
		System.out.println(m2);

		//练习1:如何实现变量的值增加2。
		//方式1:
		int s1 = 10;
		s1 = s1 + 2;

		//方式2;推荐
		int s2 = 10;
		s2 += 2;
		
		//练习2:如何实现变量的值增加1。
		//方式1:
		int c1 = 10;
		c1 = c1 + 1;

		//方式2:
		int c2 = 10;
		c1 += 1;

		//方式3;推荐
		int c3 = 10;
		c3++;

		//练习3:
		int m = 2;
		int n = 3;
		n *= m++;
		System.out.println("m = " + m);//m = 3;
		System.out.println("n = " + n);//n= 6;

		//练习4:
		int n1 = 11;
		n1 += (n1++) + (++n1);//n1=11 ---> n1=11 , ---> n1=n12 + (n++11) + (++n12) ---> 常数为25 ---> n1=32
		System.out.println(n1);//n1=35

		}
}

1.8.3 比较运算符

  1. == != > < >= <= instanceof
  2. 说明

        ① instanceof 在面向对象的多态性的位置讲解。
        ② == != > < >= <=适用于基本数据类型。(细节: > < >= <= 不适用于boolean类型 ) 运算的结果为boolean类型。
        ③ 了解:== !=可以适用于引用数据类型
        ④ 区分: == 与 = 的区别

class CompareTest{
	public static void main(String[] args) 	{
		int m1 = 10;
		int m2 = 20;
		boolean compare1 = m1 > m2;
		System.out.println(compare1); //输出false

		int n1 = 10;
		int n2 = 20;
		System.out.println(n1 == n2);//输出false
		System.out.println(n1 = n2);//20

		boolean b1 = false;
		boolean b2 = true;
		System.out.println(b1 == b2);//输出false
		System.out.println(b1 = b2);//输出true
	}
}
  • 练习:
  1. 要求:
今天是周2,10天以后是周几?

要求:控制台输出"今天是周2,10天以后是周X"。
class ConditionExer{
	public static void main(String[] args) {
		int week = 2;
		week = 4;
		
		week += 10;

		week %= 7;

		System.out.println("今天是周2,10天以后是周" + ((week == 0)? "天" : week));//因为(week == 0)? "天" : week不用输出值,所以字符串和整形类型不一致也没关系。
	}
}

1.8.4 逻辑运算符

  1. &   &&   |   ||   !   ^
  2. 说明:

        ① 逻辑运算符针对boolean类型的变量进行的操作。
        ② 逻辑运算符运算的结果也是boolean类型。
        ③ 逻辑运算符常使用条件判断结构、循环结构中

class LogicTest{
	public static void main(String[] args) 	{
		/*
		//***********************************
		区分:&(逻辑与)和&&(短路与)
		1、相同点:两个符号表达的都是"且"的关系。只有当符号左右两边的类型值均为true时,结果才为true。
		2、执行过程:
			1)如果符号左边是true,则& 、&& 都会执行符号右边的操作
			2)如果符号左边是false,则& 会执行符号右边的操作
									  && 不会执行符号右边的操作
		3、开发中,推荐使用&&
		*/
		//比较&时
		boolean b1 = false;
		
		int num1 = 10;
		
		if(b1 & (num1++ > 0)){
			System.out.println("窗前明月光");
		}else{
			System.out.println("我是郭德纲");//打印
			}

		System.out.println("num1 =" + num1);//输出11

		//比较&&时
		boolean b2 = false;
		
		int num2 = 10;
		
		if(b2 && (num2++ > 0)){
			System.out.println("窗前明月光");
		}else{
			System.out.println("我是郭德纲");//打印
			}

		System.out.println("num2 =" + num2);//输出10

		//***************************************
		//***************************************

		//比较&时
		boolean b3 = false;
		b3 = true;
		
		int num3 = 10;
		
		if(b3 & (num3++ > 0)){
			System.out.println("窗前明月光");//打印
		}else{
			System.out.println("我是郭德纲");
			}

		System.out.println("num3 =" + num3);//输出11

		//比较&&时
		boolean b4 = false;
		b4 = true;
		
		int num4 = 10;
		
		if(b4 && (num4++ > 0)){
			System.out.println("窗前明月光");//打印
		}else{
			System.out.println("我是郭德纲");
			}

		System.out.println("num4 =" + num4);//输出11


		/*
		//***********************************
		区分:|(逻辑或)和||(短路或)
		1、相同点:两个符号表达的都是"或"的关系。只有当符号左右两边的类型值均为false时,结果才为false。
		2、执行过程:
			1)如果符号左边是false,则| 、|| 都会执行符号右边的操作
			2)如果符号左边是true, 则| 会执行符号右边的操作
									  || 不会执行符号右边的操作
		3、开发中,推荐使用||
		*/
		//比较|时
		boolean b5 = false;
		
		int num5 = 10;
		
		if(b5 | (num5++ > 0)){
			System.out.println("窗前明月光");//打印
		}else{
			System.out.println("我是郭德纲");
			}

		System.out.println("num5 =" + num5);//输出11

		//比较||时
		boolean b6 = false;
		
		int num6 = 10;
		
		if(b6 || (num6++ > 0)){
			System.out.println("窗前明月光");//打印
		}else{
			System.out.println("我是郭德纲");
			}

		System.out.println("num6 =" + num6);//输出11

		//***************************************
		//***************************************

		//比较|时
		boolean b7 = false;
		b7 = true;
		
		int num7 = 10;
		
		if(b7 | (num7++ > 0)){
			System.out.println("窗前明月光");//打印
		}else{
			System.out.println("我是郭德纲");
			}

		System.out.println("num7 =" + num7);//输出11

		//比较||时
		boolean b8 = false;
		b8 = true;
				
		int num8 = 10;
		
		if(b8 || (num8++ > 0)){
			System.out.println("窗前明月光");//打印
		}else{
			System.out.println("我是郭德纲");
			}

		System.out.println("num8 =" + num8);//输出10
	}
}

通过以上例子:区分两个点

	区分:&(逻辑与)和&&(短路与)
		1、相同点:两个符号表达的都是"且"的关系。只有当符号左右两边的类型值均为true时,结果才为true。
		2、执行过程:
			1)如果符号左边是true,则& 、&& 都会执行符号右边的操作
			2)如果符号左边是false,则& 会执行符号右边的操作
									  && 不会执行符号右边的操作
		3、开发中,推荐使用&&
区分:|(逻辑或)和||(短路或)
		1、相同点:两个符号表达的都是"或"的关系。只有当符号左右两边的类型值均为false时,结果才为false。
		2、执行过程:
			1)如果符号左边是false,则| 、|| 都会执行符号右边的操作
			2)如果符号左边是true, 则| 会执行符号右边的操作
									  || 不会执行符号右边的操作
		3、开发中,推荐使用||
  • 练习:
  1. 定义类LogicExer
  2. 定义main方法
  3. 定义一个int类型变量a,变量b,都赋值为20
  4. 定义boolean类型变量bo1,判断++a 是否被3整除,并且a++是否被7整除,将结果赋值给 bo1
  5. 输出a的值,bo1的值
  6. 定义boolean类型变量bo2,判断b++ 是否被3整除,并且++b 是否被7整除,将结果赋值给 bo2
  7. 输出b的值,bo2的值
class LogicExer{
	public static void main(String[] args) 
		{
		int a,b;
		a = b = 20;
		boolean bo1 = (++a % 3 == 0) && (a++ % 7 == 0);
		System.out.println("b = " + b + ",bo1 = " + bo1);//b = 20,bo1 = true;
		boolean bo2 = (++b % 3 == 0) && (b++ % 7 == 0);
		System.out.println("b = " + b + ",bo2 = " + bo2);//b = 22,bo1 = true;

		//练习1,区分&& 和 &
		int x = 1;
		int y = 1;

		if(x++ == 2 & ++y == 2){
			x = 7;
		}
		System.out.println("x = " + x + ", y = " + y);//输出x = 2,y = 2

		//*******************
		int x1 = 1, y1 = 1;
		if (x1++ == 2 && ++y1 == 2){
			x1 = 7;
		}
		System.out.println("x1 = " + x1 + ", y1 = " + y1); //输出x1 = 2,y1 = 1

		//练习2,区分|| 和 |
		int x2 = 1;
		int y2 = 1;

		if(x2++ == 1 | ++y2 == 1){
			x2 = 7;
		}
		System.out.println("x2 = " + x2 + ", y2 = " + y2);//输出x2 = 7,y2 = 2

		//*******************
		int x3 = 1, y3 = 1;
		if (x3++ == 1 || ++y3 == 1){
			x3 = 7;
		}
		System.out.println("x3 = " + x3 + ", y3 = " + y3); //输出x3 = 7,y3 = 1

		//练习3
		boolean x4 = true;
		boolean y4 = false;
		short z4 = 42;

		if ((z4++ == 42) && (y4 = true)){
			z4++;
		}
		if ((x4 = false) || (++z4 == 45)){
			z4++;
		}
		System.out.println("z4 = " + z4); //输出z = 46
	}
}

1.8.5 位运算符(了解)

  • 1. << >> >>> & | ^ ~ 
  • 2. 

        ① << >> >>> & | ^ ~ :针对数值类型的变量或常量进行运算,运算的结果也是数值
        ② 
        <<:在一定范围内,每向左移动一位,结果就在原有的基础上*2。(对于正数、负数都适用)
        >>:在一定范围内,每向右移动一位,结果就在原有的基础上/2,如果不能整除,向下取整。(对于正数、负数都适用)

  • 3.面试题:如何高效的方式计算2*8?

        2 << 3 或 8 << 1

class BitTest{
	public static void main(String[] args) 	{
		//******************************
		//<<
		int num1 = 7;
		System.out.println("num1 << 1 :" + (num1 << 1));//输出14
		System.out.println("num1 << 2 :" + (num1 << 2));//输出28
		System.out.println("num1 << 3 :" + (num1 << 3));//输出56
		System.out.println("num1 << 28 :" + (num1 << 28));//输出是正数
		System.out.println("num1 << 29 :" + (num1 << 29));//输出是负数,过犹不及,所以是在一定范围内的左移
		int num2 = -7;
		System.out.println("num2 << 1 :" + (num2 << 1));//输出-14
		System.out.println("num2 << 2 :" + (num2 << 2));//输出-28
		System.out.println("num2 << 3 :" + (num2 << 3));//输出-56

		//******************************
		//>>
		int num3 = 69;
		System.out.println("num3 >> 1 :" + (num3 >> 4));//输出4
		/*
		69的二进制:     0000 0000 0000 0000 0000 0000 0100 0101
		 69 >> 4:(补0)	 0000 0000 0000 0000 0000 0000 0000 0100  (右边移出去四位)0101 ,69 >> 4类似于69/2^4 = 69/16=4
		*/

		int num4 = -69;
		System.out.println("num4 >> 1 :" + (num4 >> 4));//输出-5
		/*
		-69的二进制:
			   原码:	1000 0000 0000 0000 0000 0000 0100 0101
			   反码:	1111 1111 1111 1111 1111 1111 1011 1010
			   补码:	1111 1111 1111 1111 1111 1111 1011 1011
		-69 >> 4:(补1)  1111 1111 1111 1111 1111 1111 1111 1011  (右边移走了四位)
			   反码:   1111 1111 1111 1111 1111 1111 1111 1010
			   原码:   1000 0000 0000 0000 0000 0000 0000 0101  (-5)                   -69 >> 4类似于-69/2^4 = -69/16=-5
		*/
		
		//******************************
		//>>>,往右移动后,左边空出来的位直接补0。(正数、负数都适用)
		int num5 = 69;
		System.out.println("num5 >>> 1 :" + (num5 >> 4));//输出4
		/*
		69的二进制:     0000 0000 0000 0000 0000 0000 0100 0101
		 69 >> 4:(补0)	 0000 0000 0000 0000 0000 0000 0000 0100  (右边移出去四位)0101 ,69 >> 4类似于69/2^4 = 69/16=4
		*/

		int num6 = -69;
		System.out.println("num6 >> 1 :" + (num6 >> 4));//输出-5
		/*
		-69的二进制:
			   原码:	1000 0000 0000 0000 0000 0000 0100 0101
			   反码:	1111 1111 1111 1111 1111 1111 1011 1010
			   补码:	1111 1111 1111 1111 1111 1111 1011 1011
		-69 >> 4:(补0)  0000 1111 1111 1111 1111 1111 1111 1011  (右边移走了四位)
			   反码:   0000 1111 1111 1111 1111 1111 1111 1011
			   原码:   0000 1111 1111 1111 1111 1111 1111 1011
			   最高位是0,是正数,那么原码,反码,补码都一样
		*/

		//******************************
		//&
		System.out.println(9 & 7);//输出1
		/*
		& 是 且的意思,只有两者都为1,&的结果才为1
		9的二进制:0000 0000 0000 0000 0000 0000 0000 1001
		7的二进制:0000 0000 0000 0000 0000 0000 0000 0111
		9 & 7:    0000 0000 0000 0000 0000 0000 0000 0001	(输出1)
		*/

		System.out.println(-9 & 7);//输出7
		/*
		-9的二进制:
			原码: 1000 0000 0000 0000 0000 0000 0000 1001
			反码: 1111 1111 1111 1111 1111 1111 1111 0110
			补码: 1111 1111 1111 1111 1111 1111 1111 0111
		7的二进制: 0000 0000 0000 0000 0000 0000 0000 0111
		-9 & 7:    0000 0000 0000 0000 0000 0000 0000 0111	(输出7)
			补码: 0000 0000 0000 0000 0000 0000 0000 0111
			反码: 0000 0000 0000 0000 0000 0000 0000 0111
			原码: 0000 0000 0000 0000 0000 0000 0000 0111
		*/
		//******************************
		//|
		System.out.println(9 | 7);//输出15
		/*
		| 是 或的意思,只要有1个为1,|的结果就为1
		9的二进制:0000 0000 0000 0000 0000 0000 0000 1001
		7的二进制:0000 0000 0000 0000 0000 0000 0000 0111
		9 & 7:    0000 0000 0000 0000 0000 0000 0000 1111	(输出15)
		*/

		System.out.println(-9 | 7);//输出-9
		/*
		| 是 或的意思,只要有1个为1,|的结果就为1
		-9的二进制:
			原码:		1000 0000 0000 0000 0000 0000 0000 1001
			反码:		1111 1111 1111 1111 1111 1111 1111 0110
			补码:		1111 1111 1111 1111 1111 1111 1111 0111
		7的二进制:		0000 0000 0000 0000 0000 0000 0000 0111
		-9 | 7:(补码)    1111 1111 1111 1111 1111 1111 1111 0111	(输出15)
			  (反码)	1111 1111 1111 1111 1111 1111 1111 0110
			  (原码)	1000 0000 0000 0000 0000 0000 0000 1001 (输出-9)

		*/
		
		//******************************
		//^
		/*
		0^1结果为1
		1^1结果为1
		1^1结果为0
		0^0结果为0

		*/
		System.out.println(9 ^ 7);//输出14
		/*
		
		9的二进制:0000 0000 0000 0000 0000 0000 0000 1001
		7的二进制:0000 0000 0000 0000 0000 0000 0000 0111
		9 & 7:    0000 0000 0000 0000 0000 0000 0000 1110	(输出14)
		*/

		System.out.println(-9 | 7);//输出-9
		/*
		
		-9的二进制:
			原码:		 1000 0000 0000 0000 0000 0000 0000 1001
			反码:		 1111 1111 1111 1111 1111 1111 1111 0110
			补码:		 1111 1111 1111 1111 1111 1111 1111 0111
		7的二进制:		 0000 0000 0000 0000 0000 0000 0000 0111
		-9 | 7:(补码)    1111 1111 1111 1111 1111 1111 1111 0111	
			  (反码)	 1111 1111 1111 1111 1111 1111 1111 0110
			  (原码)	 1000 0000 0000 0000 0000 0000 0000 1001 (输出-9)

		*/

		//******************************
		//~
		/*
		0~结果为1
		1~结果为0
		*/
		System.out.println(~9);//输出-10
		/*
		
		9的二进制: 0000 0000 0000 0000 0000 0000 0000 1001
		~9的二进制:
			 补码:1111 1111 1111 1111 1111 1111 1111 0110
			 反码:1111 1111 1111 1111 1111 1111 1111 0101
			 原码:0000 0000 0000 0000 0000 0000 0000 1010  (输出-10)
		*/

		System.out.println(~(-9));//输出8
		/*
		
		-9的二进制:
			原码:		1000 0000 0000 0000 0000 0000 0000 1001
			反码:		1111 1111 1111 1111 1111 1111 1111 0110
			补码:		1111 1111 1111 1111 1111 1111 1111 0111
		7的二进制:		0000 0000 0000 0000 0000 0000 0000 1000 (输出8)

		*/




		System.out.println("~9 :" + ~9);//输出-10
		System.out.println("~(-10) :" + ~(-10));//输出9
	}
}
  • 练习:
  • 案例2:如何交换两个int型变量的值?String呢?
class BitExer{
	public static void main(String[] args) {
		//方法1:声明一个临时变量。(推荐)
		int m = 10;
		int n = 20;
		System.out.println("m = " + m + ",n = " + n);
		int temp = m;
		m = n;
		n = temp;
		System.out.println("m = " + m + ",n = " + n);

		//方法2:优点:不需要定义临时变量。缺点:难、适用性差(不适用于非数值类型、可能超出int范围)
		m = m + n;  //m = 30 = 10 + 20
		n = m - n;  //n = 10 = 30 - 20
		m = m - n;  //m= 20 = 30 - 10

		//方法3:优点:不需要定义临时变量。缺点:真难、适用性差(不适用于非数值类型)
		m = m ^ n; 
		n = m ^ n;  //(m ^ n) ^ n ----> m
		m = m ^ n;  
		System.out.println("m = " + m + ",n = " + n);
	}
}

1.8.6 条件运算符

  • 知识点
1.(条件表达式)? 表达式1 : 表达式2

2.说明:
① 条件表达式的结果是boolean类型。
② 如果条件表达式的结果是true,则执行表达式1。否则,执行表达式2。
③ 表达式1 和 表达式2 需要是相同的类型或能兼容的类型。

④ 开发中,凡是可以使用条件运算符的位置,都可以改写为if-else。
		  反之,能使用if-else结构,不一定能改写为条件运算符。

  建议,在二者都能使用的情况下,推荐使用条件运算符。因为执行率稍高
  • 代码:
class ConditionTest{
	public static void main(String[] args){
		String info = (2 > 1)? "表达式1" : "表达式2";
		System.out.println(info);

		double result = (3 > 4)? 1 : 2.0;
		System.out.println(result);

		//练习1:获取两个整数的较大值

		int m = 30;
		int n = 12;
		int max = (m > n)? m : n;
		System.out.println("较大值为:" + max);

		//练习2:获取三个整数的最大值
		int i = 20;
		int j = 10;
		int k = 34;
		int tempMax = (i > j)? i : j;
		int finalMax = (tempMax > k)? tempMax : k;
		System.out.println(finalMax);

		//合并以后的写法:不推荐
		int finalMax1 = (((i > j)? i : j) > k)? ((i > j)? i : j) : k;
		System.out.println(finalMax1);
	}
}
  • 练习:
  • 今天是周2,10天以后是周几?

    要求:控制台输出"今天是周2,10天以后是周X"。

class ConditionExer{
	public static void main(String[] args) {
		int week = 2;
		week = 4;
		
		week += 10;

		week %= 7;

		System.out.println("今天是周2,10天以后是周" + ((week == 0)? "天" : week));//因为(week == 0)? "天" : week不用输出值,所以字符串和整形类型不一致也没关系。
	}
}

1.8.7运算符的优先级

  • 如果想体现优先级比较高,使用()
  • 我们在编写一执行语句时,不要出现太多的运算符。

二、企业真题

1.高效的方式计算2*8的值。

使用2 << 3 或者 8  << 1

2.& 和 &&的区别?

既有相同点,又有不同点,在false时体现。

3.java中的基本类型有哪些?String是最基本的数据类型吗?

8种数据类型。

String不是,属于引用数据类型。

4.java中的基本数据类型包括那些?(同3)
5.java开发中计算金额时使用什么数据类型?

不能使用float或double,因为精度不高。

使用BigDecimal类替换,可以实现任意精度的数据的运算。

6.char型变量中能不能存储一个中文汉字,为什么?

可以的。
 

char c1 = '中';

char c2 = 'a';

因为char使用的是unicode字符集,包含了世界范围的所有的字符。

7.代码分析
short s1 = 1;
s1 = s1 + 1;  //错在右边是int型,s1是short型,需要强制转换
short s1 = 1;
s1 += 1;   //没有错
8.int i = 0; i = i++ 执行这两句话后变量i的值为

0。因为是(后)++,先运算,后赋值。

9.如何将两个变量的值互换
String s1 = "abc";
String s2 = "123";

String temp = s1;
s1 = s2;
s2 = temp;
10.boolean占几个字节
编译不谈占几个字节

但是JVM在给boolean类型分配内存空间时,boolean类型的变量占据一个槽位(slot,等于4个字节)。
细节:true:1  false:0

>扩展:在内存中,byte\short\char\boolean\int\float  :占用1个slot
                double\long :占用2个slot
11.为什么java中0.1+0.2结果不是0.3?
在代码中测试0.1+0.2,你会惊讶的发现,结果不是0.3,而是0.3000......4。这是为什么?

几乎所有现代的编程语言都会遇到上述问题,包括JavaScript、Ruby、Python、Swift和Go等。引发这个问题的原因是,它们都采用了IEEE 754标准。

IEEE是指"电子与电子工程师协会",其在1985年发布了一个IEEE 754计算标准,根据这个标准,小数的二进制表达能够有最大的精度上限提升。但无论如何,物理边界是突破不了的,它仍然不能实现  "每一个十进制小数,都对应一个二进制小数"  。正因如此,产生了0.1+0.2不等于0.3的问题。

具体的:

整数变为二进制,能够做到"每一个十进制小数,都对应一个二进制小数",比如数字3,二进制就是11;再比如数字43就是二进制101011,这个毫无争议。

对于小数,并不能做到"每一个十进制小数,都对应一个二进制小数"。举例来说,二进制小数0.0001表示十进制数0.0625(至于它是如何计算的,不用深究);二进制小数0.0010表示十进制数0.125;二进制小数0.0011表示十进制数0.1875。看,对于四位的二进制小数,二进制小数虽然是连贯的,但是十进制小数却不是连贯的。比如,你无法用四位二进制小数的形式表示0.125~0.1875之间的十进制小数。

所以在编程中,遇见小数判断相等情况,比如开发银行、交易等系统,可以采用"四舍五入"或者"同乘同除"等方式进行验证,避免上述问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值