Java从入门到精通(一)

简介: Java从入门到精通

Java从入门到精通


Java 语言基础

Java 语言概述

基础常识

软件:即一系列按照特定顺序组织的计算机数据和指令集合。分为:系统软件和应用软件


系统软件 :Windows Linux macOS Unix Android iOS……

应用软件:Word PowerPoint 画图板……

人机交互方式:图形化界面 vs 命令行方式


应用程序 = 算法 + 数据结构


常用 DOS 命令:

dir:列出点钱目录下的文件以及文件夹
md:创建目录
rd:删除目录
cd:进入指定目录
cd..:退回到上一级目录
cd/:退回到根目录
del:删除文件
exit:退出 DOS 命令行

计算机语言的发展迭代史

第一代:机器语言

第二代:汇编语言

第三代:高级语言

面向过程:C,Pascal, Fortran

面向对象:Java,JS,Python,Scala……

Java 语言版本迭代

1991年 Green 项目,开发语言最初命名为 Oak (橡树)

1994年,开发组意识到 Oak 非常适合于互联网

1996年,发布 JDK 1.0,约8.3万个网页应用Java技术来制作

1997年,发布 JDK 1.1,JavaOne 会议召开,创当时全球同类会议规模之最

1998年,发布 JDK 1.2,同年发布企业平台J2EE

1999年,Java 分成 J2SE、J2EE 和 J2ME,JSP/Servlet 技术诞生

2004年,发布里程碑式版本:JDK 1.5,为突出此版本的重要性,更名为 JDK 5.0

2005年,J2SE -> JavaSE,J2EE -> JavaEE,J2ME -> JavaME

2009年,Oracle 公司收购 SUN,交易价格74亿美元

2011年,发布 JDK 7.0

2014年,发布 JDK 8.0,是继 JDK 5.0 以来变化最大的版本

2017年,发布 JDK 9.0,最大限度实现模块化

2018年3月,发布 JDK 10.0,版本号也称为18.3

2018年9月,发布 JDK 11.0,版本号也称为18.9

Java语言的应用领域

Java Web 开发:后台开发

大数据开发

Android 应用程序开发:客户端开发

Java 语言的特点

面向对象


两个要素:类、对象

三个特征:封装、继承、多态

健壮性


去除了 C语言中的指针


自动的垃圾回收 --> 仍然会出现内存溢出、内存泄漏


跨平台性:write once, run anywhere:一次编译,到处运行


功劳归功于:JVM


JDK、JRE、JVM 的关系


JDK 的下载、安装和 path 环境变量的配置

为什么配置 path 环境变量?

path 环境变量:Windows 重装系统执行命令时所要搜寻的路径


为什么要配置 path:希望 Java 的开发工具在任何文件的文件路径下都可以执行成功


如何配置

https://blog.csdn.net/weixin_43344151/article/details/118917382


访问官网,下载对应的版本

https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html


安装

注意问题:安装软件的路径中不能包含中文、空格


配置环境变量

此电脑 --> 右击“属性” --> 点击“高级系统设置” --> 点击“环境变量”

双击系统变量的PATH

依次点击确定

打开cmd窗口

运行javajavacjava -version出现以下画面代表安装配置成功

开发体验 —— HelloWorld



编写

创建一个 Java 源文件:HelloWorld.java

public class HelloWorld{
    public static void main(String[] args){
        System.out.println("Hello, World!");
    }
}
编译
javac HelloWorld.java
运行
java HelloWorld

常见问题解决

总结第一个程序

Java程序编写、编译、运行的过程

编写:将编写的 Java代码保存在以 .java 结尾的源文件中

编译:使用 javac.exe 命令编译我们的 Java 源文件,格式:javac 源文件名.java

运行:使用 java.exe 命令解释运行我们的字节码文件,格式:java 类名

在一个 Java 源文件中可以声明多个 class,但是只能最多有一个类声明为 public 的,而且要求声明为 public 的类的类名必须与源文件名相同

程序的入口是 main() 方法,格式是固定的

输出语句:

System.out.println():先输出数据,然后换行

System.out.print():只输出数据

每一行执行语句都以 ; 结束

编译的过程:编译以后,会生成一个或多个字节码文件,字节码文件的文件名跟 Java 源文件中的类名相同

注释:Comment

分类:

单行注释://

单行注释:/* */

文档注释:/** */

作用:

对所写的程序进行解释说明,增强可读性,方便自己,方便别人

调试所写的代码

特点:

单行注释和多行注释,注释了的内容不参与编译,换句话说,编译以后生成的 .class 结尾的字节码文件不包含注释掉的内容

文档注释所注释的内容可以被 JDK 提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档

多行注释不可以嵌套使用

Java API 文档

API:application programming interface

