Java架构师成长之道之Java程序流程控制
Java架构师成长之道
4.1 程序流程控制概述
之前编写的绝大多数程序都是顺序执行,也就是从main函数开始,由上到下一行一行的执行,也被称为顺序结构。
在生活中除了顺序结构以外还有选择结构、循环结构,例如在淘宝购物时登录账号就是一个选择结构,如果输入的正确的用户名和密码才能购买商品,否则就会提示用户名密码错误。
而在淘宝首页的Banner就是一个循环结构,在指定的时间内循环切换图片。
在Java中,支持if/else和switch case两种选择结构,同时支持while,do...while,for循环以及JDK1.5以后支持foreach循环,同时还支持带标签的循环结构以及通过使用break,continue来中断循环。
4.2 使用Scanner类实现程序交互
平常在使用PC浏览电商网站时,如果想要购买商品通常需要输入用户名和密码来登录系统。
而登录的目的正是验证账号的合法性,在Java中可以使用Scanner类来模拟用户的输入数据,
可以读取的数据类型是boolean,byte,short,int,long,String,double等等,可以通过IDEA的Structure视图查看Scanner类的源码支持读取的类型。
在Java程序中如果想要使用一个类,必须使用import关键字加上类的包名+类名+分号实现
import java.util.Scanner;
Java默认为所有的源文件导入java.lang包下的类,因此在之前编写的Java程序中使用的String,System等类无需使用import导入。
Java开发中常用的包还有util,io,nio,text,time等等。同学们有时间可以多去看看这些包下的源码实现,提升自己的编程功底。
在导入之后便可以通过new关键字创建Scanner对象来模拟键盘,
同时在Scanner构造器中传入System.in作为数据的来源,表示来源于控制台
Scanner input =new Scanner(System.in);
使用Scanner读取用户信息并输出到控制台
package net.ittimeline.java.core.control;
import java.util.Scanner;
/**
* 读取用户输入数据实现程序交互
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 17:49
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ScannerTest {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入你的年龄");
int age=input.nextInt();
System.out.println("请输入你的身高");
double height=input.nextDouble();
System.out.println("请输入你的姓名");
String name=input.next();
System.out.println("你是男生么?");
boolean genderFlag=input.nextBoolean()?Boolean.TRUE:Boolean.FALSE;
if(genderFlag){
System.out.printf("你的年龄是%d,你的姓名是%s,你的性别是男生,你的身高是%.2f",age,name,height);
}
else{
System.out.printf("你的年龄是%d,你的姓名是%s,你的性别是女生,你的身高是%.2f",age,name,height);
}
}
}
交互效果
关于Scanner类的更多介绍以及使用方式,可以查阅JDK的API文档
4.3 自定义PrintUtils类
PrintUtils类位于java-core-util模块中,使用Maven管理项目,关于Maven和IntelliJ IDEA的使用后面会详细介绍
工程模块总览以及PrintUtils概览
该类主要是对于System类的PrintStream对象封装,结合JDK1.5的静态导入特性,可以实现更加"简洁的数据输出",方便程序调试。
如果想要在其他模块引用该类,只需要在其他模块的pom.xml文件中添加该类所有在模块的坐标即可
<dependency>
<groupId>net.ittimeline.java</groupId>
<artifactId>java-core-util</artifactId>
<version>${project.version}</version>
</dependency>
package net.ittimeline.java.core.util.lang;
/**
* 控制台打印输出工具类
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 11:53
* @website www.ittimeline.net
* @since JDK11.03
*/
public class PrintUtils {
/**
* 打印输出对象的内容并换行
* @param object
*/
public static void println(Object object){
System.out.println(object);
}
/**
* 打印输出对象们的内容并换行
* @param objects
*/
public static void println(Object...objects){
for (Object object:objects){
println(object);
}
}
/**
* 打印分割
*/
public static void println(){
System.out.println();
System.out.println("*********************楚河汉界*********************");
}
/**
* 打印输出对象的内容不换行
* @param object
*/
public static void print(Object object){
System.out.print(object);
}
/**
* 按照指定的格式打印输出内容
* @param format
* @param args
*/
public static void printf(String format,Object...args){
System.out.printf(format,args);
}
}
4.4 选择结构if/else
if/else用于布尔类型的变量或者表达式作为条件判断来进行程序流程控制,if/else语句有如下三种形式
if语句,也被称为单分支选择结构
单分支选择
if(true){
//执行代码块的内容
}
使用Math.random()方法随机生成1-6的整数,然后判断大小
package net.ittimeline.java.core.control;
import static java.lang.System.out;
/**
* if单选择结构
*
* if(true){
*
* }
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 10:27
* @website www.ittimeline.net
* @since JDK11.03
*/
public class Lottery {
public static void main(String[] args) {
//返回一个0.0-1.0(不包含1.0)之间的小数
double dbl=Math.random();
out.println("dbl ="+dbl);
//产生1-6之间的随机数
int number=(int)(dbl*6)+1;
out.println("number = "+number);
int target=3;
if(number<=target){
out.println("小");
}
}
}
使用Math.random()随机生成1-6的3个整数,判断手气
package net.ittimeline.java.core.control;
import static java.lang.System.out;
/**
* 单if选择结构
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 10:33
* @website www.ittimeline.net
* @since JDK11.03
*/
public class Lottery2 {
public static void main(String[] args) {
double dbl=Math.random();
int i,j,k;
//创建三个1-6之间的随机整数数
i = (int)(dbl*6)+1;
j = (int)(dbl*6)+1;
k = (int)(dbl*6)+1;
out.println("i = "+i +" j = "+j +" k = "+k );
//求三个随机数的和
int point=i+j+k;
out.println("point = "+point);
//根据随机数的和判断输出的内容
if(point>15){
out.println("今天手气很不错");
}
//只要满足if的bool表达式,就会执行代码块{}中的内容
if(point>=10&&point<=15){
out.println("今天手气一般");
}
if(point<10){
out.println("今天手气不好");
}
}
}
if/else语句(二选一),也别称为双分支选择结构
双分支选择结构
if(true){
//执行代码块的内容
}
else{
//执行代码块的内容
}
使用Math.random()产生1-6之间的随机整数,判断大小
package net.ittimeline.java.core.control;
import static java.lang.System.out;
/**
* if/else择结构
*
* if(true){
*
* }
* else{
*
* }
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 10:27
* @website www.ittimeline.net
* @since JDK11.03
*/
public class Lottery3 {
public static void main(String[] args) {
//返回一个0.0-1.0(不包含1.0)之间的小数
double dbl=Math.random();
out.println("dbl ="+dbl);
//产生1-6之间的随机数
int number=(int)(dbl*6)+1;
out.println("number = "+number);
int target=3;
if(number<=target){
out.println("小");
}
else{
out.println("大");
}
}
}
判断用户输入的年份是否是闰年
package net.ittimeline.java.core.control.ifstatement;
import java.util.Scanner;
/**
* 判断用户输入的年份是不是闰年
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 17:58
* @website www.ittimeline.net
* @since JDK11.03
*/
public class LeapYearCheck {
public static void main(String[] args) {
//创建虚拟键盘
Scanner input =new Scanner(System.in);
System.out.println("请输入年份");
int year=input.nextInt();
/**
* 闰年判断的公式
* 年份能被4整除不能被100整除 或者 年份不能被400整除
*
* 2016 2020 都是闰年
*/
boolean flag=(year%4==0&&year%100!=0)||year%400==0;
if(flag){
System.out.printf("你输入的年份%d是闰年",year);
}
else{
System.out.printf("你输入的年份%d不是闰年",year);
}
}
}
使用if/else模拟淘宝登录
package net.ittimeline.java.core.control.ifstatement;
import java.util.Scanner;
/**
* 模拟淘宝登录
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 18:09
* @website www.ittimeline.net
* @since JDK11.03
*/
public class TaobaoLogin {
public static void main(String[] args) {
Scanner input =new Scanner(System.in);
System.out.println("请输入你的用户名");
String name =input.next();
System.out.println("请输入你的密码");
String password=input.next();
String targetName="tony";
String targetPassword="123456";
if(targetName.equals(name)&&targetPassword.equals(password)){
System.out.println("欢迎登录淘宝");
}
else{
System.out.println("用户名或者密码输入错误,请检查");
}
}
}
用户名或者密码输入正确的运行结果
if/else if /else(多选一)
if(true){
//执行代码块的内容
}
else if(true){
//执行代码块的内容
}
else if(true){
//执行代码块的内容
}
else{
//执行代码块的内容
}
根据随机生成的年龄判断是青少年、中年、还是老年人
package net.ittimeline.java.core.control;
import java.util.Random;
/**
* 年龄判断
* if(){
*
* }
* else if(){
*
* }
* else{
*
* }
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 12:27
* @website www.ittimeline.net
* @since JDK11.03
*/
public class Age {
public static void main(String[] args) {
Random random=new Random();
int age=random.nextInt(110)+1;
System.out.println("age = "+age);
if(age<=6){
System.out.println("你是儿童");
}
else if(age>=7&&age<=14){
System.out.println("你是少年");
}
else if(age>=15&&age<=35){
System.out.println("你是青年人");
}
else if(age>=36&&age<=60){
System.out.println("你是中年人");
}
else if(age>60){
System.out.println("你是老年人");
}
else{
System.out.println("无法识别你的年龄");
}
}
}
比较两个数的大小,如果大于返回1,小于返回-1,等于返回0
package net.ittimeline.java.core.control;
import static java.lang.System.out;
/**
* if(){
*
* }
* else if(){
*
* }
* else{
*
* }
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 11:43
* @website www.ittimeline.net
* @since JDK11.03
*/
public class IfElseIfElse {
/**
* 多选一
* 用于比较两个数的大小
* if/else if /else
* @param testval
* @param target
* @return
*/
static int test(int testval,int target){
if(testval>target){
return +1;
}
else if(testval<target){
return -1;
}
else{
return 0;
}
}
public static void main(String[] args) {
out.println(test(10,5));
out.println(test(5,10));
out.println(test(5,5));
}
}
使用if/else if/else模拟相亲现场
package net.ittimeline.java.core.control.ifstatement;
import java.util.Scanner;
/**
* 相亲现场
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 22:55
* @website www.ittimeline.net
* @since JDK11.03
*/
public class Marry {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入你的身高:(cm)");
int height = input.nextInt();
System.out.println("请输入你的财富:(千万)");
double wealth = input.nextDouble();
System.out.println("请输入你是否帅:(true/false)");
boolean isHandsome = input.nextBoolean();
//三个条件全满足
if (height >= 180 && wealth >= 1 && isHandsome) {
System.out.println("我一定要嫁给他!!");
}
//三个满足一个
else if (height > 180 || wealth >= 1 || isHandsome) {
System.out.println("嫁吧,比上不足比下有余");
}
//一个都不满足
else {
System.out.println("不嫁");
}
}
}
在进行复杂业务开发时,还会使用到嵌套的if/else
if(true){
if(true){
//执行代码块
}
else{
//执行代码块
}
}
else{
//执行代码块
}
使用嵌套if和三元运算符求出三个整数的最大值
package net.ittimeline.java.core.operator.ternary;
/**
* 求三个数中的最大值
* 分别使用if/else if和三元运算符
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 16:58
* @website www.ittimeline.net
* @since JDK11.03
*/
public class GetMaxNumber {
public static void main(String[] args) {
int i=277;
int j=20;
int k=-99;
int max=0;
if(i>j){
if(i>k){
max=i;
}
else{
max=k;
}
}
System.out.println("使用if/else if实现求三个整数的最大值 max = "+max);
max= i>j&&i>k?i:k;
System.out.println("三个数中的最大值是"+max);
}
}
使用死循环while和if/else实现将用户输入的三个整数排序
这里为什么要用死循环while呢?是为了方便测试各种数据排序场景
package net.ittimeline.java.core.control.ifstatement;
import java.util.Scanner;
/**
* 使用If/else给用户输入的整数排序 按照从大到小
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 13:11
* @website www.ittimeline.net
* @since JDK11.03
*/
public class IfElseSort {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("请输入第一个整数");
int first = input.nextInt();
System.out.println("请输入第二个整数");
int second = input.nextInt();
System.out.println("请输入第三个整数");
int third = input.nextInt();
//第一个数最小
if (first < second && first < third) {
if (second < third) {
System.out.println(first + " < " + second + " < " + third);
} else if (second > third) {
System.out.println(first + " < " + third + " < " + second);
}
}
//第二数最小
else if (second < first && second < third) {
if (first > third) {
System.out.println(second + " < " + third + " < " + first);
} else if (first < third) {
System.out.println(second + " < " + first + " < " + third);
}
}
//第三个数最小
else if (third < first && third < second) {
if (first > second) {
System.out.println(third + " < " +second + " < " + first);
} else if (first < second) {
System.out.println(third + " < " + first + " < " + second);
}
}
}
}
}
4.5 选择结构switch/case
switch语句由一个表达式和多个case语句以及default语句组成,switch语句中表达式的数据类型只能是byte,short,char和int以及枚举(enum)类型,不能是boolean类型,否则会编译出错,同时在JDK7以后switch语句支持String类型。case之后只能声明常量值,不能声明范围,break关键字表示跳出switch语句,根据实际业务场景是可选的。而default语句类似于if/else的else语句,也是可选的,位置也是灵活的,但是通常放到最后一个case语句下面。
switch语句的执行流程
首先计算switch表达式的值,然后拿switch表达式的值和case语句的常量值和进行相等性判断,如果相等则会执行对应的case语句中的代码块,直到执行case语句中的break后跳出switch语句。
如果每个case语句的值和switch语句表达式的值不相等,则会执行default语句的代码块,直到遇到break结束switch语句。
switch(expression){
case constant value :
//代码块
break;
case constant value :
//代码块
break;
case constant value :
//代码块
break;
default :
//代码块
break;
}
使用switch/case实现等值判断
package net.ittimeline.java.core.control.switchstatement;
/**
* switch case使用
* @author liuguanglei 18601767221@163.com
* @create 2019-08-05 10:58
* @website www.ittimeline.net
* @since JDK11.03
*/
public class SwitchTest {
public static void main(String[] args) {
//变量或者表达式的值只能是byte,short,char,int,enum,String
int number=0;
switch (number){
case 1:
System.out.println("number =1");
//每一个case都需要break,break表示跳出switch语句
break;
case 2:
System.out.println("number =2");
break;
case 3:
System.out.println("number =3");
break;
case 4:
System.out.println("number =4");
break;
//如果所有的case都不匹配,则会进入default
default:
System.out.printf("number =%d",number);
}
}
}
虽然Java没有强制规定每个case语句必须加上break,而C#(微软推出的一门编程语言)是规定case语句必须加上break。程序在执行时可能会得到错误的结果。
package net.ittimeline.java.core.control.switchstatement;
/**
* switch not with case
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 13:12
* @website www.ittimeline.net
* @since JDK11.03
*/
public class SwitchDemo2 {
public static void main(String[] args) {
for (int i = 0; i <7 ; i++) {
switch (i){
case 1:
System.out.println("case 1");
case 2:
System.out.println("case 2");
case 3:
System.out.println("case 3");
case 4:
System.out.println("case 4");
case 5:
System.out.println("case 5");
default:
System.out.println("default");
}
}
}
}
程序运行结果
default
case 1
case 2
case 3
case 4
case 5
default
case 2
case 3
case 4
case 5
default
case 3
case 4
case 5
default
case 4
case 5
default
case 5
default
default
如果想要获取正确的运行结果,需要在case语句加上break,当执行到break时表示退出switch语句
package net.ittimeline.java.core.control.switchstatement;
/**
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 13:10
* @website www.ittimeline.net
* @since JDK11.03
*/
public class SwitchDemo {
public static void main(String[] args) {
for (int i = 0; i < 7; i++) {
switch (i) {
case 1:
System.out.println("case 1");
break;
case 2:
System.out.println("case 2");
break;
case 3:
System.out.println("case 3");
break;
case 4:
System.out.println("case 4");
break;
case 5:
System.out.println("case 5");
break;
default:
System.out.println("default");
break;
}
}
}
}
为什么Java不强制开发人员在使用switch/case时不强制加上break呢,因为有些场景虽然是不同的case值,但是执行的业务逻辑是一样的。
根据月份判断季节
package net.ittimeline.java.core.control.switchstatement;
import java.util.Scanner;
/**
* 根据用户输入的月份判断季节
*
* 1,2,12是冬季
* 3,4,5是春季
* 6,7,8是夏季
* 9,10,11是秋季
* 12,1,2是冬季
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 18:23
* @website www.ittimeline.net
* @since JDK11.03
*/
public class JudegMonth {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入月份");
int month = input.nextInt();
switch (month) {
case 1:
case 2:
case 12:
System.out.printf("当前月份%d是冬季",month);
break;
case 3:
case 4:
case 5:
System.out.printf("当前月份%d是春天",month);
break;
case 6:
case 7:
case 8:
System.out.printf("当前月份%d是夏季",month);
break;
case 9:
case 10:
case 11:
System.out.printf("当前月份%d是秋季",month);
break;
}
}
}
根据用户输入的年月日判断是当年的第几天
package net.ittimeline.java.core.control.switchstatement;
import java.util.Scanner;
/**
* 利用switch不带break的特性
* 根据用户输入的年月日判断是当年的第几天
* 如果switch case 不加break,程序会执行匹配到的case直到遇到break或者switch执行结束
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 09:41
* @website www.ittimeline.net
* @since JDK11.03
*/
public class GetDaysByMonthDay {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入年份");
int year = input.nextInt();
//统计总天数
int sumDays = 0;
//判断用户输入的年份是否是闰年
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
//如果是闰年 一年有366天
System.out.printf("%d年是闰年\n", year);
sumDays += 1;
}
System.out.println("请输入月份");
int month = input.nextInt();
System.out.println("请输入日(几号)");
int day = input.nextInt();
switch (month) {
case 12:
sumDays += 31;
case 11:
sumDays += 30;
case 10:
sumDays += 31;
case 9:
sumDays += 30;
case 8:
sumDays += 31;
case 7:
sumDays += 31;
case 6:
sumDays += 30;
case 5:
sumDays += 31;
case 4:
sumDays += 30;
case 3:
sumDays += 31;
case 2:
sumDays += 28;
case 1:
sumDays += day;
}
System.out.println("2019年" + month + "月" + day + "日是当年的第" + sumDays + "天");
}
}
判断字符是元音还是辅音
package net.ittimeline.java.core.control.switchstatement;
import java.util.Random;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* 判断字符是元音还是辅音
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 12:42
* @website www.ittimeline.net
* @since JDK11.03
*/
public class VowelsAndConsonants {
public static void main(String[] args) {
Random random=new Random(88);
for (int i=0;i<100;i++){
//产生97-122之间的随机数
int c=random.nextInt(26)+'a';
//打印 字符对应的数字以及是元音还是辅音
print((char)c+", "+c);
switch (c){
//元音
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
print(",vowel");
break;
case 'y':
case 'w':
//有时候是元音
print(",Sometimes a vowel");
break;
//默认是辅音
default:
print(",consonant");
}
println();
}
}
}
在JDK7以前,switch/case语句的条件表达式的类型只能支持byte,short,int,char和enum,而String是日常开发中最常用的数据类型,在JDK7后switch/case终于支持String。
package net.ittimeline.java.core.control.switchstatement;
import java.util.Scanner;
/**
* JDK7新特性-switch支持String类型
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 18:32
* @website www.ittimeline.net
* @since JDK11.03
*/
public class SwitchString {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String description;
System.out.println("请输入你的性别");
String gender = input.next();
/**
* 根据输入的性别生成招呼用语
*/
switch (gender) {
case "男":
description = "你好,先生";
break;
case "女":
description = "你好,女士";
break;
default:
description="你好";
break;
}
System.out.println(description);
}
}
但是由于switch/case语句的case 值是不能重复的,在使用String时尤其要注意。因为在Java中字符串可以使用Unicode字符来替换,也可能造成case值重复。
package net.ittimeline.java.core.control.switchstatement;
import java.util.Scanner;
/**
* JDK7新特性-switch支持String类型
* case 值 重复
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-04 18:32
* @website www.ittimeline.net
* @since JDK11.03
*/
public class SwitchString2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String description;
System.out.println("请输入你的性别");
String gender = input.next();
/**
* 根据输入的性别生成招呼用语
*/
switch (gender) {
case "男":
//字符串男对应的unicode编码就是\u7537
// case "\u7537":
description = "你好,先生";
break;
case "女":
description = "你好,女士";
break;
default:
description="你好";
break;
}
System.out.println(description);
}
}
使用switch/case实现基于字符和字符串的小写字母转大写字母
package net.ittimeline.java.core.control.switchstatement;
import java.util.Scanner;
/**
* 使用switch/case分别基于字符串和字符实现将小写字母转换为大写字母
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-05 15:34
* @website www.ittimeline.net
* @since JDK11.03
*/
public class SwitchLowerCaseUpperCase {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入需要转换的小写字母:");
String lowercase = input.next();
String uppercase = "";
switch (lowercase) {
case "a":
case "b":
case "c":
case "d":
case "e":
case "f":
case "g":
case "h":
case "i":
case "j":
case "k":
case "l":
case "m":
case "n":
case "o":
case "p":
case "q":
case "r":
case "s":
case "t":
case "u":
case "v":
case "w":
case "x":
case "y":
case "z":
//直接使用String类封装的toUpperCase方法实现小写字母转大写字母
uppercase = lowercase.toUpperCase();
break;
}
//输出转换结果 这里的%s表示字符串
System.out.printf("基于字符串小写字母%s转换为大写字母的结果是%s\n", lowercase, uppercase);
//获取输入字符串中的第一个字符
Character ch = lowercase.charAt(0);
switch (ch) {
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
//小写字母的编码减去32就是大写字母的编码
int upperCaseNumber = (int) ch - 0x20;
//将数字转换为对应的字符
Character uppperCase = Character.valueOf((char) upperCaseNumber);
//输出转换结果,这里的%c表示字符
System.out.printf("基于字符 小写字母%c转换为大写字母的结果是%c\n", ch, uppperCase);
break;
}
}
}
switch/case和if/else语句的比较
- 凡是可以使用switch/case的结构,都可以使用if/else转换。反之不成立
- 选择结构中,即可以使用switch/case,又可以使用if/else时,优先使用switch case,因为switch/case执行效率稍高
- switch case适合做等值判断,if/else适合做区间判断。
package net.ittimeline.java.core.control.switchstatement;
import java.util.Scanner;
/**
* 根据用户输入的分数判断等级
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 10:46
* @website www.ittimeline.net
* @since JDK11.03
*/
public class GetGradeByScore {
public static void main(String[] args) {
Scanner input= new Scanner(System.in);
System.out.println("请输入你的分数");
int score=input.nextInt();
String ifElseGrade=getGradeByScoreIfElse(score);
System.out.printf("if else结构实现 分数%d对应的等级是%s\n",score,ifElseGrade);
String switchCaseGrade=getGradeByScoreSwitchCase(score);
System.out.printf("switch case结构实现 分数%d对应的等级是%s\n",score,switchCaseGrade);
}
/**
* 使用if/else实现根据用户输入的分数获取等级
* @param score
* @return
*/
public static String getGradeByScoreIfElse(int score){
String grade="";
if(score>90){
grade="A";
}
else if(score>=70&&score<80){
grade="B";
}
else if(score>=60&&score<70){
grade="C";
}
else if((score<60)){
grade="D";
}
return grade;
}
/**
* 使用if/else实现根据用户输入的分数获取等级
* @param score
* @return
*/
public static String getGradeByScoreSwitchCase(int score){
String grade="";
int value=score/10;
switch (value){
case 9:
grade="A";
break;
case 8:
case 7:
grade="B";
break;
case 6:
grade="C";
break;
case 5:
case 4:
case 3:
case 2:
case 1:
grade="D";
break;
}
return grade;
}
}
4.6 循环结构while和do/while
每个循环结构都有如下四个要素
1.初始化条件
2.循环条件 必须是boolean类型
3.循环体
4.迭代条件
而循环结构的执行流程是
循环的执行顺序
1.初始化条件
2.循环条件
3.循环体
4.迭代条件
2.循环条件
3.循环体
4.迭代条件
2.循环条件
3.循环体
4.迭代条件
...
while循环的结构是
while(boolean_expression){
statement;
[iterator_statement]
}
while循环的流程图
当boolean_expression为true时,就会循环执行代码块中的内容,直到遇到boolean_expression为false则会退出while循环。
package net.ittimeline.java.core.control.whilestatement;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* 使用while循环判断随机数是否小于0.99
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 12:46
* @website www.ittimeline.net
* @since JDK11.03
*/
public class WhileTest {
/**
* 定义condition方法作为while循环的条件
* @return Math.random()是否小于0.99
*/
static boolean condition(){
boolean result=Math.random()<0.99;
println("result = "+result);
return result;
}
public static void main(String[] args) {
while (condition()){
println("Inside 'while'");
}
println("Exited 'while'");
}
}
使用while循环计算1-100以内的偶数和,借助该程序理解循环的四要素
在写while循环时特别容易忘记写迭代条件,如果while循环没有迭代条件,则会变成死循环,
在程序开发中应该尽量避免出现死循环。
package net.ittimeline.java.core.control.whilestatement;
/**
* 计算1-100以内的偶数
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 17:28
* @website www.ittimeline.net
* @since JDK11.03
*/
public class While100EvenNumber {
public static void main(String[] args) {
/**
* 循环四要素
*
* 1.初始化条件
* 2.循环条件 必须是boolean类型
* 3.循环体
* 4.迭代条件
*/
//1.循环的初始条件
int sum=0;
int i=1;
//2.循环条件
while (i<=100){
//3.循环体
if(i%2==0){
sum+=i;
}
//4.循环的迭代条件
i++;
}
System.out.println("1-100以内的偶数和是"+sum);
}
}
while循环和for循环可以相互替换,使用for循环实现1-100以内的偶数和
package net.ittimeline.java.core.control.forstatement;
/**
* 求100以内的偶数
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 11:22
* @website www.ittimeline.net
* @since JDK11.03
*/
public class For100EvenNumber {
public static void main(String[] args) {
int sum=0;
for (int i = 1; i <=100 ; i++) {
if(i%2==0){
sum+=i;
}
}
System.out.println("1-100以内的偶数和是"+sum);
}
}
do/while循环在日常开发中几乎不怎么用,它和while循环的区别就是至少执行一次循环体的内容
do/while循环和while循环的对比
package net.ittimeline.java.core.control.whilestatement;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* while循环和do/while循环的区别
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 18:52
* @website www.ittimeline.net
* @since JDK11.03
*/
public class DoWhileTest {
/**
* 测试while循环
* @param number
*/
public static void testWhile(int number){
while (number<10){
System.out.println(" while循环 number = "+number++);
}
}
public static void testDoWhile(int number){
do{
System.out.println(" do while循环 number = "+number++);
}while (number<10);
}
public static void main(String[] args) {
/**
* 当while循环和do/while循环都满足循环条件时,while循环和do/while循环是等价的
*/
int number=1;
testWhile(number);
testDoWhile(number);
/**
* 当while循环的循环条件不满足时,do...while循环会比while循环多执行一次
*/
number=10;
testWhile(number);
println();
testDoWhile(number);
}
}
4.7 循环结构for
for循环是日常开发程序中使用最多的循环结构,与while循环的不同之处在于for循环的循环初始条件(变量)只能在for循环内使用,而while循环的循环初始条件(变量)可以在whiel循环外部使用。
for循环的循环结构也是由之前提到的循环结构四要素组成,执行顺序也和while一样
for(循环的初始条件;循环条件;迭代条件){
循环体
}
for循环执行流程图
使用for循环输出1-100
package net.ittimeline.java.core.control.forstatement;
/**
* for循环打印输出1-100
*
* @author liuguanglei 18601767221@163.com
* @create 2019-07-30 16:47
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForTo100 {
public static void main(String[] args) {
for (int i =1;i<=100;i++){
System.out.print(i+" ");
}
}
}
使用for循环求1-100以内的和
package net.ittimeline.java.core.control.forstatement;
/**
* 求1-100以内的和
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 11:24
* @website www.ittimeline.net
* @since JDK11.03
*/
public class For100Sum {
public static void main(String[] args) {
//定义变量保存相加的和
int sum=0;
for (int i = 1; i <=100 ; i++) {
//循环累加
sum+=i;
}
System.out.println("1到100以内的和是"+sum);
}
}
编写程序从1循环到150,并且每行打印一个值,另外在每个3的倍数行上打印foo, 在每个5的倍数行上打印biz, 在每个7的倍数行上打印baz
package net.ittimeline.java.core.control.forstatement;
/**
* 编写程序从1循环到150,并且每行打印一个值
* 另外在每个3的倍数行上打印foo
* 在每个5的倍数行上打印biz
* 在每个7的倍数行上打印baz
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 11:28
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForTo150 {
public static void main(String[] args) {
for (int i = 1; i < 150; i++) {
if (i % 3 == 0) {
System.out.println(i + " foo ");
}
if (i % 5 == 0) {
System.out.println(i + " biz ");
}
if (i % 7 == 0) {
System.out.println(i + " baz ");
} else {
System.out.println(i);
}
}
}
}
输入两个正整数m和n,求其最大公约数和最小公倍数
- 最大公约数:两个数同时能被除尽的最大值
- 最小公倍数:同时是两个数的倍数的最小值
- 比如12和20的最大公约数是4,最小公倍数是60
package net.ittimeline.java.core.control.forstatement;
import java.util.Scanner;
/**
* 输入两个正整数m和n,求其最大公约数和最小公倍数
* 最大公约数:两个数同时能被除尽的最大值
* 最小公倍数:同时是两个数的倍数的最小值
* 比如12和20的最大公约数是4,最小公倍数是60
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 15:53
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForGreatestCommonDivisorLeastCommonMultiple {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数");
int m = input.nextInt();
System.out.println("请输入第二个数");
int n = input.nextInt();
//定义变量保存最大公约数
int greatestCommonDivisor = 0;
//定义变量保存最小公倍数
int leastCommonMultiple = 0;
int min = m > n ? n : m;
//求最大公约数
/**
* 查找最大公约数 循环的次数 可以在用户输入的两个整数中最小的那个值的次数之内
* 如果找到了就中断循环
*/
for (int i = min; i >= 1; i--) {
if ((n % i) == 0 && (m % i) == 0) {
System.out.println(" i =" + i);
greatestCommonDivisor = i;
break; //跳出for循环
}
}
System.out.printf("%d和%d的最大公约数是%d \n", m, n, greatestCommonDivisor);
//求最小公倍数
int num = m * n;
for (int i = 0; i < num; i++) {
if (num % m == 0 && num % n == 0) {
leastCommonMultiple = num / m;
break; //跳出for循环
}
}
System.out.printf("%d和%d的最小公倍数是%d \n", m, n, leastCommonMultiple);
}
}
使用for循环输出指定范围内的所有水仙花数字
package net.ittimeline.java.core.control.forstatement;
import java.util.Scanner;
/**
* 使用for循环输出指定范围内的所有水仙花数字
*
*
* 水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number),
* 水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)。
*
*
* 实现思路
* 首先通过取模运算获取三位数的各个数字
* 然后使用Math.pow函数实现求各个数字的三次幂运算
* 再把三个整数的幂运算求和,和用户输入的数字进行比较
* 如果相等,那就是水仙花数
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 16:46
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForNarcissisticNumber {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入你要在指定范围内查找的水仙花数【100-999】");
int number=input.nextInt();
for (int i=100;i<number;i++){
int hundereds=i/100;
int decade=i/10%10;
int theUnit=i%10;
int narcissisticNumber=(hundereds*hundereds*hundereds)+(decade*decade*decade)+(theUnit*theUnit*theUnit);
if(i==narcissisticNumber){
System.out.printf("你输入的数字%d是水仙花数\n",i);
}else{
System.out.printf("你输入的数字%d不是水仙花数\n",i);
}
}
}
}
4.8 死循环
当某些业务场景不知道循环的次数时,可以使用死循环实现.
while循环的死循环结构为
while(true){
//循环体
}
for循环的死循环结构为
for(;;){
//循环体
}
从键盘读取个数不确定的数,并判断读入的正数和负数的个数,输入0时结束程序
package net.ittimeline.java.core.control.forstatement;
import java.util.Scanner;
/**
* for和while死循环应用场景
* 从键盘读取个数不确定的数,并判断读入的正数和负数的个数,输入0时结束程序
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 19:34
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForWhileDeadLoop {
public static void main(String[] args) {
//正数个数的数量
int positiveNumberCount=0;
//负数个数的数量
int negativeNumberCount=0;
Scanner input =new Scanner(System.in);
//使用while循环实现
while (true){
System.out.println("while循环 请输入数字");
int number=input.nextInt();
if(number>0){
positiveNumberCount++;
}
else if(number<0){
negativeNumberCount++;
}
if (number==0){
break;//中断并跳出循环
}
}
System.out.printf("while循环输入的正数数量是%d,输入的负数数量是%d\n",positiveNumberCount,negativeNumberCount);
//使用for循环实现
for (;;){
System.out.println("for循环 请输入数字");
int number=input.nextInt();
if(number>0){
positiveNumberCount++;
}
else if(number<0){
negativeNumberCount++;
}
if (number==0){
break;//中断并跳出循环
}
}
System.out.printf("for循环输入的正数数量是%d,输入的负数数量是%d\n",positiveNumberCount,negativeNumberCount);
}
}
4.9 循环中断-break和continue
break在循环中表示结束循环,如果是嵌套循环,
continue表示结束本次循环,直接进入下一次循环。
break和continue关键字之后的语句都不会再被执行。
break和continue默认结束包含此关键字最近的循环,如果想要break和continue结束外层循环,可以使用带标签的循环实现。
package net.ittimeline.java.core.control.breakcontinue;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* 理解break和continue关键字的作用
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 22:29
* @website www.ittimeline.net
* @since JDK11.03
*/
public class BreakAndContinueSimple {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
if (i == 9) {
break; //跳出当前循环
// print(" i = "+i); //不可达代码
}
if (i % 3 == 0) {
continue; //结束本次循环,调到下次循环
// print(" i = "+i); //不可达代码
}
println(" i = " + i);
}
}
}
理解break和continue关键字在循环中的作用
package net.ittimeline.java.core.control.breakcontinue;
import static net.ittimeline.java.core.util.lang.IntArrayGeneratorUtils.*;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* 循环中断
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 10:45
* @website www.ittimeline.net
* @since JDK11.03
*/
public class BreakAndContinue {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
if (i == 76) {
break;
}
if (i % 9 != 0) {
continue;
}
//输出0-75之间能被9整除的数字
System.out.print(i + " ");
}
println();
//foreach循环
for (int i : range(100)) {
if (i == 76) {
break;
}
if (i % 9 != 0) {
continue;
}
//输出0-75之间能被9整除的数字
System.out.print(i + " ");
}
println();
int i = 0;
while (true) {
i++;
int j = i * 27;
if (j == 1269) {
break;
}
if (i % 10 != 0) {
continue;
}
System.out.print(i + " ");
}
}
}
4.10 JDK1.5新特性-foreach循环
foreach在C#语言中是一个关键字,而Java中的foreach循环是for循环实现的,它通常用于遍历Java中常用的数据结构,例如数组、链表等等。
其循环结构为
for(数据类型 变量名:数据结构){
循环体
}
这里主要先演示使用foreach遍历数组,关于数组的详细介绍,会在下一章给出。
首先在java-core-util模块中实现一个整型数组生成器
package net.ittimeline.java.core.util.lang;
/**
* 数组生成器
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 10:47
* @website www.ittimeline.net
* @since JDK11.03
*/
public class IntArrayGeneratorUtils {
/**
* 创建一个指定大小的整数数组
* @param size
* @return
*/
public static int[] range(int size){
int[] result=new int[size];
for (int i=0;i<size;i++){
result[i]=i;
}
return result;
}
/**
* 生成一个指定区间的整数数组
* @param start
* @param end
* @return
*/
public static int[] range(int start,int end){
int size=end-start;
int[]result=new int[size];
for (int i=start;i<size;i++){
result[i]=start+i;
}
return result;
}
/**
* 生成一个指定区间的整数数组
* @param start 循环的开始条件
* @param end
* @param step
* @return
*/
public static int[] range(int start,int end,int step){
int size=(end-start)/step;
int[] result=new int[size];
for (int i=0;i<size;i++){
result[i]=start+(i*step);
}
return result;
}
}
使用foreach遍历整型数组
package net.ittimeline.java.core.control.foreach;
import static net.ittimeline.java.core.util.lang.IntArrayGeneratorUtils.*;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* foreach遍历整型数组
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 11:19
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForeachInt {
public static void main(String[] args) {
for (int i:range(10)){
print(i+" ");
}
println();
for (int i:range(1,15)){
System.out.print(i+" ");
}
println();
for (int i:range(1,15,2)){
System.out.print(i+" ");
}
}
}
使用foreach遍历字符串
package net.ittimeline.java.core.control.foreach;
/**
* 遍历字符串
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 11:24
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForeachString {
public static void main(String[] args) {
String bookName="Java编程思想第四版";
//字符串的本质是字符数组
for (char ch:bookName.toCharArray()){
System.out.print(ch+" ");
}
}
}
使用foreach遍历浮点类型数组
package net.ittimeline.java.core.control.foreach;
import java.util.Random;
/**
* foreach遍历浮点类型数组
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 11:16
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForeachFloat {
public static void main(String[] args) {
Random random=new Random(88);
float[]floats=new float[10];
for (int i=0;i<floats.length;i++){
floats[i]=random.nextFloat();
}
for (float f:floats){
System.out.println("f = "+f);
}
}
}
4.11 循环嵌套
当把一个循环结构(循环B)声明在另外一个循环结构(循环A)的循环体中,此时就构成了循环的嵌套,此时循环A被称作为外层循环,循环B被称为内层循环。
嵌套循环的执行流程是外层循环执行一次,内层循环执行一遍。
假设外层循环循环m次,内层循环循环n次,那么内层循环的总次数是m*n
次。
package net.ittimeline.java.core.control.forstatement;
/**
* 理解嵌套循环结构
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 20:02
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForForStructureTest {
public static void main(String[] args) {
//外层循环执行一次
for (int i=1;i<=3;i++){
//内层循环执行五次
for (int j=1;j<=5;j++){
System.out.println("i = "+i +" j = "+j);
}
}
}
}
使用嵌套for循环实现打印九九乘法表
package net.ittimeline.java.core.control.forstatement;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* 循环嵌套
* 实现九九乘法口诀表
* 1 * 1 = 1
* 1 * 2 = 2 2 * 2 = 4
* 1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
* 1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
* 1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
* 1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
* 1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
* 1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
* 1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 19:53
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForForMultiplicationTableTest {
public static void main(String[] args) {
int number=9;
//外层循环控制行
for (int i=1;i<=number;i++){
//内层循环控制每行的列
for (int j=1;j<=i;j++){
print(j+ " * "+i+" = "+(i*j)+"\t");
}
//如果一行执行完则换行
println("");
}
}
}
使用for循环打印菱形
package net.ittimeline.java.core.control.forstatement;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* 使用嵌套for循环打印菱形
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * *
* * * *
* * *
* *
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 20:18
* @website www.ittimeline.net
* @since JDK11.03
*/
public class ForForRhombus {
public static void main(String[] args) {
/**
* 打印菱形实现步骤
* 首先将菱形拆解为两个等腰三角形
* 然后分别用两个嵌套循环打印
* 每个嵌套循环中,外层循环控制行数,内层循环控制输出的内容:即空格和*
*
*
*
*/
String star="* ";
/**
* 第一个for循环
* 外层控制循环次数 一共是五次,因为等边三角形占了5行
* 内层循环控制内容 内层循环的第一个循环先打4-i个空格,内层循环的第二个循环打印i
*
*
* * * *
* * *
* * * *
* * * * *
* * * * * *
*
*
*
*/
//第一个嵌套for循环
//外层循环控制行数
for (int i=0;i<5;i++){
//内层循环控制每行的内容
for (int j=0;j<4-i;j++){
print(" ");
}
for (int k=0;k<=i;k++){
print(star);
}
println("");
}
/**
* * * * *
* * * *
* * *
* *
*/
//总共是9行,上一次循环是5行,这里外层循环就只需要四次
for (int i=4;i>0;i--){
//打印空格 空格的个数是4-i
for (int j=0;j<=4-i;j++){
print(" ");
}
//打印星星
for (int k=0;k<i;k++){
print("* ");
}
//换行
println("");
}
}
}
使用嵌套for循环实现求1-100以内的质数
package net.ittimeline.java.core.control.forstatement;
/**
* 查找1-100以内的质数
* 质数:只能被1和自身整除的数->从2开始,到这个数减1结束为止,都不能被这个数本身整除
* 最小的质数是2
* 能被1和自身整除的数字
* @author liuguanglei 18601767221@163.com
* @create 2019-07-30 16:53
* @website www.ittimeline.net
* @since JDK11.03
*/
public class FindPrimesTo100 {
public static void main(String[] args) {
int max=100;
for (int i=2;i<max;i++){
boolean prime=true;
for (int j=2;j<i;j++){
if(i%j==0){
prime=false;
}
}
if(prime){
System.out.println(i+" ");
}
}
}
}
使用嵌套for循环实现求1-100000以内的质数,并统计执行的时间(毫秒数)
package net.ittimeline.java.core.control.forstatement;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* 查找1-100000以内的质数
* 质数:只能被1和自身整除的数->从2开始,到这个数减1结束为止,都不能被这个数本身整除
最小的质数是2
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 21:30
* @website www.ittimeline.net
* @since JDK11.03
*/
public class FindPrimersTo100000 {
public static void main(String[] args) {
/**
* 从2开始,到这个数减1结束为止,都不能被这个数本身整除
*/
int count=0;
boolean isPrimer=true;
//返回当前时间的毫秒数
long startTime=System.currentTimeMillis();
int number=10_0000;
for (int i=2;i<=number;i++){
for (int j=2;j<i;j++){
if(i%j==0){
isPrimer=false;
}
}
if(isPrimer){
// System.out.println("i = "+i);
count++;
}
isPrimer=Boolean.TRUE;
}
long endTime=System.currentTimeMillis();
printf("计算%d以内所有的质数耗时毫秒数为%d,质数的数量为%d",number,(endTime-startTime),count);
// 程序输出结果 计算1-1000000所有的质数耗时毫秒数为11603,质数的数量为9592
}
}
程序优化之后,再次使用嵌套for循环实现求1-100000以内的质数,并统计执行的时间(毫秒数)
package net.ittimeline.java.core.control.forstatement;
import static net.ittimeline.java.core.util.lang.PrintUtils.printf;
/**
* 查找1-100000以内的质数
* 质数:只能被1和自身整除的数->从2开始,到这个数减1结束为止,都不能被这个数本身整除
最小的质数是2
* @author liuguanglei 18601767221@163.com
* @create 2019-08-10 21:30
* @website www.ittimeline.net
* @since JDK11.03
*/
public class FindPrimersTo100000Optimize {
public static void main(String[] args) {
/**
* 从2开始,到这个数减1结束为止,都不能被这个数本身整除
*/
boolean isPrimer=true;
int count =0;
long startTime=System.currentTimeMillis();
int number=10_0000;
for (int i=2;i<=number;i++){
for (int j=2;j<=Math.sqrt(i);j++){
if(i%j==0){
isPrimer=false;
break; //优化 支队本身非质数的自然数有效的
}
}
if(isPrimer){
count++;
}
isPrimer=Boolean.TRUE;
}
long endTime=System.currentTimeMillis();
printf("计算%d以内所有的质数耗时毫秒数为%d,质数的数量为%d",number,(endTime-startTime),count);
//程序输出结果:计算100000以内所有的质数耗时毫秒数为11,质数的数量为9592
}
}
4.12 循环结构-带标签的循环
在循环嵌套时,如果希望在内层循环中断到外层循环时,可以使用带标签的循环实现。
带标签的循环结构如下所示
outer: for(){
inner:for(){
break outer;
}
}
带标签的for循环
package net.ittimeline.java.core.control.forlabel;
import static java.lang.System.out;
/**
* 带标签的for循环
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 11:46
* @website www.ittimeline.net
* @since JDK11.03
*/
public class LabeledFor {
public static void main(String[] args) {
int i = 0;
outer:
for (; true; ) {
inner:
for (; i < 10; i++) {
out.println(" i= " + i);
if (i == 2) {
out.println("continue");
continue;
}
if (i == 3) {
out.println("break");
break;
}
if (i == 7) {
out.println("continue outer");
i++;
//结束本次循环,调到外层循环
continue outer;
}
if (i == 8) {
out.println("break outer");
break outer;
}
for (int k = 0; k < 5; k++) {
if (k == 3) {
out.println("continue inner");
continue inner;
}
}
}
}
}
}
带标签的while循环
package net.ittimeline.java.core.control.forlabel;
import static net.ittimeline.java.core.util.lang.PrintUtils.*;
/**
* 带标签的while循环
*
* @author liuguanglei 18601767221@163.com
* @create 2019-08-02 11:52
* @website www.ittimeline.net
* @since JDK11.03
*/
public class LabeledWhile {
public static void main(String[] args) {
int i=0;
outer:
while(i<9){
int j=0;
inner:while (j<9){
if(j==6){
break outer;
}
println(" i = "+i+" j = "+j);
j++;
}
i++;
}
}
}