1 运算符

1.1 运算符概述

1.1.1 运算符概述

运算符是一种告诉计算机执行特定的数学或逻辑等操作的符号。Java运算符号包括:数学运算符、关系运算符、逻辑运算符、赋值运算符号、字符串连接运算符。计算机本质上只能处理数字,处理数字的最常见的方式就是使用运算符,如:a+b。

Java从C语言继承的丰富的运算符:

1.1.2 运算符要点

按照参与运算的元素个数来划分,运算符分为:

  • 单目(元)运算符:比如 a++
  • 双目(元)运算符:比如 a+b
  • 三目(元)运算符:比如 running ” />

    在java代码中,余数计算规则如下:

    当除数是正数时,余数运算规律为:

    • 被除数是正数时,余数是介于0到除数之间的整数,如:除数3,则余数是0 1 2之一, 范围是[0,3)
    • 如果被除数分别是0 1 2 3 4 … ,则余数现实为周期性数值,如:除数3则余数分别是0 1 2 0 1 2 0 1 2 …
    • 如果被除数是负数,除数是3其余数范围是:(-3, 0]

    在java开发中,余数计算常用于:

    • 控制计算结果的范围,比如控制计算结果是3以内的数,就对3取余数就行了
    • 控制周期性运算:比如“发牌”,周期循环动画

    1.2.4【案例】取余运算示例

    在day02包下新建类,类名为 RemainderDemo,测试取余运算。

    案例示意代码如下:

    package day02;public class RemainderDemo {public static void main(String[] args) {System.out.println(-5%3);System.out.println(0%3);System.out.println(1%3);System.out.println(2%3);System.out.println(3%3);System.out.println(4%3);System.out.println(5%3);System.out.println(6%3);System.out.println(7%3);}}

    1.2.5 自增/自减运算

    自增、自减运算就是将当前变量的值增加1或者减少1。传统数学计算中是不存在自增或者自减运算的,由于软件开发中经常需要按照次序连续处理数据,计算机专家们按照自己的使用习惯设计了自增自减运算。这些运算经常用于在开发编码中,可以使程序编码变的非常干练简洁。自增运算 ++ 和自减运算符—都是单目运算符,即只有一个操作元素参与运算,其基本运算规则是将参与运算的数值增加或者减少1。

    查看如下图所示的运算示意:

    自增/自减一共分为 4 种写法:

    1、i++ 称为“后加加”

    • 先取变量i的值作为 i++ 整体表达式的值,再将i的值增加1
    • 假设运算前i=1,则运算后 i++ 的结果为1 ,i为2

    2、++i 称为“先加加”

    • 先将i的值增加1,再取变量i的值作为 ++i 整体表达式的值
    • 假设运算前i=1,则运算后 ++i 的结果为2 ,i为2

    3、i– 称为“后减减”

    • 先取变量i的值作为 i– 整体表达式的值,再将i的值减少1
    • 假设运算前i=1,则运算后 i—的结果为1 ,i为0

    4、–i 称为“先减减”

    • 先将i的值减少1,再取变量i的值作为 –i 整体表达式的值
    • 假设运算前i=1,则运算后 –i 的结果为0 ,i为0

    1.2.6【案例】自增/自减运算示例

    在day02包下新建类,类名为 IncrementDemo,测试自增和自减运算。

    案例示意代码如下:

    package day02;public class IncrementDemo {public static void main(String[] args) {int i = 1;System.out.println(i++); //1System.out.println(i); //2i = 1;System.out.println(++i); //2System.out.println(i); //2i = 1;System.out.println(i--); //1System.out.println(i); //0i = 1;System.out.println(--i); //0System.out.println(i); //0}}

    1.3 关系运算符

    1.3.1 关系运算符

    关系运算用于比较数值的大、小、相等关系,Java关系运算符与数学上的关系运算规则类似。在开发中用来判断数据的大小以及是否相等。

    Java的关系运算符如下所示:

    关系运算的结果是boolean类型数据:如果比较结果成立则得到true,否则得到false。规则如下所示:

    1.3.2【案例】关系运算符示例

    在day02包下新建类,类名为 RelationalDemo,测试关系运算。

    案例示意代码如下:

    package day02;public class RelationalDemo {public static void main(String[] args) {int age = 5;System.out.println(age>12);System.out.println(age>=12);System.out.println(age<12);System.out.println(age<=12);System.out.println(age==5);System.out.println(age!=5);}}

    1.4 逻辑运算符

    1.4.1 什么是逻辑运算

    利用逻辑运算可以将简单的逻辑复合成为复杂逻辑,实现复杂判断。在软件开发过程中,如果遇到复杂的逻辑条件判断,就可以利用逻辑运算符将简单逻辑组合为复杂逻辑。

    比如,判定一个人是否为老头的逻辑为:年龄大于60的男性。则为两个逻辑判断组合而成:年龄大于60,且,性别为男。

    1.4.2 逻辑运算符

    参与逻辑运算的变量或表达式都是boolean类型,运算结果也为boolean类型。

    逻辑运算符有3种:

    • 逻辑与 &&
    • 逻辑或 ||
    • 逻辑非 !

    三种逻辑运算符的运算规则如下:

    1.4.3【案例】闰年判断

    闰年是比普通年份多出一段时间的年份,目的是为了弥补人为规定的纪年与地球公转产生的差异。地球公转一年的周期称为回归年,总时长为 365天5时48分46秒 ,也是太阳直射点来回的周期,也就是通常说的一年。

    按照一年365天计算,则存在时间上的差异,因为设计出来闰年以实现时间上的找平补齐。

    目前使用的格里高利历闰年规则如下:

    • 公元年份除以4可整除但除以100不可整除,为闰年
    • 公元年份除以400可整除,为闰年

    可以简单总结为:四年一闰,百年不润,四百年再闰。

    在day02包下新建类,类名为LogicalDemo1,编写代码:输入年份数字,判断是否为闰年并输出结果。

    案例示意代码如下:

    package day02;import java.util.Scanner;public class LogicalDemo1 {public static void main(String[] args) {Scanner console = new Scanner(System.in);System.out.print("输入年份:");int year = console.nextInt();boolean b=((year % 4 == 0) && !(year % 100 == 0))||(year % 400 == 0);System.out.println(b);}}

    注意:这里使用了Scanner,它是Java提供的API,利用Scanner可以从控制台获取用户输入的参数,使用步骤如下:

    • 导入Scanner API: import java.util.Scanner;
    • 创建Scanner对象:Scanner console = new Scanner(System.in);
    • 调用方法获取用户输入信息:int year = console.nextInt();

    1.4.4 短路逻辑运算

    短路逻辑运算是指在进行两元逻辑运算时,如果能够通过第一个表达式得到整体运算结果,就不再运算第二个表达式。

    Java的两元逻辑运算符 && 和 || 都按照短路规则执行。短路运算规则有着诸多的好处,首先可以减少运算次数提高程序性能,还可以利用第一个表达式运算结果跳过第二个表达式,避免第二个表达式的运算错误(这个现象会在面向对象阶段详细阐述)。

    短路&&运算的规则如下所示:

    1.4.5【案例】短路逻辑运算示例

    在day02包下新建类,类名为 LogicalDemo2,测试短路逻辑运算。

    案例示意代码如下:

    package day02;public class LogicalDemo2 {public static void main(String[] args) {char gender = '女';int age = 26;boolean pass = gender == '女' || age >= 60;System.out.println(pass);}}

    由于短路逻辑更接近生活逻辑,并且可以一定程度的提高计算速度,所以短路逻辑还是比较常用的。

    1.5 赋值运算符

    1.5.1 赋值运算

    基本的赋值运算符是“=”,你一开始可能会以为它是“等于”,其实并非如此。它实际上意味着把右边表达式的值赋给左侧变量。

    由于赋值运算是优先级别最低的运算符,在其他运算之后进行运算,所以在Java中使用如下运算是可以的:

    int i = 9;i = i + 10;System.out.println(i);//19

    赋值运算本身也是一个“赋值表达式”,运算结束后整个“赋值表达式”有值,其值是最后赋值的值,如:

    int n = 9; int k;System.out.println(k = n+5); //14

    1.5.2【案例】赋值运算示例

    在day02包下新建类,类名为 AssignmentDemo2,测试赋值运算。

    案例示意代码如下:

    package day02;public class AssignmentDemo2 {public static void main(String[] args) {int a, b, c, d;a = b = c = d = 20;System.out.println(a);System.out.println(b);System.out.println(c);System.out.println(d);}}

    由上述代码可以看出:赋值运算的结合性是从右到左,与常规的数学运算习惯的从左到右不同。

    1.5.3 复合赋值运算

    “=”和双目运算符组合为复合赋值运算:可以看成是双目运算和赋值运算的简化写法。利用复合赋值运算可以简化代码的编写,提高编程效率。如下图所示:

    常见复合赋值运算有:

    1.5.4 【案例】复合赋值运算示例

    在day02包下新建类,类名为 AssignmentDemo3,测试复合赋值运算。

    案例示意代码如下:

    public class AssignmentDemo3 {public static void main(String[] args) {int n = 1;n += 5;// n = (int)(n+5) //n=6System.out.println(n);n = 1;n -= 8;// n = (int)(n-8)System.out.println(n);// -7n = 1;n +=9.6; // n = (int)(n+9.6)System.out.println(n); // 10}}

    1.6 字符串连接运算符

    1.6.1 字符串连接运算

    字符串连接运算就是将两个字符串连接为一个新的字符串。因为字符串是Java最常用显示信息方式,所以字符串连接也是最常见的字符串运算。

    Java字符串连接使用“+”实现:“+”运算除了可以用于数学加法还可以连接字符串。也就是是说一个加号“+”具有两种功能,这种一个运算符号两种功能现象称为:“运算符重载”。

    1.6.2 “+”运算符规则

    使用“+”元素时:

    • 如果加号两侧都是数值就是数值加法
    • 如果加号的一侧出现了字符串,就按照字符串连接运算计算
    • 字符串连接时候,会将不是字符串的数据转换为字符串再进行连接

    规则如下所示:

    代码示意如下:

    System.out.println(5+5.5);System.out.println(5+"5.5");System.out.println(5+5+"5.5");System.out.println("5"+5+"5.5");

    1.7 三元运算符

    1.7.1 三元运算符

    三元/目运算符也称为“条件运算符”或者“条件表达式”,其本质上是一种简化版的条件判断语句。因为其简洁方便在开发中经常被使用。其逻辑规则如下所示:

    可以看出,在计算三元运算符时:

    • 先计算“boolean表达式”
    • 如果“boolean表达式”的值为true,整个表达式的值为“表达式1”的值
    • 如果“boolean表达式”的值为false,整个表达式的值为“表达式2”的值

    1.7.2【案例】三元运算符示例

    在day02包下新建类,类名为 TernaryDemo,测试三元运算符。

    案例示意代码如下:

    package day02;import java.util.Scanner;public class TernaryDemo {public static void main(String[] args) {// 挑选a和b中的最大值Scanner console = new Scanner(System.in);System.out.print("输入a b:");int a = console.nextInt();int b = console.nextInt();int max = a > b " />

    其中:

    • 顺序:程序按照从上到下顺次执行指令序列
    • 分支:根据分支条件选择一路指令序列执行
    • 循环:根据循环条件反复执行指令序列

    2.2 分支流程控制—if语句

    2.2.1 分支流程控制概述

    分支是指,根据分支条件选择一路指令序列执行。使用分支流程控制语句,可以根据条件控制程序的执行。比如:可以处理碰到边缘就出现反弹动作;价格超过一定值就打折扣等。分支条件语句在软件编码中,是很常用的。

    Java的分支条件语句有:

    • if 语句
    • switch 语句

    分支控制分为3种:

    2.2.2 if单路分支流程控制

    if语句用于处理单路分支流程控制。其语法结构如下:

    上述语句的执行流程为:

    1、先执行指令1

    2、然后执行判断分支条件表达式,得到boolean值

    • 若值为true,则执行if语句块中的指令2
    • 若值为false,则不执行if语句块中的指令2

    3、最后执行指令3

    利用单路分支控制语句可以处理分支逻辑操作,比如: 当商品总价大于等于500,则打8折。示意如下:

    使用分支流程控制语句时候,要先分析业务处理流程,如果业务流程能够套用分支流程控制,就将业务流程套用到分支流程控制语句中,就可以解决业务问题了。

    2.2.3 【案例】if 单路分支示例

    在day02包下新建类,类名为IfDemo1,要求实现:

    • 输入商品总价
    • 如果总价不小于500,则打八折
    • 输出付款金额

    案例示意代码如下:

    package day02;import java.util.Scanner;public class IfDemo1 {public static void main(String[] args) {Scanner console = new Scanner(System.in);System.out.print("输入商品总价:");double total = console.nextDouble();if(total>=500) {//total = total * 0.8;total *= 0.8;}System.out.println("付款金额:"+total);}}

    2.2.4 if else双路分支语句

    if 与else 搭配可以实现双路分支语句,其语法如下:

    其执行流程为:

    1、执行指令1

    2、判断if分支条件表达式的值:

    • 若值为true,则执行指令2
    • 若值为false,则执行指令3

    3、执行指令4

    这就是二选一的执行流程,可以用于解决如下案例:如果商品总价大于等于500,则打8折,如果小于500打95折。

    分析如下所示:

    2.2.5【案例】if else 双路分支示例

    在day02包下新建类,类名为IfDemo2,要求实现:

    • 输入商品总价
    • 如果总价不小于500,则打八折;否则打九折
    • 输出付款金额

    案例示意代码如下:

    package day02;import java.util.Scanner;public class IfDemo2 {public static void main(String[] args) {/** * if esle Demo */Scanner console = new Scanner(System.in);System.out.print("请输入总价:");double total = console.nextDouble();if(total>=500) {total *= 0.8;}else {total *= 0.95;}System.out.println("应付款项:"+total);}}

    2.2.6 if else if 多路分支语句

    if else 可以组合成多路分支语句,用来实现根据多个条件多选一执行,比如分段打折问题:

    • 如果商品总价大于等于800,则打7折
    • 如果商品总价小于800大于等于500,则打8折
    • 如果商品总价小于500大于等于200,则打9折
    • 如果商品总价小于200,则打95折

    其流程可以描述如下:

    利用if else if 语句就可以解决这个问题:

    2.2.7【案例】if else if 多路分支示例

    在day02包下新建类,类名为IfDemo3,要求实现:

    • 输入商品总价
    • 根据不同价位进行折扣计算
    • 输出付款金额

    案例示意代码如下:

    package day02;import java.util.Scanner;public class IfDemo3 {public static void main(String[] args) {Scanner console = new Scanner(System.in);System.out.print("输入总金额:");double total = console.nextDouble();if(total>=800) {total *= 0.7;}else if(total>=500) {total *= 0.8;}else if(total>=200) {total *= 0.9;}else {total *= 0.95;}System.out.println("应付款:"+total);}}

    2.3 分支流程控制—switch语句

    2.3.1 switch case 语句

    switch ... case 是Java的一种多路分支语句,可以根据整数、字符串、枚举类型进行分支:从不同的程序入口开始执行。

    具体语法如下:

    • Java 5 开始switch case语句支持枚举类型
    • Java 7 开始switch case开始支持支持String类型
    • break 用于结束switch语句
    • byte、short、char可以自动转换为int,可以作为分支条件
    • case 后只能是常量,不能是表达式

    具体使用规则如下所示:

    if else if 语句已经可以实现多路分支了,而switch case语句在整数等情况下进行分支判断时候性能更好。所以根据整数值进行分支时候建议使用switch case,这样可以提升运算性能。

    注意:if else if是万能多路分支语句,而switch只能对整数(字符串、枚举)进行分支,是限定整数情况下才能使用;而使用switch case的根本原因就是因为其性能优势。所以在开发中,如果可以根据整数进行分支,建议使用switch case。

    2.3.2【案例】switch case分支示例

    在day02包下新建类,类名为SwitchDemo,要求实现:

    • 根据学生的成绩输出学生的等级(输入的成绩是百分制)
    • 输出评定等级:100~90分输出A,89~80输出B,79~60输出C,59以下输出D

    分析这个案例,其代码逻辑如下所示:

    对于相同的case语句,可以去除break后合并case语句,简化代码:

    案例示意代码如下:

    package day02;import java.util.Scanner;public class SwitchDemo {public static void main(String[] args) {Scanner console = new Scanner(System.in);System.out.print("输入分数:");int score = console.nextInt();switch(score/10) {case 10:case 9:System.out.println("A");break;case 8:System.out.println("B");break;case 7:case 6:System.out.println("C");break;default:System.out.println("D");}}} 

    2.4 Java新特性-switch表达式

    2.4.1 什么是switch表达式

    Java 12引入了一种新的switch表达式,它在语法和功能上有所改进,使得编写更简洁、易读的代码成为可能。

    传统的switch语句中,每个case后面需要使用break语句来结束,而Java 12的switch表达式中,可以使用"->"箭头来表示代码块的执行,并且不需要显式使用break语句。此外,Java 12的switch表达式还支持新的语法特性,如匹配模式(Pattern Matching)、Lambda表达式和块标签。

    下面是Java 12 switch表达式的基本语法:

    int result = switch (expression) {case value1 -> {// 执行代码块1yield result1;}case value2 -> {// 执行代码块2yield result2;}// 更多的case语句default -> {// 执行默认代码块yield defaultResult;}};

    在这个语法中,switch表达式的结果被赋值给一个变量(此例中的result)。每个case后面的箭头(->)表示对应的代码块的执行,并且可以使用yield语句来返回一个值作为表达式的结果。如果case中只有一个表达式作为返回值的时候可以省略{}和yield。

    2.4.2【案例】使用switch表达式计算价格

    在Java 12中,我们可以使用箭头操作符(->)来指定每个分支的结果。

    String fruit = "apple";int quantity = 2;double totalPrice = switch (fruit) {case "apple" -> 1.0 * quantity;case "banana" -> 0.8 * quantity;case "orange" -> 0.5 * quantity;default -> 0 * quantity;};System.out.println("Total price: $" + totalPrice);

    在这个例子中,我们根据不同的水果类型计算总价格。使用switch表达式,我们可以直接在分支条件中进行计算,并返回结果。

    Java 12的switch表达式提供了更简洁、灵活的语法,使得处理多个分支情况的代码更加清晰易读。它在简化代码、提高开发效率方面有很大的帮助。