习惯上:将语言提供的类库,都称为 API

API 文档:针对于提供的类库如何使用,给的一个说明书

良好的编程风格

正确的注释和注释风格

使用文档注释来注释整个类或整个方法。

如果注释方法中的某一个步骤,使用单行或多行注释。

正确的缩进和空白

使用一次tab操作,实现缩进

运算符两边习惯性各加一个空格。比如:2 + 4 * 5。

块的风格

  • Java API 源代码选择了行尾风格

开发工具

文本编辑工具

记事本

UltraEdit

EditPlus

Notepad

TextPad

Java IDE

JBuilder

NetBeans

Eclipse

MyEclipse

IDEA

基本语法

关键字与标识符

关键字

定义:被 Java 语言赋予了特殊含义,用做专门用途的字符串(单词)

特点:关键字中所写字母都为小写

具体关键字:

保留字

定义:现有Java版本尚未使用,但以后版本可能会作为关键字使用。


具体哪些保留字:goto、const


注意:自己命名标识符时要避免使用这些保留字


标识符

定义:凡是自己可以起名字的地方都叫标识符


涉及到的结构:包名、类名、方法名、变量名、接口名、常量名


规则:(必须遵守,否则,编译不通过)


由26个英文字母大小写,0-9 ,_或$ 组成

数字不可以开头。

不可以使用关键字和保留字,但能包含关键字和保留字。

Java 中严格区分大小写,长度无限制。

标识符不能包含空格。

