相关链接
目录
- 搭建maven项目运行,参考pom.xml 用junit测试类执行代码
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
Part3 流程语句【循环结构】、随机数
1 循环结构
1.1 for循环
-
快捷键 fori
-
执行流程:
- A:执行初始化语句
- B:执行判断条件语句,看其结果是true还是false
- 如果是false,循环结束。
- 如果是true,继续执行。
- C:执行循环体语句
- D:执行控制条件语句
- E:回到B继续
-
循环结构 for循环语句格式:
for(初始化语句;判断条件语句;控制条件语句) { 循环体语句; } //实例 for (int x = 1; x <= 5; x++) { System.out.println("HelloWorld"); } for (int i = 0; i < collection.size(); i++) { }
-
执行流程图
-
arraylist可以用for遍历;
-
collection没有索引,不能用for循环;
案例代码一 流程语句-循环结构-for循环练习
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* for循环语句的格式:
* for(初始化语句;判断条件语句;控制条件语句) {
* 循环体语句;
* }
*
* 执行流程:
* A:执行初始化语句
* B:执行判断条件语句,看其结果是true还是false
* 如果是false,就结束循环
* 如果是true,就继续执行
* C:执行循环体语句
* D:执行控制条件语句
* E:回到B继续
*/
public void OperatorDemo01() {
//需求:在控制台输出5次HelloWorld
//原始做法
System.out.println("HelloWorld");
System.out.println("HelloWorld");
System.out.println("HelloWorld");
System.out.println("HelloWorld");
System.out.println("HelloWorld");
System.out.println("----------");
//用for循环改进
for (int x = 1; x <= 5; x++) {
System.out.println("HelloWorld");
}
}
}
案例代码二 流程语句-循环结构-for循环练习 获取数据1-5和5-1
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* 需求:获取数据1-5和5-1
*/
public void OperatorDemo02() {
//从1-5
for (int i = 1; i < 5; i++) {
System.out.println("i:" + i);
}
System.out.println("=========");
//从5-1
for (int i = 5; i > 0; i--) {
System.out.println("i:" + i);
}
}
}
案例代码三 流程语句-循环结构-for循环练习 1-5之间数据和
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* 需求:求出1-5之间数据之和
*
* 分析:
* A:定义一个求和变量,初始化值是0
* B:获取1-5的数据,用for循环就可以实现
* C:把每一次获取到的数据累加到求和变量
* D:输出求和变量
*/
public void OperatorDemo03() {
//定义一个求和变量,初始化值是0
int sum = 0;
//获取1-5的数据,用for循环就可以实现
for (int i = 1; i <= 5; i++) {
sum += i;
/*
* 第一次:sum = sum + x = 0 + 1 = 1
* 第二次:sum = sum + x = 1 + 2 = 3
* 第三次:sum = sum + x = 3 + 3 = 6
* 第四次:sum = sum + x = 6 + 4 = 10
* 第五次:sum = sum + x = 10 + 5 = 15
*/
System.out.println("sum:" + sum);
}
//15
System.out.println("结果为:" + sum);
}
}
案例代码四 流程语句-循环结构-for循环练习 1-100之间的偶数
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* 需求:求出1-100之间偶数和
*
* 分析:
* A:定义求和变量,初始化值是0
* B:获取1-100之间的偶数,用for循环实现
* C:拿到每一个获取的数据进行判断看是否是偶数
* 如果是偶数,就累加。
* D:输出求和变量
*/
public void OperatorDemo04() {
int sum = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
sum += i;
}
}
System.out.println("偶数和为:" + sum);
}
}
案例代码五 流程语句-循环结构-for循环练习 寻找水仙花数
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* 需求:求出1-100之间偶数和
*
* 分析:
* A:定义求和变量,初始化值是0
* B:获取1-100之间的偶数,用for循环实现
* C:拿到每一个获取的数据进行判断看是否是偶数
* 如果是偶数,就累加。
* D:输出求和变量
*/
public void OperatorDemo05() {
int ge, shi, bai;
int tempvalue;
int count = 0;
for (int i = 100; i < 1000; i++) {
//获取每一个三位数的个位,十位,百位
ge = i % 10;
shi = i / 10 % 10;
bai = i / 100 % 10;
tempvalue = ge * ge * ge + shi * shi * shi + bai * bai * bai;
//如果相等,就说明该数是水仙花数,在控制台打印
if (tempvalue == i) {
count++;
/*
第1个水仙花数:153
第2个水仙花数:370
第3个水仙花数:371
第4个水仙花数:407
*/
System.out.println("第" + count + "个水仙花数:" + i);
}
}
}
}
1.2 while循环
-
执行流程:
- A:执行初始化语句
- B:执行判断条件语句,看其结果是true还是false
- 如果是false,循环结束。
- 如果是true,继续执行。
- C:执行循环体语句
- D:执行控制条件语句
- E:回到B继续
-
循环结构 while语句格式:
//基本格式 while(判断条件语句) { 循环体语句; } //扩展格式 初始化语句; while(判断条件语句) { 循环体语句; 控制条件语句; } //实例 while(x<=5) { System.out.println("HelloWorld"); x++; }
-
执行流程图
案例代码六 流程语句-循环结构-while循环
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* while循环的语句格式:
* while(判断条件语句) {
* 循环体语句;
* }
*
* 完整格式:
* 初始化语句;
* while(判断条件语句) {
* 循环体语句;
* 控制条件语句;
* }
*
* 回顾for循环的语句格式:
* for(初始化语句;判断条件语句;控制条件语句) {
* 循环体语句;
* }
*/
public void OperatorDemo6() {
//在控制台输出5次HelloWorld
//for循环实现
/*
for(int x=1; x<=5; x++) {
System.out.println("HelloWorld");
}
System.out.println("--------------");
*/
//while循环实现
int x = 1;
while (x <= 5) {
System.out.println("HelloWorld");
x++;
}
}
}
案例代码七 流程语句-循环结构-while循环练习 1-100求和
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* 需求:求1-100之间的数据和。
*/
public void OperatorDemo7() {
//for循环实现
/*
//定义求和变量
int sum = 0;
for(int x=1; x<=100; x++) {
//累加即可
sum += x;
}
//输出结果
System.out.println("sum:"+sum);
*/
//while循环实现
//定义求和变量
int sum = 0;
int x = 1;
while (x <= 100) {
//累加即可
sum += x;
x++;
}
//输出结果
System.out.println("sum:" + sum);
}
}
1.3 do while循环
-
执行流程:
- A:执行初始化语句
- B:执行循环体语句
- C:执行控制条件语句
- D:执行判断条件语句,看其结果是true还是false
- 如果是false,循环结束。
- 如果是true,继续执行。
- E:回到B继续
-
循环结构 do while语句格式:
//基本格式 do { 循环体语句; }while(判断条件语句); //扩展格式 初始化语句; do { 循环体语句; 控制条件语句; } while(判断条件语句); //实例 do { System.out.println("HelloWorld"); x++; }while(x<=5);
-
执行流程图
案例代码八 流程语句-循环结构-do while
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* do...while循环语句的格式:
* do {
* 循环体语句;
* }while(判断条件语句);
*
* 完整格式:
* 初始化语句;
* do {
* 循环体语句;
* 控制条件语句;
* }while(判断条件语句);
*
* 执行流程:
* A:执行初始化语句
* B:执行循环体语句
* C:执行控制条件语句
* D:执行判断条件语句,看是true还是false
* 如果是false,就结束循环
* 如果是true,就回到B继续
*
* 练习:求和案例,水仙花案例
*/
public void OperatorDemo8() {
//在控制台输出5次HelloWorld案例
/*
for(int x=1; x<=5; x++) {
System.out.println("HelloWorld");
}
*/
int x = 1;
do {
System.out.println("HelloWorld");
x++;
} while (x <= 5);
}
}
1.4 三种循环的区别
- 虽然三种循环结构【for、while、do…while】可以完成同样的功能,但是还是有区别:
- do…while循环会执行至少一次循环体。
- for循环和while循环只有在条件成立时才会去执行循环体
- for循环语句和while循环语句的区别:
- for循环:控制条件语句变量,在for循环结束后,不可再访问。(for循环结束,该变量就从内存中消失,能够提高内存使用效率)
- while循环:控制条件语句变量,在while循环结束后,可以继续访问。
1.5 死循环
- 两种最简单的死循环
- while
int a = 1; while (true) { System.out.println(a++); }
- for
int a = 1; for (; ; ) { System.out.println(a--); }
- 循环中需要注意通过控制条件语句来控制循环变量,否则容易陷入死循环
1.6 foreach 循环 / 增强for循环
- foreach是一种遍历形式, 可以遍历集合或者数组。
- foreach遍历集合实际上是迭代器遍历的简化写法。
增强型for循环定义如下:
for(ElementType element: arrayName){};
上述for循环可被读为:for each element in arrayName do {...}
相对于for(;;)而言 增强for循环有两个好处:
1.写起来简单
2.遍历集合、容器简单
//实例
for (int i : arr) {
System.out.println(i);
}
2 嵌套循环
- 在一个循环体语句中又包含另一个循环语句,称为循环嵌套。
案例代码九 流程语句-循环结构-嵌套循环 4行5列的星星(*)图案
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* 需求:请输出一个4行5列的星星(*)图案。
* 结果:
* *****
* *****
* *****
* *****
*
* 循环嵌套:就是循环体语句本身是一个循环语句。
*
* 结论:
* 外循环控制的是行,内循环控制的是列
*/
public void OperatorDemo9() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 5; j++) {
//* * * * *
System.out.print("* ");
}
//换行
System.out.println();
}
/*
* * * * *
* * * * *
* * * * *
* * * * *
*/
}
}
案例代码十 流程语句-循环结构-嵌套循环 正三角形
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* 需求:请输出如下图形
* *
* **
* ***
* ****
* *****
*/
public void OperatorDemo10() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < i; j++) {
//每次内循环打印i个*
System.out.print("* ");
}
//换行
System.out.println();
}
/*
*
* *
* * *
* * * *
* * * * *
*/
}
}
案例代码十一 流程语句-循环结构-嵌套循环 九九乘法表
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* 需求:在控制台打印九九乘法表
*
* \t:转移字符,表示一个tab键的位置
*/
public void OperatorDemo11() {
for (int i = 0; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i + "*" + j + "=" + i * j + "\t");
}
//换行
System.out.println();
}
/*
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
*/
}
}
3 控制循环语句
3.1 跳转控制语句break
- break使用场景
- 在选择结构switch语句中
//实例 switch (weekDay) { case 1: System.out.println("星期一"); break; case 2: System.out.println("星期二"); break; default: System.out.println("其他"); break; } //case穿透写法 switch (weekDay) { case 1: case 2: case 3: case 4: case 5: System.out.println("工作日"); break; case 6: case 7: System.out.println("休息日"); break; default: System.out.println("日期错误"); break; }
- 在循环语句中
//实例 乘法表 1-9 不要5 for (int i = 0; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(i + "*" + j + "=" + i * j + "\t"); } if (i==5){ break; } //换行 System.out.println(); } /* 1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 */
- 离开使用场景的存在是没有意义的
- break的作用:
- 跳出单层循环
- 跳出多层循环(带标签的跳出)
wc: for (int i = 1; i <= 3; i++) { nc: for (int j = 1; j <= 3; j++) { if (j == 3) { break wc; } System.out.print("*"); } System.out.println(); }
- 格式:
- 标签名:循环语句
- 标签名要符合Java的命名规范
案例代码十二 流程语句-循环结构-跳转控制语句break
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* break:中断的意思
*
* 使用场景:
* A:switch语句中,用于结束switch语句
* B:循环语句中,用于结束循环
* 如何使用:
* A:跳出单层循环
* B:跳出多层循环
* 用带标签的语句格式。
*/
public void OperatorDemo12() {
//break可以用于结束当前的循环。
for (int x = 1; x <= 5; x++) {
if (x == 3) {
break;
}
System.out.println("HelloWorld");
}
/*
HelloWorld
HelloWorld
*/
System.out.println("-----------------------");
//如果是多层循环,break到底结束的是哪个循环呢?
//break结束的是离他最近的那个循环
//如果我要跳出外层循环,可不可以呢?
//可以。如何实现呢?
//带标签的语句:
//格式:标签名:语句
wc:
for (int i = 1; i <= 3; i++) {
nc:
for (int j = 1; j <= 3; j++) {
if (j == 3) {
break wc;
}
System.out.print("*");
}
System.out.println();
}
/*
**
*/
}
}
3.2 跳转控制语句continue
- continue的作用:
- 单层循环对比break,然后总结两个的区别
- break 退出当前循环
- continue 退出本次循环
- 单层循环对比break,然后总结两个的区别
案例代码十三 流程语句-循环结构-跳转控制语句continue
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* continue:继续的意思
*
* 使用场景:
* 循环中。离开使用场景是没有意义的。
*
* break和continue的区别:
* break:跳出整个循环
* continue:跳出这一次的操作,进入下一次的执行
*/
public void OperatorDemo13() {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
/*
HelloWorld1
HelloWorld2
HelloWorld4
HelloWorld5
*/
System.out.println("HelloWorld" + i);
}
}
}
4 Random随机数
4.1 java.lang.Math.Random
- 作用:返回带正号的double值,返回值是一个伪随机选择的数,在该范围内(近似)均匀分布。
- 范围:[0.0,1.0)的左闭右开区间
- 原理:Math.Random内部是调用的Java.util.Random无参构造器实现的
案例代码十四 java.lang.Math.Random
package com.itheima;
import org.junit.Test;
public class day03 {
@Test
/**
* Random:java.lang.Math.Random;
* 不需要导包
*/
public void OperatorDemo14() {
for (int i = 0; i < 5; i++) {
/*
0.6786675846878583
0.36699904452209553
0.9194537891343871
0.7271913829671783
0.4315928699154187
*/
System.out.println(Math.random());
}
}
}
4.2 java.util.Random
-
作用:生成伪随机数
使用的是48-bit的种子,然后调用一个linear congruential formula线性同余 (和P1、7.6 数学证明 【反码、补码、同余、取模】是同一概念) 方程(Donald Knuth的编程艺术的3.2.1节)。如果两个Random实例使用相同的种子,并且调用同样的函数,那么生成的sequence是相同的- 无参构造Random():创建一个新的随机数生成器。
- 无参构造器内部也是调用的有参构造器,只是种子是通过系统当前时间计算出来的一个long型数据,所以多次运行结果都不一样
- 有参构造Random(long seed):使用单个 long 种子创建一个新的随机数生成器。
- 有参构造在指定种子(seed)值不变的情况下,返回随机数的序列是固定的。
- 无参构造Random():创建一个新的随机数生成器。
-
方法摘要
生成下一个伪随机数。 protected int next(int bits) 返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的boolean值。 boolean nextBoolean() 生成随机字节并将其置于用户提供的 byte 数组中。 void nextBytes(byte[] bytes) 返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布的 double值。 double nextDouble() 返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布float值。 float nextFloat() 返回下一个伪随机数,它是取自此随机数生成器序列的、呈高斯(“正态”)分布的double值,其平均值是0.0标准差是1.0。 double nextGaussian() 返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。 int nextInt() 返回一个伪随机数,它是取自此随机数生成器序列的、在(包括和指定值(不包括)之间均匀分布的int值。 int nextInt(int n) 返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 long 值。 long nextLong() 使用单个 long 种子设置此随机数生成器的种子。 void setSeed(long seed)
-
范围
- double d1 = r.nextDouble();
- => 生成[0,1.0)区间的小数
- double d2 = r.nextDouble() * 5;
- => 生成[0,5.0)区间的小数
- double d3 = r.nextDouble() * 1.5 + 1;
- => 生成[1,2.5)区间的小数
- int n = r.nextInt();
- => 生成[-231,231-1)之间的整数
- 生成[0,10)区间的整数
- int n2 = r.nextInt(10);
- n2 = Math.abs(r.nextInt() % 10); //对10取余后,Math.abs取绝对值
- double d1 = r.nextDouble();
案例代码十五 java.util.Random
package com.itheima;
import org.junit.Test;
import java.util.Random;
public class day03 {
@Test
/**
* Random:用于产生随机数的类。用法和Scanner类似。
*
* 使用步骤:
* A:导包
* import java.util.Random;
* B:创建对象
* Random r = new Random();
* C:获取随机数(有参构造)
* int number = r.nextInt(10);
* 获取的范围:[0,10) 包括0,不包括10
*/
public void OperatorDemo15() {
//创建对象
Random r = new Random();
for (int x = 1; x <= 10; x++) {
//获取随机数
int number = r.nextInt();
/*
number:167800495
number:-1793232755
number:1616292626
number:2039967788
number:-204215836
number:2083858793
number:-1415376024
number:-1291646196
number:1152449652
number:733253850
*/
System.out.println("number:" + number);
}
System.out.println("--------------");
for (int x = 1; x <= 10; x++) {
//获取随机数
int number1 = r.nextInt(10);
/*
number1:7
number1:6
number1:7
number1:8
number1:7
number1:8
number1:4
number1:6
number1:5
number1:3
*/
System.out.println("number1:" + number1);
}
System.out.println("--------------");
//如何获取一个1-100之间的随机数呢?
int i = r.nextInt(100) + 1;
/*
76
*/
System.out.println(i);
}
}
案例代码十六 java.util.Random原理
package com.itheima;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Random;
public class day03 {
@Test
public void OperatorDemo16() {
// 案例1
System.out.println("=========案例1=========");
// 对于种子相同的Random对象,生成的随机数序列是一样的。
Random ran1 = new Random(10);
System.out.println("【使用种子为10的Random对象生成[0,10)内随机整数序列:】 ");
for (int i = 0; i < 10; i++) {
System.out.print(ran1.nextInt(10) + " ");
}
System.out.println();
Random ran2 = new Random(10);
System.out.println("【使用另一个种子为10的Random对象生成[0,10)内随机整数序列: 】");
for (int i = 0; i < 10; i++) {
System.out.print(ran2.nextInt(10) + " ");
}
// 输出结果为:
//
//=========案例1=========
// 【使用种子为10的Random对象生成[0,10)内随机整数序列:】
// 3 0 3 0 6 6 7 8 1 4
// 【使用另一个种子为10的Random对象生成[0,10)内随机整数序列: 】
// 3 0 3 0 6 6 7 8 1 4
// 案例2
System.out.println();
System.out.println();
System.out.println("=========案例2=========");
// 在没带参数构造函数生成的Random对象的种子缺省是当前系统时间的毫秒数。
Random r3 = new Random();
System.out.println("【使用种子缺省是当前系统时间的毫秒数的Random对象生成[0,10)内随机整数序列】");
for (int i = 0; i < 10; i++) {
System.out.print(r3.nextInt(10) + " ");
}
// 输出结果为:
//
// =========案例2=========
// 【使用种子缺省是当前系统时间的毫秒数的Random对象生成[0,10)内随机整数序列】
// 3 7 2 0 6 0 8 9 5 9
System.out.println();
System.out.println();
System.out.println("=========案例3=========");
// 另外,直接使用Random无法避免生成重复的数字,如果需要生成不重复的随机数序列,需要借助数组和集合类
ArrayList list = new day03().getDiffNO(15);
System.out.println("产生的n个不同的随机数:" + list);
//=========案例3=========
//产生的n个不同的随机数:[13, 12, 8, 7, 11, 9, 0, 2, 4, 3, 10, 1, 14, 6, 5]
}
/**
* 方法:生成n个不同的随机数,且随机数区间为[0,10)
* @param n
* @return
*/
public ArrayList getDiffNO(int n) {
// 生成 [0-n) 个不重复的随机数
// list 用来保存这些随机数
ArrayList list = new ArrayList();
Random rand = new Random();
boolean[] bool = new boolean[n];
int num = 0;
for (int i = 0; i < n; i++) {
do {
// 如果产生的数相同继续循环
num = rand.nextInt(n);
} while (bool[num]);
bool[num] = true;
list.add(num);
}
return list;
}
}
4.3 随机数原理
解密随机数生成器(1)——真随机数生成器
解密随机数生成器(2)——从java源码看线性同余算法
21/01/27
M