javaSE(变量与运算符、流程控制语句)

自学 java+大数据 第二天


一、变量与运算符

1.1 关键字、保留字

说明:

  1. 关键字一共50个,其中constgoto保留字(reserved word)。
  2. truefalsenull`不在其中,它们看起来像关键字,其实是字面量,表示特殊的布尔值和空值。
  • 关键字:被Java赋予特殊含义的字符串。

    • 官方规范中有50个关键字
    • true、false、null虽然不是关键字,但是可以当做关键字来看待。
  • 保留字:goto 、 const

1.2 标识符

  • 标识符:凡是可以自己命名的地方,都是标识符。
    • 比如:类名、变量名、方法名、接口名、包名、常量名等
  • 记住:标识符命名的规则(必须要遵守的,否则编译不通过)
> 由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
  • “见名知意”
class IdentifierTest{
	public static void main(String[] args){
		
		int abc = 12;
		int age = 12; //age :标识符


		char gender = '男';

		char c1 = '女';
		
		//不推荐的写法
		//int myage = 12;

		//System.out.println(myage);

		int myAge = 12;
		
	}

	public static void main1(String[] args){
		
	}
}


class _a$bc{
}

/*
class 1abc{
}
*/

class Public{
}

class publicstatic{
}

class BiaoShiFuTest{
}

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

  1. 变量的理解:内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化
  2. 变量的构成包含三个要素:数据类型、变量名、存储的值
  3. Java中变量声明的格式:数据类型 变量名 = 变量值
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 = '男';
		
		//由于number前没有声明类型,即当前number变量没有提前定义。所以编译不通过。
		//number = 10;

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

	}

	public static void main123(String[] args) {
		//System.out.println("gender = " + gender);

		char gender = '女';
		
	}
}

说明:

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

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

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


	基本数据类型(8种):
		整型:byte \ short \ int \ long 
		浮点型:float \ double 
		字符型:char
		布尔型:boolean

	引用数据类型:
		类(class)
		数组(array)
		接口(interface)

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

测试整型和浮点型:

/*
测试整型和浮点型变量的使用


*/
class VariableTest1 {
	public static void main(String[] args) {
		
		//1.测试整型变量的使用
		// byte(1字节=8bit) \ short(2字节) \ int(4字节) \ long(8字节) 

		byte b1 = 12;
		byte b2 = 127;
		//编译不通过。因为超出了byte的存储范围
		//byte b3 = 128;

		short s1 = 1234;

		int i1 = 123234123;
		//① 声明long类型变量时,需要提供后缀。后缀为'l'或'L'
		long l1 = 123123123L;

		//② 开发中,大家定义整型变量时,没有特殊情况的话,通常都声明为int类型。

		//2.测试浮点类型变量的使用
		//float \ double
		double d1 = 12.3;
		//① 声明long类型变量时,需要提供后缀。后缀为'f'或'F'
		float f1 = 12.3f;
		System.out.println("f1 = " + f1);

		//② 开发中,大家定义浮点型变量时,没有特殊情况的话,通常都声明为double类型,因为精度更高。

		//③ float类型表数范围要大于long类型的表数范围。但是精度不高。

		//测试浮点型变量的精度
		//结论:通过测试发现浮点型变量的精度不高。如果在开发中,需要极高的精度,需要使用BigDecimal类替换浮点型变量。
		//测试1
		System.out.println(0.1 + 0.2);

		//测试2:
		float ff1 = 123123123f;
		float ff2 = ff1 + 1;
		System.out.println(ff1);
		System.out.println(ff2);
		System.out.println(ff1 == ff2);
		
	}
}

测试字符型和布尔型:

/*
测试字符类型和布尔类型的使用


*/
class VariableTest2 {
	public static void main(String[] args) {
		
		//1.字符类型:char(2字节)

		//表示形式1:使用一对''表示,内部有且仅有一个字符
		char c1 = 'a';
		char c2 = '中';
		char c3 = '1';
		char c4 = '%';
		char c5 = 'γ';
		
		//编译不通过
		//char c6 = '';
		//char c7 = 'ab';

		//表示形式2:直接使用Unicode值来表示字符型常量。
		char c8 = '\u0036';
		System.out.println(c8);

		//表示形式3:使用转义字符
		char c9 = '\n';
		char c10 = '\t';
		System.out.println("hello" + c10 + "world");

		//表示形式4:使用具体字符对应的数值(比如ASCII码)
		char c11 = 97;
		System.out.println(c11);//a

		char c12 = '1';
		char c13 = 1;

		//2. 布尔类型:boolean
		//① 只有两个取值:true 、 false
		boolean bo1 = true;
		boolean bo2 = false;
		
		//编译不通过
		//boolean bo3 = 0;
		//② 常使用在流程控制语句中。比如:条件判断、循环结构等
		boolean isMarried = true;
		if(isMarried){
			System.out.println("很遗憾,不能参加单身派对了");
		}else{
			System.out.println("可以多谈几个女朋友或男朋友");
		}
		//③ 了解:我们不谈boolean类型占用的空间大小。但是,真正在内存中分配的话,使用的是4个字节。
	}
}

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

1.5.1 自动类型提升
/*
测试基本数据类型变量间的运算规则。

1. 这里提到可以做运算的基本数据类型有7种,不包含boolean类型。
2. 运算规则包括:
		① 自动类型提升
		② 强制类型转换

3. 此VariableTest3.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 = i1;

		float f1 = l1;


		byte b1 = 12;
		int i3 = b1 + i1;

		//编译不通过
		//byte b2 = b1 + i1;
		
		//**********************************************
		//特殊的情况1:byte、short之间做运算
		byte b3 = 12;
		short s1 = 10;
		//编译不通过
		//short s2 = b3 + s1;
		i3 = b3 + s1;

		byte b4 = 10;
		//编译不通过
		//byte b5 = b3 + b4;

		//特殊的情况2:char
		char c1 = 'a';
		//编译不通过
		//char c2 = c1 + b3;
		int i4 = c1 + b3;


		//**********************************************
		//练习1:
		long l2 = 123L;
		long l3 = 123; //理解为:自动类型提升 (int--->long)

		//long l4 = 123123123123; //123123123123理解为int类型,因为超出了int范围,所以报错。
		long l5 = 123123123123L;//此时的123123123123L就是使用8个字节存储的long类型的值
		
		//练习2:
		float f2 = 12.3F;
		//编译不通过
		//float f3 = 12.3; //不满足自动类型提升的规则(double --> float)。所以报错

		//练习3:
		//规定1:整型常量,规定是int类型。
		byte b5 = 10;
		//byte b6 = b5 + 1;
		int ii1 = b5 + 1;
		//规定2:浮点型常量,规定是double类型。
		double dd1 = b5 + 12.3;

		//练习4:说明为什么不允许变量名是数字开头的。为了“自洽”
		/*
		int 123L = 12;
		long l6 = 123L;
		*/
	}
}
1.5.2 强制类型转换
/*
此VariableTest4.java用来测试强制类型转换

规则:
1. 如果需要将容量大的变量的类型转换为容量小的变量的类型,需要使用强制类型转换
2. 强制类型转换需要使用强转符:()。在()内指明要转换为的数据类型。
3. 强制类型转换过程中,可能导致精度损失。
*/
class VariableTest4 {
	public static void main(String[] args) {
		
		double d1 = 12;//自动类型提升
		
		//编译失败
		//int i1 = d1;

		int i2 = (int)d1;
		System.out.println(i2);


		long l1 = 123;
		//编译失败
		//short s1 = l1;
		short s2 = (short)l1;
		System.out.println(s2);


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

		float f2 = (float)i3; //编译可以通过。只不过可以省略()而已。
		
		//精度损失的例子1:
		double d2 = 12.9;
		int i4 = (int)d2;
		System.out.println(i4);

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


		//实际开发举例:
		byte b2 = 12;
		method(b2);

		long l2 = 12L;
		//编译不通过
		//method(l2);
		method((int)l2);
	}

	public static void method(int num){   //int num = b2;自动类型提升
		System.out.println("num = " + num);
	}
}

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

  • String的认识:字符串。使用一对""表示,内部包含0个、1个或多个字符。
  • String与8种基本数据类型变量间的运算:+。运算的结果是String类型。
/*

基本数据类型与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");
		System.out.println(str1);


		String str2 = ""; 
		String str3 = "a";//char c1 = 'a';


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

		System.out.println(str4 + b1);

		String str5 = str4 + b1;
		String str6 = str4 + b1 + num1;
		System.out.println(str6);//hellotrue10
		
		//思考:如下的声明编译能通过吗?不能
		//String str7 = b1 + num1 + str4;

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

		int num2 = 10;
		String str9 = num2 + ""; //"10"
		//编译不通过
		//int num3 = (int)str9;

		//如何实现呢?使用Integer类。暂时大家了解。
		int num3 = Integer.parseInt(str9);
		System.out.println(num3 + 1);
		
	}
}
  • 练习1
/*
要求填写自己的姓名、年龄、性别、体重、婚姻状况(已婚用true表示,单身用false表示)、联系方式等等。
*/
class StringExer {
	public static void main(String[] args) {
		
		String name = "李进";
		int age = 24;
		char gender = '男';
		double weight = 130.5;
		boolean isMarried = false;
		String phoneNumber = "13012341234";

		String info = "name = " + name + ",age = " + age + ",gender = " + gender + ",weight = " + 
			weight + ",isMarried = " + isMarried + ",phoneNumber = " + phoneNumber;

		System.out.println(info);
	}
}

  • 练习2
class StringExer1 {
	public static void main(String[] args) {
		
		//练习1:
		//String str1 = 4;                       //判断对错:no
		String str2 = 3.5f + "";               //判断str2对错:yes
		System.out.println(str2);              //输出:3.5
		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' + '*');		//输出:93

	}
}

1.7 常识:进制的认识

  • 熟悉:二进制(以0B、0b开头)、十进制、八进制(以0开头)、十六进制(以0x或0X开头)的声明方式。
  • 二进制的理解
    • 正数:原码、反码、补码三码合一。
    • 负数:原码、反码、补码不相同。了解三者之间的关系。
    • 计算机的底层是以补码的方式存储数据的。
  • 熟悉:二进制与十进制之间的转换
  • 了解:二进制与八进制、十六进制间的转换

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

1.8.1 算术运算符
/*
测试运算符的使用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
		
		//*******************************
		//取模(或取余): %
		int i1 = 12;
		int j1 = 5;
		System.out.println(i1 % j1); //2

		//开发中,经常用来判断某个数num1能整除另外一个数num2。  num1 % num2 == 0
		//比如:判断num1是否是偶数: num1 % 2 == 0
		
		//结论:取模以后,结果与被模数的符号相同
		int i2 = -12;
		int j2 = 5;
		System.out.println(i2 % j2); //-2

		int i3 = 12;
		int j3 = -5;
		System.out.println(i3 % j3); //2

		int i4 = -12;
		int j4 = -5;
		System.out.println(i4 % j4); //-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);//11

		//练习2:
		short s1 = 10;
		//方式1:

		//编译不通过
		//s1 = s1 + 1;

		//s1 = (short)(s1 + 1);
		//System.out.println(s1);

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

		//*******************************
		//(前)-- :先自减1,再运算
		//(后)-- :先运算,再自减1
		//略
		
		//结论:++ 或 -- 运算,不会改变变量的数据类型!

		//+ :连接符,只适用于String与其他类型的变量间的运算,而且运算的结果也是String类型。

	}
}

练习1:

/*
随意给出一个三位的整数,打印显示它的个位数,十位数,百位数的值。
格式如下:
数字xxx的情况如下:
个位数:
十位数:
百位数:

例如:
数字153的情况如下:
个位数:3
十位数:5
百位数:1

*/
class AriExer {
	public static void main(String[] args) {
		
		int num = 153;
		int ge = num % 10; //个位
		int shi = num / 10 % 10; //十位.   或者 int shi = num % 100 / 10
		int bai = num / 100;

		System.out.println("个位是:" + ge);
		System.out.println("十位是:" + shi);
		System.out.println("百位是:" + bai);

	}
}

练习2:

/*

案例2:为抵抗洪水,战士连续作战89小时,编程计算共多少天零多少小时?
*/
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);
		System.out.println("5+5=" + (5 + 5));

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

		//额外的练习3:
		//int i = 1;
		//int j = i++ + ++i * i++;

		//System.out.println("j = " + j);//10

		//额外的练习4:
		int i = 2;
		int j = i++;
		System.out.println(j); //2


		int k = 2;
		int z = ++k;
		System.out.println(z);//3

		int m = 2;
		m = m++;
		System.out.println(m); //2

	}
}

1.8.2 赋值运算符
/*
测试运算符的使用2:赋值运算符

1. =   +=、 -=、*=、 /=、%=  

2. 说明:
① 当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理。
② 支持连续赋值。
③ +=、 -=、*=、 /=、%=  操作,不会改变变量本身的数据类型。
*/
class SetValueTest {
	public static void main(String[] args) {

		//***********************************
		int i = 5;

		long l = 10; //自动类型提升

		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);

		//操作方式3:
		//int a3 = 10;
		//int b3 = 20;

		int a3 = 10,b3 = 20;
		System.out.println(a3 + "," + b3);

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

		byte by1 = 10;
		by1 += 5; //by1 = by1 + 5操作会编译报错。应该写为: by1 = (byte)(by1 + 5);
		System.out.println(by1);


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

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

		//方式2:推荐
		int n2 = 10;
		n2 += 2;

		//错误的写法:
		//int n3 = 10;
		//n3++++;

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

		//方式2:
		int i2 = 10;
		i2 += 1;

		//方式3:推荐
		int i3 = 10;
		i3++; //++i3;

	}
}

1.8.3 比较运算符
/*
测试运算符的使用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);

		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.8.4 逻辑运算符
/*
测试运算符的使用4:逻辑运算符

1.  & &&  |  ||  ! ^
2. 说明:
① 逻辑运算符针对的都是boolean类型的变量进行的操作
② 逻辑运算符运算的结果也是boolean类型。
③ 逻辑运算符常使用条件判断结构、循环结构中


*/
class LogicTest {
	public static void main(String[] args) {
				
		/*
		区分:& 和 &&
		
		1、相同点:两个符号表达的都是"且"的关系。只有当符号左右两边的类型值均为true时,结果才为true。

		2、执行过程:
			1)如果符号左边是true,则& 、&& 都会执行符号右边的操作
			2)如果符号左边是false,则 & 会继续执行符号右边的操作
			                           && 不会执行符号右边的操作
		3、开发中,我们推荐使用&& 
		*/
		boolean b1 = true;
		b1 = false;

		int num1 = 10;

		if(b1 & (num1++ > 0)){
			System.out.println("床前明月光");
		}else{
			System.out.println("我叫郭德纲");
		}
		
		System.out.println("num1 = " + num1);

		//

		boolean b2 = true;
		b2 = false;

		int num2 = 10;

		if(b2 && (num2++ > 0)){
			System.out.println("床前明月光");
		}else{
			System.out.println("我叫郭德纲");
		}
		
		System.out.println("num2 = " + num2);

		//********************************************
		/*
		区分:| 和 ||
		
		1、相同点:两个符号表达的都是"或"的关系。只要符号两边存在true的情况,结果就为true.

		2、执行过程:
			1)如果符号左边是false,则| 、|| 都会执行符号右边的操作
			2)如果符号左边是true,则 | 会继续执行符号右边的操作
			                          || 不会执行符号右边的操作
		3、开发中,我们推荐使用||
		*/
		boolean b3 = false;
		b3 = true;

		int num3 = 10;

		if(b3 | (num3++ > 0)){
			System.out.println("床前明月光");
		}else{
			System.out.println("我叫郭德纲");
		}
		
		System.out.println("num3 = " + num3);

		//

		boolean b4 = false;
		b4 = true;

		int num4 = 10;

		if(b4 || (num4++ > 0)){
			System.out.println("床前明月光");
		}else{
			System.out.println("我叫郭德纲");
		}
		
		System.out.println("num4 = " + num4);
	}
}

练习:

/*
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("a = " + a + ",bo1 = " + bo1);

		
		boolean bo2 = (b++ % 3 == 0) && (++b % 7 == 0);
		
		System.out.println("b = " + b + ",bo2 = " + bo2);
		

	}
}

1.8.5 位运算符(了解)
/*
测试运算符的使用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));
		System.out.println("num1 << 2 : " + (num1 << 2));
		System.out.println("num1 << 3 : " + (num1 << 3));
		System.out.println("num1 << 28 : " + (num1 << 28));
		System.out.println("num1 << 29 : " + (num1 << 29));//过犹不及

		int num2 = -7;
		System.out.println("num2 << 1 : " + (num2 << 1));
		System.out.println("num2 << 2 : " + (num2 << 2));
		System.out.println("num2 << 3 : " + (num2 << 3));

		System.out.println(~9);
		System.out.println(~-10);

		
		

	}
}

练习:

/*
案例2:如何交换两个int型变量的值?String呢?

*/
class BitExer {
	public static void main(String[] args) {
		
		int m = 10;
		int n = 20;

		System.out.println("m = " + m + ",n = " + n);

		//交换两个变量的值
		//方式1:声明一个临时变量。(推荐)
		//int temp = m;
		//m = n;
		//n = temp;

		//方式2:优点:不需要定义临时变量。  缺点:难、适用性差(不适用于非数值类型)、可能超出int的范围
		//m = m + n; //30 = 10 + 20;
		//n = m - n; //10 = 30 - 20;
		//m = m - n; //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 条件运算符
/*
测试运算符的使用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 > 10)? "表达式1" : "表达式2";
		System.out.println(info);

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

		//练习1:获取两个整数的较大值
		int m = 10;
		int n = 20;

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

		//练习2:获取三个整数的最大值
		int i = 20;
		int j = 30;
		int k = 23;

		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);
	}
}

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

二、企业真题

1. 高效的方式计算2 * 8的值 (文**辉、轮*科技)

使用 <<

2. &和&&的区别?(恒*电子、*度)

3. Java中的基本类型有哪些?String 是最基本的数据类型吗?(恒*电子)

8种基本数据类型。(略)

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

4. Java中的基本数据类型包括哪些?(*米)

类似问题:
> Java的基础数据类型有哪些?String是吗?(贝壳)

5. Java开发中计算金额时使用什么数据类型?(5*到家)

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

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

6. char型变量中能不能存储一个中文汉字,为什么?(*通快递)

可以的。char c1 = ‘中’;

char c2 = ‘a’。

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

7. 代码分析(君*科技、新*陆)

short s1=1; 
s1=s1+1;  //有什么错?  =右边是int类型。需要强转
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之间的十进制小数。

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


二、流程控制语句

2.1 (了解)流程控制结构

  • 顺序结构
  • 分支结构
    • if-else
    • switch-case
  • 循环结构
    • for
    • while
    • do-while

2.2 分支结构之1:if-else

  • 在程序中,凡是遇到了需要使用分支结构的地方,都可以考虑使用if-else。
  • if-else嵌套的练习多关注
基本语法
/*
分支结构1:if-else条件判断结构

1. 格式
格式1:
if(条件表达式){
  	语句块;
}

格式2:"二选一"
if(条件表达式) { 
  	语句块1;
}else{
  	语句块2;
}

格式3:"多选一"
if (条件表达式1) {
  	语句块1;
} else if (条件表达式2) {
  	语句块2;
}
...
}else if (条件表达式n) {
 	语句块n;
} else {
  	语句块n+1;
}


*/
class IfElseTest {
	public static void main(String[] args) {
		
		/*
		案例1:成年人心率的正常范围是每分钟60-100次。体检时,
		如果心率不在此范围内,则提示需要做进一步的检查。
		*/
		int heartBeats = 89;
		//错误的写法:if(60 <= heartBeats <= 100){

		if(heartBeats < 60 || heartBeats > 100){
			System.out.println("你需要做进一步的检查");
		}

		System.out.println("体检结束");

		//**********************************
		/*
		案例2:定义一个整数,判定是偶数还是奇数    
		*/
		int num = 13;
		if(num % 2 == 0){
			System.out.println(num + "是偶数");
		}else{
			System.out.println(num + "是奇数");
		}
	}
}

案例
/*
岳小鹏参加Java考试,他和父亲岳不群达成承诺:
如果:
成绩为100分时,奖励一辆跑车;
成绩为(80,99]时,奖励一辆山地自行车;
当成绩为[60,80]时,奖励环球影城一日游;
其它时,胖揍一顿。

说明:默认成绩是在[0,100]范围内

结论:
1. 如果多个条件表达式之间没有交集(理解是互斥关系),则哪个条件表达式声明在上面,哪个声明在下面都可以。
   如果多个条件表达式之间是包含关系,则需要将范围小的条件表达式声明在范围大的条件表达式的上面。否则,范围小的条件表达式不可能被执行。


*/
class IfElseTest1 {
	public static void main(String[] args) {
		
		int score = 61;

		//方式1:
		/*
		if(score == 100){
			System.out.println("奖励一辆跑车");
		}else if(score > 80 && score <= 99){
			System.out.println("奖励一辆山地自行车");
		}else if(score >= 60 && score <= 80){
			System.out.println("奖励环球影城一日游");
		}else{
			System.out.println("胖揍一顿");
		}
		*/
		
		//方式2:
		score = 88;

		if(score == 100){
			System.out.println("奖励一辆跑车");
		}else if(score > 80){
			System.out.println("奖励一辆山地自行车");
		}else if(score >= 60){
			System.out.println("奖励环球影城一日游");
		}else{
			System.out.println("胖揍一顿");
		}

		//特别的:
		if(score == 100){
			System.out.println("奖励一辆跑车");
		}else if(score > 80){
			System.out.println("奖励一辆山地自行车");
		}else if(score >= 60){
			System.out.println("奖励环球影城一日游");
		}
		/*else{
			System.out.println("胖揍一顿");
		}
		*/
		
	}
}

/*
测试if-else的嵌套使用

案例:
由键盘输入三个整数分别存入变量num1、num2、num3,对它们进行排序(使用 if-else if-else),并且从小到大输出。

拓展:你能实现从大到小顺序的排列吗?

1. 从开发经验上讲,没有写过超过三层的嵌套if-else结构。
2. 如果if-else中的执行语句块中只有一行执行语句,则此执行语句所在的一对{}可以省略。但是,不建议省略
*/
class IfElseTest2 {
	public static void main(String[] args) {
		
		int num1 = 30;
		int num2 = 21;
		int num3 = 44;

		//int num1 = 30,num2 = 21,num3 = 44;

		if(num1 >= num2){
			if(num3 >= num1)
				System.out.println(num2 + "," + num1 + "," + num3);
			else if(num3 <= num2)
				System.out.println(num3 + "," + num2 + "," + num1);
			else
				System.out.println(num2 + "," + num3 + "," + num1);	
				//System.out.println(num2 + "," + num3 + "," + num1);	
				
		}else{ // num1 < num2
			if(num3 >= num2){
				System.out.println(num1 + "," + num2 + "," + num3);
			}else if(num3 <= num1){
				System.out.println(num3 + "," + num1 + "," + num2);
			}else{
				System.out.println(num1 + "," + num3 + "," + num2);
			}
		}

	}
}

1.3 分支结构之2:switch-case

  • 在特殊的场景下,分支结构可以考虑使用switch-case

    • 指定的数据类型:byte \ short \ char \ int ; 枚举类(jdk5.0)\ String (jdk7.0)
    • 可以考虑的常量值有限且取值情况不多。
  • 特别之处:case穿透。

  • 在能使用switch-case的情况下,推荐使用switch-case,因为比if-else效率稍高

基本语法
/*
分支结构之switch-case的使用

1. 语法格式

switch(表达式){
	
	case 常量1:
		//执行语句1
		//break;
	case 常量2:
		//执行语句2
		//break;
	...
	default:
		//执行语句2
		//break;
}

2.执行过程:
根据表达式中的值,依次匹配case语句。一旦与某一个case中的常量相等,那么就执行此case中的执行语句。
执行完此执行语句之后,
		情况1:遇到break,则执行break后,跳出当前的switch-case结构
		情况2:没有遇到break,则继续执行其后的case中的执行语句。 ---> case 穿透
				...
			   直到遇到break或者执行完所有的case及default中的语句,退出当前的switch-case结构

3. 说明:
① switch中的表达式只能是特定的数据类型。如下:byte \ short \ char \ int \ 枚举(JDK5.0新增) \ String(JDK7.0新增)
② case 后都是跟的常量,使用表达式与这些常量做相等的判断,不能进行范围的判断。
③ 开发中,使用switch-case时,通常case匹配的情况都有限。
④ break:可以使用在switch-case中。一旦执行此break关键字,就跳出当前的switch-case结构
⑤ default:类似于if-else中的else结构。
           default是可选的,而且位置是灵活的。

4. switch-case 与if-else之间的转换
① 开发中凡是可以使用switch-case结构的场景,都可以改写为if-else。反之,不成立
② 开发中,如果一个具体问题既可以使用switch-case,又可以使用if-else的时候,推荐使用switch-case。
  为什么?switch-case相较于if-else效率稍高。

*/
class SwitchCaseTest{
	public static void main(String[] args){
		
		int num = 1;
		switch(num){
			
			case 0:
				System.out.println("zero");
				break; 
			case 1:
				System.out.println("one");
				break; //结束当前的switch-case结构
			case 2:
				System.out.println("two");
				break; 
			case 3:
				System.out.println("three");
				break; 
			default:
				System.out.println("other");
				//break; 
		}

		//另例:
		String season = "summer";
        switch (season) {
            case "spring":
                System.out.println("春暖花开");
                break;
            case "summer":
                System.out.println("夏日炎炎");
                break;
            case "autumn":
                System.out.println("秋高气爽");
                break;
            case "winter":
                System.out.println("冬雪皑皑");
                break;
            /*default:
                System.out.println("季节输入有误");
                break;
			*/
        }

		//错误的例子:编译不通过
		/*
		int number = 20;
		switch(number){
			case number > 0:
				System.out.println("正数");
                break;
			case number < 0:
				System.out.println("负数");
                break;
			default:
				System.out.println("零");
                break;
		}
		*/
	}
}
案例
/*
案例3:使用switch-case实现:对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。

*/
class SwitchCaseTest1 {
	public static void main(String[] args) {
		//定义一个学生成绩的变量
		int score = 78;

		//根据需求,进行分支
		//方式1:
		/*
		switch(score){
			case 0:
				System.out.println("不及格");
				break;
			case 1:
				System.out.println("不及格");
				break;
			//...
			
			case 100:
				System.out.println("及格");
				break;
			default:
				System.out.println("成绩输入有误");
				break;
		
		}
		*/
		//方式2:体会case穿透
		switch(score / 10){
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
				System.out.println("不及格");
				break;
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
				System.out.println("及格");
				break;
			default:
				System.out.println("成绩输入有误");
				break;
		}

		//方式3:
		switch(score / 60){
			case 0:
				System.out.println("不及格");
				break;
			case 1:
				System.out.println("及格");
				break;
			default:
				System.out.println("成绩输入有误");
				break;
		}
	}
}

/*
案例:编写程序:从键盘上输入2023年的“month”和“day”,要求通过程序输出输入的日期为2023年的第几天。
*/
import java.util.Scanner;

class SwitchCaseTest2 {
	public static void main(String[] args) {
		//1.使用Scanner,从键盘获取2023年的month、day
		Scanner input = new Scanner(System.in);

		System.out.println("请输入2023年的月份:");
		int month = input.nextInt();//阻塞式方法

		System.out.println("请输入2023年的天:");
		int day = input.nextInt();

		//假设用户输入的数据是合法的。后期我们在开发中,使用正则表达式进行校验。

		//2. 使用switch-case实现分支结构
		int sumDays = 0;//记录总天数
		//方式1:不推荐。存在数据的冗余
		/*
		switch(month){
			case 1:
				sumDays = day;
				break;
			case 2:
				sumDays = 31 + day;
				break;
			case 3:
				sumDays = 31 + 28 + day;
				break;
			case 4:
				sumDays = 31 + 28 + 31 + day;
				break;
			//...
			case 12:
				sumDays = 31 + 28 + ... + 30 + day;
				break;
		
		}
		*/
		//方式2:
		switch(month){
			case 12:
				sumDays += 30;
			case 11:
				sumDays += 31;
			case 10:
				sumDays += 30;
			case 9:
				sumDays += 31;
			case 8:
				sumDays += 31;
			case 7:
				sumDays += 30;
			case 6:
				sumDays += 31;
			case 5:
				sumDays += 30;
			case 4:
				sumDays += 31;
			case 3:
				sumDays += 28; //28:2月份的总天数
			case 2:
				sumDays += 31; //31:1月份的总天数
			case 1:
				sumDays += day;
				//break;
		}
		

		System.out.println("2023年" + month + "月" + day + "日是当前的第" + sumDays + "天");
		
		
		input.close();//为了防止内存泄漏
	}
}

1.4 循环结构之1:for

  • 凡是循环结构,都有4个要素:①初始化条件 ②循环条件(是boolean类型) ③ 循环体 ④ 迭代条件
  • 应用场景:有明确的遍历的次数。 for(int i = 1;i <= 100;i++)
基本语法
/*
循环结构之一:for循环

1. Java中规范了3种循环结构:for、while、do-while
2. 凡是循环结构,就一定会有4个要素:
① 初始化条件
② 循环条件 ---> 一定是boolean类型的变量或表达式
③ 循环体
④ 迭代部分

3. for循环的格式

for(①;②;④){
	③
}

执行过程:① - ② - ③ - ④ - ② - ③ - ④ - ... - ②

*/
class ForTest {
	public static void main(String[] args) {
		//需求1:题目:输出5行HelloWorld
		/*
		System.out.println("HelloWorld");
		System.out.println("HelloWorld");
		System.out.println("HelloWorld");
		System.out.println("HelloWorld");
		System.out.println("HelloWorld");
		*/

		for(int i = 1;i <= 50;i++){
			System.out.println("HelloWorld");
		}
		
		//此时编译不通过。因为i已经出了其作用域范围。
		//System.out.println(i);

		//需求2:
		int num = 1;
        for(System.out.print("a");num < 3;System.out.print("c"),num++){
            System.out.print("b");

        }

		//输出结果:abcbc

		System.out.println();//换行

		//需求3:遍历1-100以内的偶数,并获取偶数的个数,获取所有的偶数的和
		int count = 0;//记录偶数的个数

		int sum = 0;//记录所有偶数的和

		for(int i = 1;i <= 100;i++){

			if(i % 2 == 0){
				System.out.println(i);
				count++;
				sum += i; //sum = sum + i;
			}	
		}

		System.out.println("偶数的个数为:" + count);
		System.out.println("偶数的总和为:" + sum);
		
	}
}

案例
/*
题目:输出所有的水仙花数,所谓水仙花数是指一个3位数,其各个位上数字立方和等于其本身。
例如: 153 = 1*1*1 + 3*3*3 + 5*5*5
*/
class ForTest1 {
	public static void main(String[] args) {
		
		//遍历所有的3位数
		for(int i = 100;i <= 999;i++){
			
			//针对于每一个三位数i,获取其各个位上数值
			int ge = i % 10;
			int shi = i / 10 % 10;  //或 int shi = i % 100 / 10
			int bai = i / 100;

			//判断是否满足水仙花数的规则
			if(i == ge * ge * ge + shi * shi * shi + bai * bai * bai){
				System.out.println(i);
			}

		}
	}
}

/*
案例:输入两个正整数m和n,求其最大公约数和最小公倍数。

比如:12和20的最大公约数是4,最小公倍数是60。

约数:12为例,约数有1,2,3,4,6,12
      20为例,约数有1,2,4,5,10,20

倍数:12为例,倍数有12,24,36,48,60,72,....
      20为例,倍数有20,40,60,80,....


说明:
1. 我们可以在循环结构中使用break。一旦执行break,就跳出(或结束)当前循环结构。
2. 如何结束一个循环结构?
	方式1:循环条件不满足。(即循环条件执行完以后是false)
	方式2:在循环体中执行了break

*/
class ForTest2 {
	public static void main(String[] args) {

		int m = 12;
		int n = 20;

		//获取m和n中的较小值
		int min = (m < n)? m : n;

		//需求1:最大公约数
		//方式1:
		int result = 1;
		for(int i = 1;i <= min;i++){
			if(m % i == 0 && n % i == 0){
				//System.out.println(i);
				result = i;
			}

		}

		System.out.println(result);

		//方式2:推荐
		for(int i = min;i >= 1;i--){
			if(m % i == 0 && n % i == 0){
				System.out.println("最大公约数为:" + i);
				break;//一旦执行,就跳出当前循环结构。
			}
		}

		//需求2:最小公倍数
		int max = (m > n)? m : n;
		for(int i = max;i <= m * n;i++){
			if(i % m == 0 && i % n == 0){
				System.out.println("最小公倍数为:" + i);
				break;
			}
		}
	}
}

1.5 循环结构之2:while

  • 应用场景:没有明确的遍历次数。
基本语法
/*
循环结构之一:while循环


1. 凡是循环结构,就一定会有4个要素:
① 初始化条件
② 循环条件 ---> 一定是boolean类型的变量或表达式
③ 循环体
④ 迭代部分

2.while的格式

①
while(②){
	③
	④
}

3.执行过程:① - ② - ③ - ④ - ② - ③ - ④ - ... - ②

4. for循环与while循环可以相互转换!

5. for循环和while循环的小区别:初始化条件的作用域范围不同。while循环中的初始化条件在while循环结束后,依然有效。
*/
class WhileTest {
	public static void main(String[] args) {
		
		//需求1:遍历50次HelloWorld
		int i = 1;
		while(i <= 50){
			System.out.println("HelloWorld");
			i++;//一定要小心!不要丢了
		}

		//需求2:遍历1-100以内的偶数,并获取偶数的个数,获取所有的偶数的和
		int j = 1;

		int count = 0;//记录偶数的个数
		int sum = 0;//记录偶数的总和
		while(j <= 100){
			if(j % 2 == 0){
				System.out.println(j);
				count++;
				sum += j;
			}
			j++;
		}

		System.out.println("偶数的个数为:" + count);
		System.out.println("偶数的总和为:" + sum);
	}
}

案例
/*
随机生成一个100以内的数,猜这个随机数是多少?

从键盘输入数,如果大了,提示大了;如果小了,提示小了;如果对了,就不再猜了,并统计一共猜了多少次。

提示:生成一个[a,b] 范围的随机数的方式:(int)(Math.random() * (b - a + 1) + a)
*/
import java.util.Scanner;
class WhileTest1 {
	public static void main(String[] args) {

		//1. 生成一个[1,100]范围的随机整数
		int random = (int)(Math.random() * 100) + 1;

		//2. 使用Scanner,从键盘获取数据
		Scanner scan = new Scanner(System.in);
		System.out.print("请输入1-100范围的一个整数:");
		int guess = scan.nextInt();

		//3.声明一个变量,记录猜的次数
		int guessCount = 1;

		//4. 使用循环结构,进行多次循环的对比和获取数据
		while(random != guess){

			if(guess > random){
				System.out.println("你输入的数据大了");
			}else if(guess < random){
				System.out.println("你输入的数据小了");
			}//else{
			//	break;
			//}
			
			System.out.print("请输入1-100范围的一个整数:");
			guess = scan.nextInt();
			guessCount++;

		}

		//能结束结束,就意味着random和guess相等了
		System.out.println("恭喜你!猜对了!");
		System.out.println("共猜了" + guessCount + "次");
		
		
		scan.close();

	}
}

/*
世界最高山峰是珠穆朗玛峰,它的高度是8848.86米,假如我有一张足够大的纸,它的厚度是0.1毫米。
请问,我折叠多少次,可以折成珠穆朗玛峰的高度?

*/
class WhileTest2 {
	public static void main(String[] args) {
		
		//1. 声明珠峰的高度、纸的默认厚度
		double paper = 0.1;//单位:毫米
		double zf = 8848860;//单位:毫米
		

		//2. 定义一个变量,记录折纸的次数
		int count = 0;


		//3. 通过循环结构,不断调整纸的厚度 (当纸的厚度超过珠峰高度时,停止循环)
		while(paper <= zf){
			
			paper *= 2;
			count++;

		}
		
		System.out.println("paper的高度为:" + (paper / 1000) + ",超过了珠峰的高度" + (zf/1000));
		System.out.println("共折纸" + count + "次");


	}
}

1.6 循环结构之3:do-while

  • 至少会执行一次循环体。
  • 开发中,使用的较少
基本语法
/*
循环结构之一:do-while循环


1. 凡是循环结构,就一定会有4个要素:
① 初始化条件
② 循环条件 ---> 一定是boolean类型的变量或表达式
③ 循环体
④ 迭代部分

2. do-while的格式

①
do{
	③
	④
}while(②);

执行过程:① - ③ - ④ - ② - ③ - ④ - .... - ②

3. 说明:
1) do-while循环至少执行一次循环体。
2) for、while、do-while循环三者之间是可以相互转换的。
3) do-while循环结构,在开发中,相较于for、while循环来讲,使用的较少。

*/
class DoWhileTest {
	public static void main(String[] args) {
		
		//需求:遍历100以内的偶数,并输出偶数的个数和总和
		int i = 1;
		int count = 0;//记录偶数的个数
		int sum = 0;//记录偶数的总和

		do{
			if(i % 2 == 0){
				System.out.println(i);
				count++;
				sum += i;
			}

			i++;

		}while(i <= 100);
		
		System.out.println("偶数的个数为:" + count);
		System.out.println("偶数的总和为:" + sum);

		//***************************
		int num1 = 10;
		while(num1 > 10){
			System.out.println("while:hello");
			num1--;
		}

		int num2 = 10;
		do{
			System.out.println("do-while:hello");
			num2--;
		}while(num2 > 10);
	}
}

案例
/*
题目:模拟ATM取款

声明变量balance并初始化为0,用以表示银行账户的余额,下面通过ATM机程序实现存款,取款等功能。

=========ATM========
   1、存款
   2、取款
   3、显示余额
   4、退出
请选择(1-4):
*/
import java.util.Scanner;
class DoWhileTest1 {
	public static void main(String[] args) {
		
		//1. 定义balance的变量,记录账户余额
		double balance = 0.0;

		boolean flag = true; //控制循环的结束

		Scanner scan = new Scanner(System.in);//实例化Scanner

		do{
			//2. 声明ATM取款的界面
			System.out.println("=========ATM========");
			System.out.println("   1、存款");
			System.out.println("   2、取款");
			System.out.println("   3、显示余额");
			System.out.println("   4、退出");
			System.out.print("请选择(1-4):");

			//3. 使用Scanner获取用户的选择
			
			int selection = scan.nextInt();
			switch(selection){
				//4. 根据用户的选择,决定执行存款、取款、显示余额、退出的操作
				case 1:
					System.out.print("请输入存款的金额:");
					double money1 = scan.nextDouble();
					if(money1 > 0){
						balance += money1;
					}
					break;
				case 2:
					System.out.print("请输入取款的金额:");
					double money2 = scan.nextDouble();
					
					if(money2 > 0 && money2 <= balance){
						balance -= money2;
					}else{
						System.out.println("输入的数据有误或余额不足");
					}


					break;
				case 3:
					System.out.println("账户余额为:" + balance);
					break;
				case 4 :
					flag = false;
					System.out.println("感谢使用,欢迎下次光临^_^");
					break;
				default:
					System.out.println("输入有误,请重新输入");
					//break;
			
			}
		
		
		}while(flag);

		
		//关闭资源
		scan.close();

		

	}
}

1.7 “无限”循环

基本语法
/*

"无限"循环结构的使用

1. 格式: while(true)  或  for(;;)

2.开发中,有时并不确定需要循环多少次,需要根据循环体内部某些条件,来控制循环的结束(使用break)。

3. 如果此循环结构不能终止,则构成了死循环!开发中要避免出现死循环。
*/
class ForWhileTest {
	public static void main(String[] args) {
		/*
		for(;;){//while(true){
			System.out.println("I love you!");
		}
		*/
		
		//死循环的后面不能有执行语句。
		//System.out.println("end");

		
	}
}

案例
/*
案例:从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序。

*/
import java.util.Scanner;
class ForWhileTest1 {
	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);

		int positiveCount = 0;//记录正数的个数
		int negativeCount = 0;//记录负数的个数
		
		for(;;){//while(true){
			System.out.print("请输入一个整数(输入为0时结束程序):");
			int num = scan.nextInt(); //获取用户输入的整数

			if(num > 0){ //正数
				positiveCount++;
			}else if(num < 0){ //负数
				negativeCount++;
			}else{ //零
				System.out.println("程序结束");
				break;
			}
		
		
		}
		
		System.out.println("正数的个数为:" + positiveCount);
		System.out.println("负数的个数为:" + negativeCount);


		scan.close();
	}
}

1.8 嵌套循环

基本语法
/*
嵌套循环的使用

1. 嵌套循环:是指一个循环结构A的循环体是另一个循环结构B。
- 外层循环:循环结构A
- 内层循环:循环结构B

2. 说明:
1)内层循环充当了外层循环的循环体。
2)对于两层嵌套循环来说,外层循环控制行数,内层循环控制列数。
3)举例:外层循环执行m次,内层循环执行n次,则内层循环的循环体共执行m * n次
4)实际开发中,我们不会出现三层以上的循环结构,三层的循环结构都很少见。
*/
class ForForTest {
	public static void main(String[] args) {
		
		//******
		for(int i = 1;i <= 6;i++){
			System.out.print('*');
		}

		System.out.println("\n##################");
		
		/*

		******
		******
		******
		******
		******

		*/
		
		for(int j = 1;j <= 5;j++){

			for(int i = 1;i <= 6;i++){
				System.out.print('*');
			}

			System.out.println();
		}
		
		/*
						i(第几行)		j(每一行中*的个数)
		*				1				1
		**				2				2
		***				3				3
		****			4				4
		*****			5				5

		*/
		for(int i = 1;i <= 5;i++){
			
			for(int j = 1;j <= i;j++){
				System.out.print("*");
			}
			System.out.println();
		
		}

		/*
						i(第几行)		j(每一行中*的个数)		i + j = 7 --> j = 7 - i
		******			1				6
		*****			2				5
		****			3				4
		***				4				3
		**				5				2
		*				6				1
		
		*/

		for(int i = 1;i <= 6;i++){

			for(int j = 1;j <= 7 - i;j++){
				System.out.print("*");
			}
			
			System.out.println();
		}

	/*
						i(第几行)	j(每一行中-的个数)		k(每一行中*的个数)    2*i + j = 10 --->j = 10 - 2*i
--------*				1				8				1                k = 2 * i - 1
------* * *				2				6				3
----* * * * *			3				4				5
--* * * * * * *			4				2				7
* * * * * * * * *		5				0				9



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

	//上半部分
	for(int i = 1;i <= 5;i++){
		// -
		for(int j = 1;j <= 10 - 2*i;j++){
			System.out.print("-");
		}


		// *
		for(int k = 1;k <= 2 * i - 1;k++){
			System.out.print("* ");
		}

		System.out.println();
	}

	}
}

案例
/*
练习:九九乘法表

*/
class NineNineTable {
	public static void main(String[] args) {
		
		for(int i = 1;i <= 9;i++){
			
			for(int j = 1;j <= i;j++){
				
				System.out.print(i + "*" + j + "=" + i * j + "\t");
			
			}

			System.out.println();
		
		}

	}
}

1.9 关键字break、continue

  • break在开发中常用;而continue较少使用
  • 笔试题:break和continue的区别。
基本语法
/*
1. break和continue关键字的使用

				使用范围			在循环结构中的作用					相同点
break:			switch-case
				循环结构中			结束(或跳出)当前循环结构			在此关键字的后面不能声明执行语句。

continue:		循环结构中			结束(或跳出)当次循环				在此关键字的后面不能声明执行语句。

		
2. 了解带标签的break和continue的使用

3. 开发中,break的使用频率要远高于continue。
*/
class BreakContinueTest{
	public static void main(String[] args){
		
		for(int i = 1;i <= 10;i++){

			if(i % 4 == 0){
				//break;
				continue;
				
				//编译不通过
				//System.out.println("今晚上迪丽热巴要约我!");
			}
			
			System.out.print(i);
		
		}
		
		System.out.println();

		//*****************************
		label:for(int j = 1;j <= 4;j++){
		
			for(int i = 1;i <= 10;i++){

				if(i % 4 == 0){
					//break;
					//continue;	

					//了解
					//break label;
					//continue label;
				}
				
				System.out.print(i);			
			}
			System.out.println();
		
		}
	
	}
}

1.10 项目1:谷粒记账软件

  • 特点1:代码量更大,逻辑更复杂 —> 推荐大家一定写一写,而且多写几遍。
  • 特点2:内部不包含新的知识点。 —> 不太着急写。

1.11 Scanner类的使用

基本语法


/*
如何从键盘获取不同类型(基本数据类型、String类型)的变量:使用Scanner类。

1. 使用Scanner获取不同类型数据的步骤
步骤1:导包 import java.util.Scanner;
步骤2:提供(或创建)一个Scanner类的实例
步骤3:调用Scanner类中的方法,获取指定类型的变量 (nextXxx())
步骤4:关闭资源,调用Scanner类的close()

2. 案例:小明注册某交友网站,要求录入个人相关信息。如下:

请输入你的网名、你的年龄、你的体重、你是否单身、你的性别等情况。


3. Scanner类中提供了获取byte \ short \ int \ long \float \double \boolean \ String类型变量的方法。
   注意,没有提供获取char类型变量的方法。需要使用next().charAt(0)
*/
//步骤1:导包 import java.util.Scanner;
import java.util.Scanner;
class ScannerTest {
	public static void main(String[] args) {
		
		//步骤2:提供(或创建)一个Scanner类的实例
		Scanner scan = new Scanner(System.in);
		
		System.out.println("欢迎光临你来我往交友网");
		System.out.print("请输入你的网名:");
		//步骤3:调用Scanner类中的方法,获取指定类型的变量
		String name = scan.next();

		System.out.print("请输入你的年龄:");
		int age = scan.nextInt();

		System.out.print("请输入你的体重:");	
		double weight = scan.nextDouble();


		System.out.print("你是否单身(单身:true;不单身:false):");
		boolean isSingle = scan.nextBoolean();

		System.out.print("请输入你的性别(男\\女):"); 
		char gender = scan.next().charAt(0);

		System.out.println("网名:" + name + ",年龄: " + age + ",体重:" + weight + ",是否单身:" + isSingle + 
			",性别:" + gender);

		System.out.println("注册完成,欢迎继续进入体验!");

		//步骤4:关闭资源,调用Scanner类的close()
		scan.close();
	}
}
案例
import java.util.Scanner;
class ScannerExer {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);

		System.out.println("请输入你的身高:(cm)");
		int height = scan.nextInt();

		System.out.println("请输入你的财富:(以千万为单位)");
		double wealth = scan.nextDouble();

		//关于是否帅问题,我们使用String类型接收
		System.out.println("帅否?(是/否)");
		String isHandsome = scan.next();
		
		//判断
		if(height >= 180 && wealth >= 1.0 && isHandsome.equals("是")){  //知识点:判断两个字符串是否相等,使用String的equals()
			System.out.println("我一定要嫁给他!!!");
		}else if(height >= 180 || wealth >= 1.0 || isHandsome.equals("是")){
			System.out.println("嫁吧,比上不足,比下有余。");
		}else{
			System.out.println("不嫁");
		}
		//关闭资源
		scan.close();
	}
}

1.12 获取随机数

/*
如何获取一个随机数?

1. 可以使用Java提供的API:Math类的random() 
2. random()调用以后,会返回一个[0.0,1.0)范围的double型的随机数

3. 需求1:获取一个[0,100]范围的随机整数?
   需求2:获取一个[1,100]范围的随机整数?

4. 需求:获取一个[a,b]范围的随机整数?
   (int)(Math.random() * (b - a + 1)) + a
*/
class RandomTest {
	public static void main(String[] args) {
		
		double d1 = Math.random();

		System.out.println("d1 = " + d1);


		int num1 = (int)(Math.random() * 101);  //[0.0,1.0) --> [0.0,101.0) --->[0,100]
		System.out.println("num1 = " + num1);

		int num2 = (int)(Math.random() * 100) + 1; //[0.0,1.0) --> [0.0,100.0) --->[0,99] ---> [1,100]


	}
}

1.13 体会算法的魅力

  • 基本实现
/*
如何获取一个随机数?

1. 可以使用Java提供的API:Math类的random() 
2. random()调用以后,会返回一个[0.0,1.0)范围的double型的随机数

3. 需求1:获取一个[0,100]范围的随机整数?
   需求2:获取一个[1,100]范围的随机整数?

4. 需求:获取一个[a,b]范围的随机整数?
   (int)(Math.random() * (b - a + 1)) + a
*/
class RandomTest {
	public static void main(String[] args) {
		
		double d1 = Math.random();

		System.out.println("d1 = " + d1);


		int num1 = (int)(Math.random() * 101);  //[0.0,1.0) --> [0.0,101.0) --->[0,100]
		System.out.println("num1 = " + num1);

		int num2 = (int)(Math.random() * 100) + 1; //[0.0,1.0) --> [0.0,100.0) --->[0,99] ---> [1,100]


	}
}

  • 测试性能:方式1
/*
遍历100000以内的所有的质数。体会不同的算法实现,其性能的差别

此PrimeNumberTest1.java是实现方式1
*/
class PrimeNumberTest1 {
	public static void main(String[] args) {

		//获取系统当前的时间:
		long start = System.currentTimeMillis();
		
		boolean isFlag = true;

		int count = 0;//记录质数的个数

		for(int i = 2;i <= 100000;i++){ //遍历100000以内的自然数
			
			
			//判定i是否是质数
			for(int j = 2;j < i;j++){
				
				if(i % j == 0){
					isFlag = false;
				}
			
			}

			if(isFlag){
				count++;
			}
			
			//重置isFlag
			isFlag = true;
		}

		//获取系统当前的时间:
		long end = System.currentTimeMillis();

		System.out.println("质数的总个数为:" + count); //9592
		System.out.println("花费的时间为:" + (end - start)); //7209

	}
}

  • 测试性能:方式2
/*
遍历100000以内的所有的质数。体会不同的算法实现,其性能的差别

此PrimeNumberTest2.java是方式2,针对于PrimeNumberTest1.java中算法的优化
*/
class PrimeNumberTest2 {
	public static void main(String[] args) {

		//获取系统当前的时间:
		long start = System.currentTimeMillis();
		
		boolean isFlag = true;

		int count = 0;//记录质数的个数

		for(int i = 2;i <= 100000;i++){ //遍历100000以内的自然数
			
			
			//判定i是否是质数
			for(int j = 2;j <= Math.sqrt(i);j++){
				
				if(i % j == 0){
					isFlag = false;
					break;//针对于非质数有效果。
				}
			
			}

			if(isFlag){
				count++;
			}
			
			//重置isFlag
			isFlag = true;
		}

		//获取系统当前的时间:
		long end = System.currentTimeMillis();

		System.out.println("质数的总个数为:" + count); //9592
		System.out.println("花费的时间为:" + (end - start)); //7209 -->加上break:659 -->加上Math.sqrt():6

	}
}

二、企业真题

1. break和continue的作用(智*图)

2. if分支语句和switch分支语句的异同之处(智*图)

  • if-else语句优势
    • if语句的条件是一个布尔类型值,if条件表达式为true则进入分支,可以用于范围的判断,也可以用于等值的判断,使用范围更广
    • switch语句的条件是一个常量值(byte,short,int,char,枚举,String),只能判断某个变量或表达式的结果是否等于某个常量值,使用场景较狭窄
  • switch语句优势
    • 当条件是判断某个变量或表达式是否等于某个固定的常量值时,使用if和switch都可以,习惯上使用switch更多。因为效率稍高。当条件是区间范围的判断时,只能使用if语句。
    • 使用switch可以利用穿透性,同时执行多个分支,而if…else没有穿透性。

3. 什么时候用语句if,什么时候选用语句switch(灵伴*来科技)

同上

4. switch语句中忘写break会发生什么(北京*蓝)

case穿透

5. Java支持哪些类型循环(上海*睿)

  • for;while;do-while
  • 增强for (或foreach),放到集合中讲解

6. while和do while循环的区别(国*科技研究院)

  • do-while至少会执行一次。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Story

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值