规范:(可以不遵守,不影响编译和运行,但是要求大家遵守


包名:多单词组成时所有字母都小写:xxxyyyzzz

类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz

变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个 单词首字母大写:xxxYyyZzz

常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ

注意点:


在起名字时,为了提高阅读性,要尽量有意义,“见名知意”。

代码整洁之道

介绍


软件中随处可见命名。我们给变量、函数、参数、类和包命名。我们给源代码及源代码所在目录命名。

这么多命名要做,不妨做好它。下文列出了取个好名字的几条简单规则。

名副其实,见名知意


变量名太随意,haha、list1、ok、theList 这些都没啥意义

避免误导


包含List、import、java等类名、关键字或特殊字;

字母o与数字0,字母l与数字1等

提防使用不同之处较小的名称。比如:XYZControllerForEfficientHandlingOfStrings与XYZControllerForEfficientStorageOfStrings

做有意义的区分


反面教材,变量名:a1、a2、a3

避免冗余,不要出现Variable、表字段中避免出现table、字符串避免出现nameString,直接name就行,知道是字符串类型

再比如:定义了两个类:Customer类和CustomerObject类,如何区分?

定义了三个方法:getActiveAccount()、getActiveAccounts()、getActiveAccountInfo(),如何区分?

使用读得出来的名称


不要使用自己拼凑出来的单词,比如:xsxm(学生姓名);genymdhms(生成日期,年、月、日、时、分、秒)

所谓的驼峰命名法,尽量使用完整的单词

使用可搜索的名称


一些常量,最好不直接使用数字,而指定一个变量名,这个变量名可以便于搜索到.

比如:找MAX_CLASSES_PER_STUDENT很容易,但想找数字7就麻烦了。

避免使用编码


匈牙利语标记法

即变量名表明该变量数据类型的小写字母开始。例如,szCmdLine的前缀sz表示“以零结束的字符串”。

成员前缀

避免使用前缀,但是Android中一个比较好的喜欢用m表示私有等,个人感觉比较好

接口和实现

作者不喜欢把接口使用I来开头,实现也希望只是在后面添加Impl

避免思维映射


比如传统上惯用单字母名称做循环计数器。所以就不要给一些非计数器的变量命名为:i、j、k等

类名


类名与对象名应该是名词与名词短语。如Customer、WikiPage、Account和AddressParser。避免使用Data或Info这样的类名。


不能使动词。比如:Manage、Process


方法名


方法名应当是动词或者动词短语。如postPayment、deletePage或save

别扮可爱


有的变量名叫haha、banana


别用eatMyShorts()表示abort()


每个概念对应一个词


项目中同时出现controllers与managers,为什么不统一使用其中一种?


对于那些会用到你代码的程序员,一以贯之的命名法简直就是天降福音。


别用双关语

有时可能使用add并不合适,比例insert、append。add表示完整的新添加的含义。


使用解决方案领域名称


看代码的都是程序员,所以尽量用那些计算机科学术语、算法名、模式名、数学术语,


依据问题所涉领域来命名不算是聪明的做法。


使用源自所涉问题领域的名称


如果不能用程序员熟悉的术语来给手头的工作命名,就采用从所涉问题领域而来的名称吧。


至少,负责维护代码的程序员就能去请教领域专家了。


添加有意义的语境


可以把相关的变量放到一个类中,使用这个类来表明语境。

不要添加没用的语境


名字中带有项目的缩写,这样完全没有必要。比如有一个名为“加油站豪华版”(Gas Station Deluxe)的项目,

在其中给每个类添加GSD前缀就不是什么好策略。

最后的话


取好名字最难的地方在于需要良好的描述技巧和共有文化背景

变量的使用

变量的分类

按数据类型分类

详细说明:

整型:byte(1字节) short(2字节) int(4字节) long(8字节)

byte 范围 -128~127

声明 long 型变量,必须以 “l” 或 ”L” 结尾

通常,定义整型变量时,使用 int 型

整型的常量默认类型是 int 型

浮点型:float (4字节) double(8字节)

浮点型表示带小数点的数值

float 表示数值的范围比 long 还大

定义 float 类型变量时,变量要以 “f” 或 “F” 结尾

通常,定义浮点型变量时,使用 double 型

浮点型的常量,默认类型为 double

字符型:char (2字节)

定义 char 型变量,通常使用一对 ‘’ ,内部只能写一个字符

表示方式

声明一个字符

转义字符

直接使用 Unicode 值来表示字符型常量

布尔型:boolean

只能取两个值之一:true false

通常在条件判断、循环结构中使用

按声明的位置分类

定义变量的格式

数据类型 变量名 = 变量值;

或者

数据类型 变量名;

变量名 = 变量值;

变量使用的注意点

变量必须先声明,后使用

变量都定义在其作用域内。在作用域内,它是有效的。换句话说,出了作用域就失效了

同一个作用域中不可以说明两个重名的变量

基本数据类型变量间运算规则

涉及到的基本数据类型

除了 boolean 类型之外的其它7种

自动类型转换(只涉及7种基本数据类型)

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

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

特别地:当 byte 、short 、char 三种类型的变量做运算时,结果为 int 类型

说明:此时的容量大小指的是,表示数的范围的大小,比如,float 容量要大于 long 的容量

强制类型转换(只涉及7种基本数据类型)

自动类型提升运算的逆过程

需要使用强制符:()

注意点:强制类型转换,可能导致精度损失

String 与 8种基本数据类型间的运算

String 属于引用数据类型,翻译为:字符串

声明 String 类型变量时,使用一对 “”

String 可以和8种基本数据类型做运算,且运算只能是连接运算:+

运算的结果仍然是 String 类型

避免:

// 编译错误
String s = 123;
// 编译错误
int i = (int)"123";

进制

编程中涉及的进制及表示方式

二进制(binary):0,1 ,满2进1.以0b或0B开头。

十进制(decimal):0-9 ,满10进1。

八进制(octal):0-7 ,满8进1. 以数字0开头表示。

**十六进制(hex):**0-9及A-F,满16进1. 以0x或0X开头表示。此处的A-F不区分大小写。 如:0x21AF +1= 0X21B0

二进制的使用说明

计算机底层存储方式:所有数字在计算机底层都以二进制形式存在

二进制数据的存储方式:所有的数值,不管正负,底层都以补码的形式存储

原码、反码、补码的说明

正数

三码合一

负数

原码:直接将一个数值换成二进制,最高位是符号位

反码:对原码按位取反,只是最高位(符号位)确定为1

补码:其反码加1

进制间的转换

运算符

算术运算符

代码

/*
    运算符之一:算术运算符
        + - + - * / % (前)++ ++(后) (前)-- --(后) +
*/
public class AriTest {
    public static void main(String[] args) {
        // 除号:/
        int num1 = 12;
        int num2 = 5;
        int result1 = num1 / num2;
        // 2
        System.out.println(result1);
        int result2 = num1 / num2 * num2;
        // 10
        System.out.println(result1);
        double result3 = num1 / num2;
        // 2.0
        System.out.println(result3);
        // 2.0
        double result4 = num1 / num2 + 0.0;
        // 2.4
        double result5 = num1 / (num2 + 0.0);
        // 2.4
        double result6 = (double) num1 + num2;
        System.out.println(result5);
        System.out.println(result6);
        // 取余:%
        // 结果数的符号与被模数相同
        // 开发中,经常使用 % 来判断能否被除尽的情况
        int m1 = 12;
        int n1 = 5;
        System.out.println("m1 % n1 = " + m1 % n1);
        int m2 = -12;
        int n2 = 5;
        System.out.println("m1 % n1 = " + m2 % n2);
        int m3 = 12;
        int n3 = -5;
        System.out.println("m1 % n1 = " + m3 % n3);
        int m4 = -12;
        int n4 = -5;
        System.out.println("m1 % n1 = " + m4 % n4);
        // (前)++:先自增1,后运算
        // ++(后):先运算,后自增1
        int a1 = 10;
        int b1 = ++a1;
        int a2 = 10;
        int b2 = a2++;
        System.out.println("a1 = " + a1 + ", b1 = " + b1);
        System.out.println("a2 = " + a2 + ", b2 = " + b2);
        int a3 = 10;
        a3++;
        int b3 = a3;
        // 注意点:自增1不会改变本身变量的数据类型
        short s1 = 10;
        s1++;
        System.out.println(s1);
        byte b = 127;
        b++;
        System.out.println("b = " + b);
        // (前)--:先自减1,后运算
        // --(后):先运算,后自减1
        int a4 = 10;
        int b4 = --a4;
        System.out.println("a4 = " + a4 + ", b4 = " + b4);
        int a5 = 10;
        int b5 = --a5;
        System.out.println("a5 = " + a5 + ", b5 = " + b5);
    }
}

特别说明

(前)++:先自增,后运算

(后)++:先运算,后自增**

(前)–:先自减,后运算

(后)–:先运算,后自减

连接符:+ 只能使用在 String 与其它数据类型变量之间使用。

赋值运算符

代码

/*
 * 运算符之二:赋值运算符
 * = += -= *= /= %=
 */
public class SetValueTest {
  public static void main(String[] args) {
    // =:赋值符号
    int i1 = 10;
    int j1 = 10;
    int i2, j2;
    // 连续赋值
    i2 = j2 = 10;
    int i3 = 10, j3 =10;
    int num1 = 10;
    num1 += 2; // num1 = num1 + 2;
    System.out.println(num1);
    int num2 = 10;
    num2 %= 5; // num2 = num2 % 5;
    System.out.println(num2);
    short s1 = 10;
    // 不会改变变量本身的数据类型
    s1 += 2;
    System.out.println(s1);
    // 开发中,如果希望变量实现+2的操作,有几种方法?(前提:int num = 10)
    // 方式1:num = num + 2;
    // 方式2:num += 2; (推荐)
    // 开发中,如果希望变量实现+1的操作,有几种方法?(前提:int num = 10)
    // 方式1:num = num + 1;
    // 方式2:num += 1;
    // 方式3:num++; (推荐)
    // 练习1
    int i = 1;
    i *= 0.1;
    // 0
    System.out.println(i);
    i++;
    // 1
    System.out.println(i);
    // 练习2
    int m = 2;
    int n = 3;
    n *= m++;
    // 3
    System.out.println("m = " + m);
    // 6
    System.out.println("n = " + n);
    // 练习3
    int n1 = 10;
    n1 += (n1++) + (++n1);
    // 32
    System.out.println( n1);
  }
}

特别说明

运算结果不会改变变量本身的数据类型

赋值运算符

代码

/*
 * 运算符之三:比较运算符
 * ==  != > < >= <= instanceof
 * 结论:
 * 1.比较运算符的结果是 boolean 类型
 * 2.区分 == 和 =
 */
public class CompareTest {
  public static void main(String[] args) {
    int i = 10;
    int j = 20;
    System.out.println(i == j); // false
    System.out.println(i = j); // 20
    boolean b1 = true;
    boolean b2 = false;
    System.out.println(b2 == b1); // false
    System.out.println(b2 = b1); // true
  }
}

特别说明

比较运算符的结果都是 boolean 类型

> < >= <= :只能使用在数值类型的数据之间

== != :不仅可以使用在数值类型数据之间,还可以使用在引用类型变量之间

Account acct1 = new Account(1000);
Account acct2 = new Account(2000);
boolean b1 = acct1 == acct2; // 比较两个 Account 是否是同一账户
boolean b2 = acct1 != acct2;

逻辑运算符

代码

/**
* Filename : LogicTest.java
* Author : keke
* Creation time : 下午8:06:50 2021年10月30日
* Description : 运算符之四:逻辑运算符
*         && & || | ! ^
* 说明:
* 1.逻辑运算符操作的都是 boolean 类型的变量
*/
public class LogicTest {
  public static void main(String[] args) {
    // 区分 & 与 &&
    // 相同点:
    // 1.& 与 && 的运算结果相同
    // 2.当符号左边为 true 时,二者都会执行符号右边的运算
    // 不同点:
    // 当符号左边为 false 时,& 会执行符号右边的运算,&& 不会执行符号右边的运算
    // 开发中,推荐使用 &&
    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.| 与 || 的运算结果相同
    // 2.当符号左边为 false 时,二者都会执行符号右边的运算
    // 不同点:
    // 当符号左边为 true 时,| 会执行符号右边的运算,|| 不会执行符号右边的运算
    // 开发中,推荐使用 ||
    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);
  }
}

特别说明

逻辑运算符的操作的都是 boolean 类型的变量,运算结果是 boolean 类型

位运算符

代码

/**
* Filename : BitTest.java
* Author : keke
* Creation time : 下午8:42:10 2021年10月30日
* Description : 运算符之五:位运算符(了解)& | ~ ^ << >> >>>
* 结论:
* 1.位运算符操作的都是整型的数据
* 2.<<:在一定范围内,向左移1位,相当于乘以2
*   >>:在一定范围内,右移1位,相当于除以2
*
* 面试题:最高效的计算 2 * 8 ? 2 << 3 或 8 << 1
*/
public class BitTest {
  public static void main(String[] args) {
    int i = 21;
    i = -21;
    System.out.println("i << 2 = " + (i << 2));
    System.out.println("i << 3 = " + (i << 3));
    System.out.println("i << 26 = " + (i << 26));
    System.out.println("i << 27 = " + (i << 27));
    System.out.println("i >> 2 = " + (i >> 2));
    int m = 12;
    int n = 5;
    System.out.println("m & n = " + (m & n));
    System.out.println("m | n = " + (m | n));
    System.out.println("m ^ n = " + (m ^ n));
    // 练习:交换两个变量的值
    int num1 = 10;
    int num2 = 20;
    System.out.println("num1 = " + num1 + ", num2 =" + num2);
    // 方式一:定义临时变量 (推荐)
    int temp = num1;
    num1 = num2;
    num2 = temp;
    System.out.println("num1 = " + num1 + ", num2 =" + num2);
    // 方式二:
    // 好处:不用定义临时变量
    // 弊端:
    // 1、相加操作可能超出存储范围
    // 2.有局限性:只能适用于数值类型
    num1 = num1 + num2;
    num2 = num1 - num2;
    num1 = num1 - num2;
    System.out.println("num1 = " + num1 + ", num2 =" + num2);
    // 方式三:使用位运算符
    num1 = num1 ^ num2;
    num2 = num1 ^ num2;
    num1 = num1 ^ num2;
    System.out.println("num1 = " + num1 + ", num2 =" + num2);
  }
}

面试题:最高效的计算 2 * 8 ?

答案: 2 << 3 或 8 << 1

特别说明

1.位运算符操作的都是整型的数据

2.<<:在一定范围内,每向左移1位,相当于乘以2

>>:在一定范围内,每向右移1位,相当于除以2

三元运算符

代码

/**
* Filename : SanYuanTest.java
* Author : keke
* Creation time : 下午9:16:12 2021年10月30日
* Description : 运算符之六:三元运算符
* 1.结构:(条件表达式) ? 表达式1 : 表达式2
* 2.说明
*   1.条件表达式的结果为 boolean 类型
*   2.根据条件表达式真或假,决定执行表达式1,还是表达式2
*     如果表达式为 true,则执行表达式1
*     如果表达式为 false,则执行表达式2
*   3.表达式1和表达式2要求是一致的
*   4.三元运算符是可以嵌套的
* 3.凡是可以使用三元运算符的地方,都可以改写成 if-else
* 4.如果程序既可以用三元运算符,也可以用 if-else,那么优先选择三元运算符
*   原因:简洁、执行效率高
*/
public class SanYuanTest {
  public static void main(String[] args) {
    // 获取两个整数的较大值
    int m = 12;
    int n = 5;
    int max = m > n ? m : n;
    System.out.println(max);
    double num = m > n ? 2 : 1.0;
    // m > n ? 2 : "n大"; // 编译错误
    // 不建议
    String maxStr = m > n ? "m 大" : m == n ? "m 和 n 相等" : "n 大";
    System.out.println(maxStr);
    // 获取三个数的最大值
    int n1 = 12;
    int n2 = 30;
    int n3 = -43;
    max = n1 > n2 ? n1 > n3 ? n1 : n3 : n2;
    System.out.println(max);
    if (m > n) {
      System.out.println(m);
    }else {
      System.out.println(n);
    }
  }
}

特别说明

条件表达式的结果为 boolean 类型

根据条件表达式真或假,决定执行表达式1,还是表达式2

如果表达式为 true,则执行表达式1

如果表达式为 false,则执行表达式2

表达式1和表达式2要求是一致的

三元运算符是可以嵌套的

流程控制

分支结构

if-else

格式:

结构一

if(条件表达式){
    执行表达式
}

结构二

if(条件表达式){
    执行表达式1
} else{
    执行表达式2
}

结构三

if(条件表达式){
    执行表达式1
}else if(条件表达式){
    执行表达式2
}
...
else{
  执行表达式n
}

说明:

else 结构是可选的

针对于条件表达式:

如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上面函数下面,无所谓

如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清除应该将哪个结构声明在上面

如果多个条件表达式之间有包含的关系。通常情况下,需要将范围小的声明在范围大的上面,否则,范围小的没机会执行

if-else 结构是可以相互嵌套的

如果 if-else 结构中的执行语句只有一行时,那么这一对大括号可以省略,但是不建议省略

switch-case

格式:

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

说明:

根据 switch 表达式中的值,依次匹配各个 case 中的常量,一旦匹配成功,则进入相应 case 结构中,调用其执行语句。当调用完执行语句以后,则仍然继续向下执行其它 case 结构中的执行语句,直到遇到 break 关键字或此 switch-case结构末尾结束为止

break 关键字可以使用在 switch-case 结构中,表示一旦执行到此关键字,就跳出 switch-case 结构

switch结构中的表达式,只能是如下的6种数据类型之一:

byte、short、char、int、枚举类型(JDK5.0新增)、String(JDK7.0新增)

case 之后只能声明常量,不能声明范围

break 关键字是可选的

default 相当于 if-else 结构中的 else, default 结构是可选的,而且位置是灵活的

循环结构

循环结构的四要素

初始化条件

循环条件 --> 是 boolean 类型

循环体

迭代条件

说明:通常情况下,循环结束都是因为循环条件返回 false 了

for

结构

for(1;2;4){
    3
}

执行过程:1 --> 2 --> 3 --> 4 --> 2 --> 3 --> 4 --> … --> 2

while

结构

1
while(2){
    3;
    4;
}

执行过程:1 --> 2 --> 3 --> 4 --> 2 --> 3 --> 4 --> … --> 2

说明

写 while 循环千万小心不要丢了迭代条件,一旦丢了,就可能导致死循环

for 和 while 循环总结:

开发中,基本上都会从 for、while 中进行选择,实现循环结构

for 循环和 while 循环是可以相互装换的

区别:for 循环和 while 循环的初始化条件部分的作用范围不同

避免出现死循环

do-while

结构:

1
do{
    3
    4;
}while(2);

执行过程:1 -->3 --> 4 --> 2 --> 3 --> 4 --> 2 --> … --> 2

说明:

do-while 循环至少会执行一次循环体

开发中,使用 for 和 while 更多一些,较少使用 do-while

“无限循环”结构

for(;;){
}
while(true){
}

总结:如何结束一个循环结构?

当循环条件是 false 时

在循环体中,执行 break

嵌套循环

嵌套循环:将一个循环结构 A 声明在另一个循环结构 B 的循环体中,就构成了嵌套循环

外层循环:循环结构 B

内层循环:循环结构 A

2.说明

内层循环结构遍历一遍,只相当于外层循环循环体执行了一次

假设外层循环需要执行 m 次,内层循环需要执行 n 次,此时内层循环的循环体一个执行了 m * n 次

外层循环控制行数,内层循环控制列数

典型练习

package day05;
/**
* Filename : ForForTest.java
* Author : keke
* Creation time : 下午1:47:24 2021年11月1日
* Description :
* 嵌套循环的使用
* 1.嵌套循环:将一个循环结构 A 声明在另一个循环结构 B 的循环体中,就构成了嵌套循环
* 2.外层循环:循环结构 B
*   内层循环:循环结构 A
* 3.说明
*   1.内层循环结构遍历一遍,只相当于外层循环循环体执行了一次
*   2.假设外层循环需要执行 m 次,内层循环需要执行 n 次,此时内层循环的循环体一个执行了 m * n 次
*   3.外层循环控制行数,内层循环控制列数
*/
public class ForForTest {
  public static void main(String[] args) {
    for(int i = 1; i <= 4; i++) {
      for(int j = 1; j <= 6; j++) {
        System.out.print('*');
      }
      System.out.println();
    }
    for(int i = 0; i < 5; i++) {
      for(int j = 0; j <= i; j++) {
        System.out.print('*');
      }
      System.out.println();
    }
    for(int i = 0; i < 5; i++) {
      for(int j = 1; j <= 5 - i; j++) {
        System.out.print('*');
      }
      System.out.println();
    }
    System.out.println("==============================================");
    for(int i = 0; i < 5; i++) {
      for(int j = 0; j <= i; j++) {
        System.out.print('*');
      }
      System.out.println();
    }
    for(int i = 0; i < 5; i++) {
      for(int j = 2; j <= 5 - i; j++) {
        System.out.print('*');
      }
      System.out.println();
    }
  }
}
package day05;
/**
* Filename : NineNineTable.java
* Author : keke
* Creation time : 下午2:31:29 2021年11月1日
* Description :
* 九九乘法表
*/
public class NineNineTable {
  public static void main(String[] args) {
    for (int i = 1; i < 10; i++) {
      for(int j = 1; j <= i; j++) {
        System.out.print(j + " * " + i + " = " + i * j + "\t");
      }
      System.out.println();
    }
  }
}
package day05;
/**
* Filename : PrimeNumberTest2.java
* Author : keke
* Creation time : 下午2:41:08 2021年11月1日
* Description :
* 100以内所有的质数
* 质数:只能被1和它本身整除的自然数,又叫素数 --> 从2开始,到这个数-1结束为止,都不能被这个数本身整除
* 最小的质数:2
*/
public class PrimeNumberTest2 {
  public static void main(String[] args) {
    // 获取当前时间的毫秒数
    long start = System.currentTimeMillis();
    label:
    for(int i = 2; i <= 1000; i++) {
      for(int j = 2; j <= Math.sqrt(i); j++) {
        // i 被 j 除尽
        if (i % j == 0) {
          continue label;
        }
      }
      // 能执行到此步骤的,都是质数
      System.out.print(i + " ");
    }
    System.out.println();
    long end = System.currentTimeMillis();
    System.out.println(end - start);
  }
}

补充:衡量一个功能代码的优劣:

正确性

可读性

健壮性

高效率与低存储:时间复杂度、空间复杂度(衡量算法的好坏)

break 和 continue 关键字的使用

关键字 使用范围 循环中使用的作用 相同点
break switch-case
循环结构 结束当前循环 关键字后面不能声明执行语句
continue 循环结构 结束当次循环 关键字后面不能声明执行语句

带标签的 break 和 continue 关键字的使用

Scanner 类的使用

package day04;
import java.util.Scanner;
/**
* Filename : ScannerTest.java
* Author : keke
* Creation time : 下午3:23:13 2021年10月31日
* Description :
* 如何从键盘获取不同类型的变量:需要使用 Scanner 类
* 具体实现步骤:
* 1.导包:import java.util.Scanner;
* 2.Scanner 实例化:Scanner scanner = new Scanner(System.in);
* 3.调用 Scanner 类的相关方法(next() 和 nextXxx()),来获取指定类型的变量
* 注意:
* 需要根据相应的方法,来输入指定类型的值,如果深入到数据类型与要求的类型不匹配,则报异常 InputMismatchException
* 导致程序终止
*/
public class ScannerTest {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.print("请输入你的姓名:");
    String name = scanner.next();
    System.out.println(name);
    System.out.print("请输入你的年龄:");
    int age = scanner.nextInt();
    System.out.println(age);
    System.out.print("请输入你的体重:");
    double weight = scanner.nextDouble();
    System.out.println(weight);
    System.out.print("是否单身:");
    boolean isLove = scanner.nextBoolean();
    System.out.println(isLove);
    // 对于 char 型的获取,Scanner 没有提供相关的方法。只能获取一个字符串
    System.out.print("请输入你的性别:");
    // 获取索引为0位置上的字符
    char genderChar = scanner.next().charAt(0);
    System.out.println(genderChar);
  }
}

数组

数组的概述

数组:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。

数组相关概念

数组名

元素

角标、下标、索引

数组的长度:元素的个数

数组的特点:

数组是有序排列的

数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型

创建数组对象会在内存中开辟一整块连续的空间

数组的长度一旦确定,就不能修改

数组的分类

按照维数:一维数组、二维数组、…

按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组

数据结构:

数据与数据之间的逻辑关系:集合、一对一、一对多、多对多

数据的存储结构

线性表:顺序表(比如:数组)、链表、栈、队列

树形结构:二叉树

图形结构

算法:

排序算法

搜索算法

一维数组

一维数组的声明和初始化

// 1.一维数组的声明和初始化
int[] ids;
// 1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001, 1002, 1003, 1004};
int dids = {1001, 1002, 1003, 1004}; // 类型推断
// 1.2 动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
// 错误的写法
// int[] arr1 = new int[];
// int[5] arr1 = new int[];
// int[] arr1 = new int[3]{1, 2, 3};

一维数组的引用

通过角标的方式调用

// 数组的角标(或索引)从0开始,到数组的长度-1结束
names[0] = "王铭";
names[1] = "王赫";
names[2] = "张学良";
names[3] = "张居龙";
names[4] = "王宏志";
数组的属性

length

System.out.println(names.length);
System.out.println(ids.length);

注意

  • 数组一旦初始化完成,其长度就确定了
  • 数组长度一旦确定,就不可以修改
遍历一维数组
for(int i = 0; i < names.length; i++){
    System.out.print(names[i] + " ");
}
一维数组元素的默认初始化值
  • 数组元素是整型:0
  • 数组元素是浮点型:0.0
  • 数组元素是字符型:0 ‘\u0000’
  • 数组元素是布尔型:false
  • 数组元素是引用类型: null
数组的内存解析

二维数组

如何理解二维数组

数组属于引用数据类型,数组的元素也可以是引用数据类型,一个一维数组的元素如果还是一个一维数组类型的,则此数组称为二维数组

二维数组的声明和初始化
// 静态初始化
int[][] arr1 = new int[][] {{1, 2, 3}, {4, 5}, {6, 7, 8}};
// 动态初始化
String[][] arr2 = new String[3][2];
String[][] arr3 = new String[3][];
// 错误的情况
// String[][] arr4 = new String[][3];
// 正确
int arr4[][] = new int[3][];
int[] arr5[] = new int[3][];
// 类型推断
int[] arr6[] = {{1, 2, 3}, {4, 5}, {6, 7, 8}};


目录
相关文章
|
1月前
|
XML Java 数据库连接
谈谈Java反射:从入门到实践,再到原理
谈谈Java反射:从入门到实践,再到原理
58 0
|
20天前
|
关系型数据库 Java 开发工具
Java入门高频考查基础知识9(15问万字参考答案)
本文探讨了Spring Cloud的工作原理,包括注册中心的心跳机制、服务发现机制,以及Eureka默认的负载均衡策略。同时,概述了Spring Boot中常用的注解及其实现方式,并深入讨论了Spring事务的注解、回滚条件、传播性和隔离级别。文章还介绍了MySQL的存储引擎及其区别,特别关注了InnoDB如何实现MySQL的事务处理。此外,本文还详细探讨了MySQL索引,包括B+树的原理和设计索引的方法。最后,比较了Git和SVN的区别,并介绍了Git命令的底层原理及流程。
29 0
Java入门高频考查基础知识9(15问万字参考答案)
|
20天前
|
存储 缓存 算法
Java入门高频考查基础知识4(字节跳动面试题18题2.5万字参考答案)
最重要的是保持自信和冷静。提前准备,并对自己的知识和经验有自信,这样您就能在面试中展现出最佳的表现。祝您面试顺利!Java 是一种广泛使用的面向对象编程语言,在软件开发领域有着重要的地位。Java 提供了丰富的库和强大的特性,适用于多种应用场景,包括企业应用、移动应用、嵌入式系统等。下是几个面试技巧:复习核心概念、熟悉常见问题、编码实践、项目经验准备、注意优缺点、积极参与互动、准备好问题问对方和知其所以然等,多准备最好轻松能举一反三。
46 0
Java入门高频考查基础知识4(字节跳动面试题18题2.5万字参考答案)
|
20天前
|
存储 算法 JavaScript
Java入门高频考查算法逻辑基础知识3-编程篇(超详细18题1.8万字参考编程实现)
解决这类问题时,建议采取下面的步骤: 理解数学原理:确保你懂得基本的数学公式和法则,这对于制定解决方案至关重要。 优化算法:了解时间复杂度和空间复杂度,并寻找优化的机会。特别注意避免不必要的重复计算。 代码实践:多编写实践代码,并确保你的代码是高效、清晰且稳健的。 错误检查和测试:要为你的代码编写测试案例,测试标准的、边缘情况以及异常输入。 进行复杂问题简化:面对复杂的问题时,先尝试简化问题,然后逐步分析和解决。 沟通和解释:在编写代码的时候清晰地沟通你的思路,不仅要写出正确的代码,还要能向面试官解释你的
32 0
|
20天前
|
存储 Java 编译器
Java入门高频考查基础知识2(超详细28题2.5万字答案)
多态是面向对象编程中的一个重要概念,它允许不同类的对象对同一消息作出不同的响应。在具体实现上,多态允许一个父类的引用指向其子类的对象,并根据实际指向的对象的类型来调用相应的方法。在 Java 中,多态可以通过以下几种方式实现:在同一个类中,方法名相同,但形参列表不同,实现了多态。子类可以重写(覆盖)其父类的方法,实现多态。在父类引用中调用该方法时,根据实际指向的子类对象的类型来调用相应的方法实现。
38 0
|
21天前
|
编解码 算法 安全
【Java技术专题】「入门到精通系列」深入探索Java技术中常用到的六种加密技术和实现
【Java技术专题】「入门到精通系列」深入探索Java技术中常用到的六种加密技术和实现
44 0
|
1月前
|
算法 Java
Java必刷入门递归题×5(内附详细递归解析图)
Java必刷入门递归题×5(内附详细递归解析图)
21 1
|
1月前
|
Java
Java入门必刷的基础题1(八道)
Java入门必刷的基础题1(八道)
20 0
|
1月前
|
分布式计算 Oracle Java
第一篇CSDN博客——Java入门指南:学习Java编程的第一步
第一篇CSDN博客——Java入门指南:学习Java编程的第一步
|
1月前
|
Java 编译器
【Java从入门到精通】Java Character 类
【Java从入门到精通】Java Character 类
31 0