184_刘发顺_Java核心编程

本文详细介绍了Java编程的基础知识,包括Java的面向对象特性、编译和运行过程中的常见错误、数据类型转换规则、二元运算符、直接量类型以及流程控制语句。内容涵盖JavaSE、异常处理、集合框架、函数式接口、List和Set集合的实现类ArrayList和HashSet,以及Map集合的HashMap和TreeMap。文章还讨论了编译和运行Java程序时可能出现的问题及其解决方案,以及如何处理异常。此外,文章提到了IDEA开发环境,强调了Java程序的可读性和规范性,并提供了关于Lambda表达式和集合操作的简要介绍。
摘要由CSDN通过智能技术生成

Java核心编程
Java 技术栈:
Java基础
Java面向对象:Java 是一种面向对象的语言,它对对象中的类、对象、继承、封装、多态、接口、包等均有很好的支持。为了简单起见,Java 只支持类之间的单继承,但是可以使用接口来实现多继承。使用 Java 语言开发程序,需要采用面向对象的思想设计程序和编写代码。
JavaSE(常用的工具类库)
JavaWEB
Java基础框架(SSM)
Spring
SpringMVC
MyBatis

微服务与分布式
SpringBoot + SpringCloud 实训

学完Java可以做什么工作:
Java工程师(程序员)爬虫工程师 运维 产品设计 软件测试

  • Java入门基础及环境搭建

1、Java是什么?Java的特点有哪些?

Java 是近 10 年来计算机软件发展过程中的传奇,其在众多开发者心中的地位可谓“爱不释手”,与其他一些计算机语言随着时间的流逝影响也逐渐减弱不同,Java 随着时间的推移反而变得更加强大。从首次发布开始,Java 就跃到了 Internet 编程的前沿。后续的每一个版本都进一步巩固了这一地位。如今,Java 依然是开发基于 Web 的应用程序的最佳选择。此外,Java 还是智能手机变革的推手,Android 编程采用的就是 Java 语言。

二、什么是Java语言?

  简单地说,Java 是由 Sun Microsystems 公司于 1995 年推出的一门面向对象程序设计语言。

Java程序可用记事本编写运行(保存的文件名中不能出现空格)。

源代码中的重要组成元素

关键字 public 表示访问说明符,表明该类是一个公共类,可以控制其他对象对类成员的访问。

关键字 class 用于声明一个类,其后所跟的字符串是类的名称。

关键字 static 表示该方法是一个静态方法,允许调用 main() 方法,无须创建类的实例。

关键字 void 表示 main() 方法没有返回值。

main() 方法是所有程序的入口,最先开始执行。

“/*”“*/”之间的内容和以“//”开始的内容为 Java 程序的注释。

  • Java 命名规则

1、包的名称由一个小写字母序列组成。

2、类的名称由大写字母开头,其他字母都由小写的单词组成。

3、类的实例的名称由一个小写字母开头,后面的单词由大写字母开头。

4、常量的名称都大写,并且指出完整含义。

5、参数的名称无其他具体规定。

6、数组的命名使用类型[] 数组名的形式。

另外,编码格式规定如下。

7、程序最开始编写导入包和类语句,即 import 语句。import 语句可以有多行,编写完 import 语句后空一行。

8、定义 public 类,顶格书写。类的主体左括号“{”不换行书写,右括号“}”顶格书写。

9、定义 public 类中的变量,缩进书写。

10、定义方法用缩进书写,方法的左括号“{”不换行书写,右括号“}”和方法首行第一个字符对齐。方法体要再次缩进书写,最后一个变量定义和第一个方法定义之间、方法和方法之间最好空一行。

四、编译和运行

        Java 源程序编写并保存到文件之后,还需要进行编译才能运行。编译 Java 源程序使用的是 JDK 中的 javac 命令。

五、编译常见错误解决方法在使用 javac 编译器编译源代码文件时,可能会出现下面几个常见问题。

        (1) Error:cannot read:HelloJava.java javac

        工具程序找不到指定的 java 文件,需要检查文件是否存储在当前目录中,或文件名是否错误。

        (2) HelloJava.java:4:class HelloJava is public,should be declared in a file named MyApplication.java

        源文件中类的名称和源文件名称不符,需要确定源文件名称和类名称是否相同。

        (3) HelloJava.java:6:cannot find symbol

        源程序文件中某些代码部分输入错了,最常产生的原因可能是没有注意到字母的大小写。

        (4) Javac 不是内部或外部命令、可执行程序或批量文件。

        path 设置有误或没有在 path 系统变量中加入 JDK bin 目录。

        如果没有出现上述所列问题,即成功编译了该 Java 文件。在解释执行 .dass 文件时,可能会出现下面几个常见问题。

        (1) Exception in thread main java.lang.NoClassDe£FoundError

        Java 工具程序找不到所指定的 .class 类,需要确定指定的类是否存储在当前目录中,名称是否正确。

        (2)Exception in thread main java.lang.NoSuchMetliodError:main

        没有指定 Java 程序的入口。Java 工具程序指定的类必须有一个程序入口,也就是必须包括 main(String args[]) 这个方法。

五、Java程序的运行过程

Java 程序的运行必须经过编写、编译和运行 3 个步骤。

                 编写:是指在 Java 开发环境中进行程序代码的输入,最终形成后缀名为 .java Java 源文件。

                 编译:是指使用 Java 编译器对源文件进行错误排査的过程,编译后将生成后缀名为 .class 的字节码文件,不像C语言那样生成可执行文件。

                 运行:是指使用 Java 解释器将字节码文件翻译成机器代码,执行并显示结果。

六、IDEA简介

IDEA 全称 IntelliJ IDEA,是java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(gitsvn)JUnitCVS整合、代码分析、 创新的GUI设计等方面的功能可以说是超常的。

 
1、数据类型的转换可以分为隐式转换(自动类型转换)和显式转换(强制类型转换)两种。

2隐式转换(自动类型转换)

如果以下 2 个条件都满足,那么将一种类型的数据赋给另外一种类型变量的时,将执行自动类型转换(automatic type conversion)。

(1)两种数据类型彼此兼容

(2)目标类型的取值范围大于源数据类型(低级类型数据转换成高级类型数据)

在运算过程中,由于不同的数据类型会转换成同一种数据类型,所以整型、浮点型以及字符型都可以参与混合运算。自动转换的规则是从低级类型数据转换成高级类型数据。转换规则如下:

  1. 数值型数据的转换:byte→short→int→long→float→double。
  2. 字符型转换为整型:char→int。

以上数据类型的转换遵循从左到右的转换顺序,最终转换成表达式中表示范围最大的变量的数据类型。3、基本数据类型大小排行榜
 byte    1字节
 short   2字节
 char    2字节
 
int     4字节
 
long    8字节

 float   4字节

 double  8字节
4、小类型数据转为大类型数据(自动转换)
大类型数据转为小类型数据时需要强制转换(类型强转),小类型  变量名  =  (需要转换的类型) 大类型;

注意:大类型数据转为小类型数据有可能会造成数据进度丢失和溢出
5、short类型与char类互相转化需要强制转换
 
7String str1 = "Hello";

//不能强转

//int num1 = (int) str1;

int num2 = 56;

//不能强转

//String str2 = (String) num2;

  // 注意:两种数据类型彼此兼容,否则不能互相转换

  // 基本数据类型不能与引用数据类型转换
8byte b1 = 12;

int num = 13;

byte b2;

//b1+num的结果赋值给b2

    //b1+num 将数据类型统一之后再运算(往大类型数据统一)

    b2 = (byte) (b1 +  num);

9二元运算符

Java 语言中算术运算符的功能是进行算术运算,除了经常使用的加(+)、减(-)、乘(*)和除(\)外,还有取模运算(%)。加(+)、减(-)、乘(*)、除(\)和我们平常接触的数学运算具有相同的含义。

  1. 一元运算符:      -:取反      ++:自增      --:自减
运行代码:public class Demo01 {

    public static void main(String[] args){

        /**

         * 一元运算符:

         *      -:取反

         *      ++:自增

         *      --:自减

         */

     int num1 = 56;

     int num2 = - num1;

        System.out.println(num2);

        int num3 = 25;

        // num3 = num3 ++;

        num3 ++;

        // num3自增 + 1

        System.out.println(num3);

        ++ num3;

        // num3自增 + 1

        System.out.println(num3);// 27

        int num4;

        num4 =  num3 ++;

        // 先将 num3 赋值给num4,然后num3再自增 1

        System.out.println("num4 =" + num4 +",num3 =" + num3);

        int num5 = 25;

        int num6;

        num6 = ++ num5;

        // num5自增,然后再将自增之后的值赋值给 num6

        System.out.println("num5 =" +num5 +",num6 =" + num6);

        int num7 = 25;

        -- num7;

        System.out.println(num7);

        num7 --;

        System.out.println(num7);

    }

}
11java中赋值运算符:

         =:赋值符号

         +=:如, num += 2;  -----> 本质:num = num + 2;

         -=: 如, num -= 2;  -----> 本质:num = num - 2;

         *=: 如, num *= 2;  -----> 本质:num = num * 2;

         /=: 如, num /= 2;  -----> 本质:num = num / 2;

         %=: 如, num %= 2;  -----> 本质:num = num % 2;

运行代码:public class Demo03 {

    public static void main(String[] args) {

        /**

         * java中赋值运算符:

         *          =:赋值符号

         *          +=:如, num += 2;  -----> 本质:num = num + 2;

         *          -=: 如, num -= 2;  -----> 本质:num = num - 2;

         *          *=: 如, num *= 2;  -----> 本质:num = num * 2;

         *          /=: 如, num /= 2;  -----> 本质:num = num / 2;

         *          %=: 如, num %= 2;  -----> 本质:num = num % 2;

         */

        int num = 25;

        num += 2 ;// num = num + 2; ---->  num = 25 + 2

        System.out.println(num);// 27



        int num1 = 25;

        num1 -= 5; // num1 = num1 - 5  -----> num1 = 25 - 5

        System.out.println(num1);// 20



        int num2 = 25;

        num2 *= 2;// num2 = num2 * 2; ------>num2 = 25 * 2

        System.out.println(num2);// 50



        int num3 = 25;

        num3 /= 2 ;// num3 = num3 / 2; -------->num3 = 25 / 2

        System.out.println(num3);// 12



        int num4 = 25;

        num4 %= 2;//num4 = num4 % 2; ------->num4 = 25 % 2

        System.out.println(num4);// 1



    }

}
12java中逻辑运算符:

    与、或、非

   &&(短路与):如:a && b, 如果ab全部为true则结果为true,否则为false
   ||(短路或):如:a || b, a或者b有一个为true,或者ab均为true,则为true,否则为false

  !:atrue,则结果为falseafalse,则结果为true

13、&& & 区别:如果 a false,则不计算 b(因为不论 b 为何值,结果都为 false)

    || | 区别:如果 a true,则不计算 b(因为不论 b 为何值,结果都为 true
  1. 关系运算符:     ==:对等于
   =:不等于
  >:大于
  <:小于
  >=:大于等于
<=:小于等
  注意:关系运算符的结果为布尔值类型
  1. equals(obj)方法和 == 的区别:     equals方法比较的是两个对象的内容是否相等     == 比较的是两个对象再内存中存放的地址是否为同一个
15、java扫描器:用户从控制台输入数据,后台Java程序接收

//创建扫描器对象

Scanner scan = new Scanner(System.in);
16next()nextLine()方法的区别:

     1、当遇到空格或者回车的时候 next()方法停止读取

     2、当遇到回车的时候 nextLine()方法停止读取,读取整行数据
17

18直接量的类型

并不是所有的数据类型都可以指定直接量,能指定直接量的通常只有三种类型:基本类型、字符串类型和 null 类型。具体而言,Java 支持如下 8 种类型的直接量。

1)int 类型的直接量

在程序中直接给出的整型数值,可分为二进制、十进制、八进制和十六进制 4 种,其中二进制需要以 0B 或 0b 开头,八进制需要以 0 开头,十六进制需要以 0x 或 0X 开头。例如 123、012(对应十进制的 10)、0x12(对应十进制的 18)等。

2)long 类型的直接量

在整型数值后添加 l 或 L 后就变成了 long 类型的直接量。例如 3L、0x12L(对应十进制的 18L)。

3)float 类型的直接量

在一个浮点数后添加 f 或 F 就变成了 float 类型的直接量,这个浮点数可以是标准小数形式,也可以是科学计数法形式。例如 5.34F、3.14E5f。

4)double 类型的直接量

直接给出一个标准小数形式或者科学计数法形式的浮点数就是 double 类型的直接量。例如 5.34、3.14E5。

5)boolean 类型的直接量

这个类型的直接量只有 true 和 false。

6)char 类型的直接量

char 类型的直接量有三种形式,分别是用单引号括起来的字符、转义字符和 Unicode 值表示的字符。例如‘a’,‘\n’和‘\u0061’。

7)String 类型的直接量

一个用双引号括起来的字符序列就是 String 类型的直接量。

在大多数其他语言中,包括 C/C++,字符串作为字符的数组被实现。然而,在 Java 中并非如此。在 Java 中,字符串实际上是对象类型。在教程后面你将看到,因为 Java 对字符串是作为对象实现的,因此,它有广泛的字符串处理能力,而且功能既强又好用。

8)null 类型的直接量

这个类型的直接量只有一个值,即 null。

在上面的 8 种类型的直接量中,null 类型是一种特殊类型,它只有一个值:null。而且这个直接量可以赋给任何引用类型的变量,用以表示这个引用类型变量中保存的地址为空,即还未指向任何有效对象。

19关于字符串直接量有一点需要指出,当程序第一次使用某个字符串直接量时,Java 会使用常量池(constant pool)来缓存该字符串直接量,如果程序后面的部分需要用到该字符串直接量时,Java 会直接使用常量池(constantpool)中的字符串直接量。

提示: 由于 String 类是一个典型的不可变类,因此 String 对象创建出来的就不可能改变,因此无需担心共享 String 对象会导致混乱。 常量池(constant pool)指的是在编译期被确定,并被保存在已编译的 .class 文件中的一些数据,它包括关于类、方法、接口中的常量,也包括字符串直接量。

编译期:是指把源码交给编译器编译成计算机可以执行的文件的过程。在Java中也就是把Java代码编成class文件的过程.编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误。

运行期:是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来,在Java中把磁盘中的代码放到内存中就是类加载过程,类加载是运行期的开始部分。

编译期分配内存并不是说在编译期就把程序所需要的空间在内存中分配好,而是说在编译期生成的代码中产生一些指令,在运行代码时通过这些指令把程序所需的内存分配好。只不过在编译期的时候就知道分配的大小,并且知道这些内存的位置。而运行期分配内存是指只有在运行期才确定内存的大小、存放的位置。

 
 
 


Java 流程控制语句

一、Java 语句格式

1、语句编写方式

在 Java 中,语句是最小的组成单位,每个语句必须使用分号作为结束符。

为了使程序语句排列得更加美观、容易阅读和排除错误,一般使用如下规则格式化源代码。 1、在一行内只写一个语句,并采用空格、空行来保证语句容易阅读。 2、在每个复合语句内使用 Tab 键向右缩进。 3、大括号总是放在单独的一行,便于检查是否匹配。

2、空语句

所谓空语句(Empty Statement),它在程序中什么都不做,也不包含具有实际性的语句。在程序中,空语句主要用来作为空循环体。

3、表达式语句

在很多的高级语言中,有专门的赋值语句。而在 Java 中将赋值作为一个运算符,因此只有赋值表达式。在赋值表达式后面添加分号就成了独立的语句。

4、复合语句

复合语句又称为语句块,是很多个语句的组合,从而可以将多个语句看作单个语句。

它的执行规则如下: 1、如果语句块是空的,控制转到语句块的结束点。 2、如果语句块不是空的,控制转到语句列表。当控制到达语句列表的结束点时,控制转到语句的结束点。

二、if else 语句

选择结构(也叫分支结构)解决了顺序结构不能判断的缺点,可以根据一个条件判断执行哪些语句块。选择结构适合于带有逻辑或关系比较等条件判断的计算。例如,判断是否到下班时间,判断两个数的大小等。

1、if 结构

if 语句是使用最多的条件分支结构,它属于选择语句,也可以称为条件语句。if 选择结构是根据条件判断之后再做处理的一种语法结构。默认情况下,if 语句控制着下方紧跟的一条语句的执行。

条件表达式:条件表达式可以是任意一种逻辑表达式,最后返回的结果必须是一个布尔值。取值可以是一个单纯的布尔变量或常 量,也可以是使用关系或布尔运算符的表达式。如果条件为真,那么执行语句块;如果条件为假,则语句块将被绕过而不被执行。

语句块:该语句块可以是一条语句也可以是多条语句。如果仅有一条语句,可省略条件语句中的大括号 {}。当从编程规范角度不 要省略大括号,省略大括号会使程序的可读性变差。

2、if-else 结构

单 if 语句仅能在满足条件时使用,而无法执行任何其他操作(停止)。而结合 else 语句的 if 可以定义两个操作,此时的 if…else 语句表示“如果条件正确则执行一个操作,否则执行另一个操作”。

3、多条件 if-else-if 语句

if 语句的主要功能是给程序提供一个分支。然而,有时候程序中仅仅多一个分支是远远不够的,甚至有时候程序的分支会很复杂,这就需要使用多分支的 if…else if 语句。

4、嵌套 if 的使用

if 语句的用法非常灵活,不仅可以单独使用,还可以在 if 语句里嵌套另一个 if 语句。同样,if…else 语句和 if…else if 语句中也可以嵌套另一个 if 结构的语句,以完成更深层次的判断。

public class Demo01 {

    public static void main(String[] args){

        /**

         * 单分支结构:

         *     if () {

         *

         *     }

         */

​

​

        /**

         * 双分支结构

         * if语句:

         *      if (条件表达式) {

         *          // 条件为true执行

         *          // 代码块

         *      } else {

         *          // 条件为false执行

         *      }

         *

         *      案例:要求用户输入自己的年龄,然后判断其是否成年

         */

        // 创建扫描器对象

        Scanner scan = new Scanner(System.in);

        // 提示用户输入自己的年龄

        System.out.println("请输入您的年龄:");

        int age = scan.nextInt();

        // 判断是否成年

        if(age >= 18){

            System.out.println("恭喜你已经成年,可以上网");

        }else{

            System.out.println("信不信报警抓你");

        }

        /**

         * 多分支结构:

         *      if () {

         *

         *      }else if () {

         *

         *      }else if () {

         *

         *      }....{

         *

         *      }else{

         *         // 最后的else语句可要可不要

         *      }

         *

         *      案例:根据用户输入的年龄判断阶段

         *              0-6:儿童

         *              7-12:少年

         *              13-17:青少年

         *              18-35:青年

         *              36-50:中年

         *              51-65:中老年

         *              65+:老年

         */

        // 提示用户输入自己的年龄

        System.out.println("请输入您的年龄:");

        int age1 = scan.nextInt();

        if(age1 > 0 && age1 <= 6 ){

            System.out.println("儿童");

        }else if(age1 >= 6 && age1 <= 12){

            System.out.println("少年");

        }else if(age1 >= 13 && age1 <= 17){

            System.out.println("青少年");

        }else if(age1 >= 18 && age1 <= 35){

            System.out.println("青年");

        }else if(age1 >= 36 && age1 <= 50){

            System.out.println("中年");

        }else if(age1 >= 51 && age1 <= 65){

            System.out.println("中老年");

        }else{

            System.out.println("老年");

        }

        /***

         * if嵌套

         *      if(boolean){

         *          if(boolean){

         *              ....

         *          }

         *      }else{

         *          if(boolean){

         *              ....

         *          }

         *      }

         *

         *      案例:QQ登录功能,登录流程:1、用户输入用户名,2、用户输入密码,3、点击登录按钮

         */

​

        // 第一种情况:先判断用户名,然后判断密码

        System.out.println("*********************");

        System.out.println("请输入您的用户名:");

        String username = scan.next();

​

        System.out.println("请输入您的密码:");

        String password = scan.next();

​

        // 判断用户名是否正确

        if ("2227894845".equals(username)) {

            // 用户名正确,判断密码是否正确

            if ("123456".equals(password)) {

                // 密码正确

                System.out.println("恭喜你登成功");

            }else{

                // 密码错误

                System.out.println("密码错误");

            }

        }else{

            // 用户名错误,结束登录

            System.out.println("用户名错误");

        }

​

​

        // 第二种情况:直接同判断用户名和密码

        if("2227894845".equals(username) && "123456".equals(password) ){

            System.out.println("登录成功");

        }else{

            System.out.println("登录失败");

        }

    }

}
三木运算语法:

    条件表达式 ? 表达式1 : 表达式2

    当表达式结果为true,执行表达式1,否则执行表达式2

    条件表达式 ? (条件表达式1 ? 表达式1 : 表达式2) : (条件表达式2 ? 表达式1 : 表达式2)

三、switch case语句

1、switch 语句格式

1.1、switch

表示“开关”,这个开关就是 switch 关键字后面小括号里的值,小括号里要放一个整型变量或字符型变量。表达式必须为 byte,short,int,char类型。

Java7 增强了 switch 语句的功能,允许 switch 语句的控制表达式是 java.lang.String 类型的变量或表达式。只能是 java.lang.String 类型,不能是 StringBuffer 或 StringBuilder 这两种字符串的类型。

1.2、case

表示“情况,情形”,case 标签可以是: 1、类型为 char、byte、 short 或 int 的常量表达式。 2、枚举常量。 3、从 Java SE 7 开始, case 标签还可以是字符串字面量。

注意:重复的 case 值是不允许的。

1.3、default

表示“默认”,即其他情况都不满足。default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。通常,default 块放在末尾,也可以省略不写。

1.4、break

表示“停止”,即跳出当前结构。

如果在 case 分支语句的末尾没有 break 语句,有可能触发多个 case 分支。那么就会接着执行下一个 case 分支语句。这种情况相当危险,常常会引发错误。为此,我们在程序中从不使用 switch 语句。

switch 语句的执行过程如下:表达式的值与每个 case 语句中的常量作比较。如果发现了一个与之相匹配的,则执行该 case 语句后的代码。如果没有一个 case 常量与表达式的值相匹配,则执行 default 语句。当然,default 语句是可选的。如果没有相匹配的 case 语句,也没有 default 语句,则什么也不执行。

2、嵌套 switch 语句

可以将一个 switch 语句作为一个外部 switch 语句的语句序列的一部分,这称为嵌套 switch 语句。因为一个 switch 语句定义了自己的块,外部 switch 语句和内部 switch 语句的 case 常量不会产生冲突。

3、if 语句和 switch 语句的区别

if 和 switch 语句都表示条件语句,可以从使用效率和实用性两方面加以区分。

1. 从使用效率上区分

从使用效率上区分,在对同一个变量的不同值作条件判断时,既可以使用 switch 语句,也可以使用 if 语句。使用 switch 语句的效率更高一些,尤其是判断的分支越多,越明显。

2. 从实用性上区分

从语句的实用性角度区分,switch 语句不如 if 条件语句,if 语句是应用最广泛和最实用的语句。

3. 何时使用 if 语句和 switch 语句

在程序开发的过程中,何时使用 if 语句和 switch 语句,需要根据实际情况而定,应尽量做到物尽其用。不能因为 switch 语句的效率高就一直使用,也不能因为 if 语句常用就不用 switch 语句。需要根据实际情况,具体问题具体分析,使用最适合的条件语句。

一般情况下,对于判断条件较少的,可以使用 if 条件语句,但是在实现一些多条件的判断中,最好使用 switch 语

四、while 和 do while 循环

初始化语句(init statement): 一条或多条语句,这些语句用于完成一些初始化工作,初始化语句在循环开始之前执行。 循环条件(test_expression):这是一个 boolean 表达式,这个表达式能决定是否执行循环体。 循环体(body_statement):这个部分是循环的主体,如果循环条件允许,这个代码块将被重复执行。如果这个代码块只有一 行语句,则这个代码块的花括号是可以省略的。 迭代语句(iteration_statement):这个部分在一次循环体执行结束后,对循环条件求值之前执行,通常用于控制循环条件中 的变量,使得循环在合适的时候结束。

while循环:

*      语法:

*          while (循环条件) {

*              循环体

*          }

*
do.while循环

*      语法:

*          do{

*              循环体

*          } while (循环条件);
while循环与do...while循环的区别:

*      1、while是先判断后执行,do...while循环是先执行然后再判断

*      2、do...while循环至少执行一次

* while循环与do...while的特点:都是循环执行某一语句,循环次数素不固定

五、for循环

for循环:

*      语法:

*              for (表达式1; 表达式2; 表达式3) {

*                  循环体

*              }

*      特点:循环次数固定
循环嵌套

         */

        //如果循环嵌套层数超过三层,那么一定是逻辑出了问题

//      for(){

//        while(){

//        do{

//           for(){

//           }

//        }while

//      }

//    }

八、break 语句

某些时候需要在某种条件出现时强行终止循环,而不是等到循环条件为 false 时才退出循环。此时,可以使用 break 来完成这个功能。break 用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到 break,系统将完全结束该循环,开始执行循环之后的代码。

在 Java 中,break 语句有 3 种作用,分别是:在 switch 语句中终止一个语句序列、使用 break 语句直接强行退出循环和使用 break 语句实现 goto 的功能。

1、使用 break 语句直接强行退出循环(break 不带标签)

可以使用 break 语句强行退出循环,忽略循环体中的任何其他语句和循环的条件判断。在循环中遇到 break 语句时,循环被终止,在循环后面的语句重新开始。

 foreach语法:

*      for(迭代变量类型 变量的名字 :需要遍历(迭代)的对象){

*          语句块;

*      }

*/
break语句:作用:结束当前循环

*/
定义方法的语法:

 *      修饰符  返回值类型   方法名(参数1,参数2...) { 方法体... }

 */

​

// 自定义方法输出

// 无返回值。有参数
定义有返回值的方法,但是没有参数
return关键字的作用:1、结束方法的执行。2、将方法的执行结果返回给调用者
 方法(函数)的类型:

 *      1、无参无返回值

 *          修饰符  void  方法名(){ 方法体 }

 *      2、无参有返回值

 *          修饰符   返回值类型   方法名(){ 方法体}

 *      3、有参无返回值

 *          修饰符   void   方法名(参数1, 参数2,....){ 方法体}

 *      4、有参有返回值

 *          修饰符   返回值类型  方法名(参数1, 参数2,....){ 方法体}

 */

​

/**

 * 比较两个数的大小,将大的值返回回去

 * @param num1

 * @param num2

 * @return 返回最大值
# 二、方法的定义和调用

​

首先方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

​

       **修饰符:**修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。

​

       返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。

​

       **方法名:**是方法的实际名称。方法名和参数表共同构成方法签名。

​

       **参数类型:**参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。

​

       **方法体:**方法体包含具体的语句,定义该方法的功能。

方法调用

**方法的作用及特点:**

​

       1、封装一段特定的业务逻辑功能

​

       2、尽可能独立,一个方法只干一件事

​

       3、方法可以被反复多次的调用

​

       4、减少代码的重复,有利于代码的维护,有利于团队的协作

​

 **方法调用:**

​

       调用方法:对象名.方法名(实参列表),类名.方法名()。

​

       Java支持两种调用方法的方式,根据方法是否有返回值来选择:

*      1、通过 对象.方法名字(参数)

*      2、类名.方法(参数)

*      3、方法(参数)
调用非static关键字修饰的方法,语法:对象.方法(参数)
调用被static修饰的方法,语法:类名.方法(参数)
法重载:

       重载就是在一个类中,有相同的函数名称,但参数列表不相同的方法。

​

   注意:

       方法重载只与方法名字和参数列表有关,与方法返回值类型无关

​

   方法签名:方法名字 + 参数列表

​

   什么是程序?

   答:程序 = 算法 + 数据结构

*/
可变参数的定义, 可变参数最终会被封装成一个数组

可变参数必须位于参数列表的最后一个

    /*public String fun3(long... longs, String str, int num){

        return null;

    }*/

九、continue 语句

continue 语句是跳过循环体中剩余的语句而强制执行下一次循环,其作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。

continue 语句类似于 break 语句,但它只能出现在循环体中。它与 break 语句的区别在于:continue 并不是中断循环语句,而是中止当前迭代的循环,进入下一次的迭代。简单来讲,continue 是忽略循环语句的当次循环。

注意:continue 语句只能用在 while 语句、for 语句或者 foreach 语句的循环体之中,在这之外的任何地方使用它都会引起语法错误。

十、选择结构和循环结构的总结

Java 同样提供了这两种流程控制结构的语法,Java 提供了 if 和 switch 两种分支语句,并提供了 while、do while 和 for 三种循环语句。一般写循环语句时,分以下三步走:

定义初始值

设置判断条件

初始值变化

除此之外,JDK5 还提供了一种新的循环:foreach 循环,能以更简单的方式来遍历集合、数组的元素。

Java 还提供了 break、continue 和 return 来控制程序的循环结构,作用如下:

break:表示跳出当前层循环

continue:表示跳出本次循环,进入下一次循环

return:跳出当前方法的循环

当在实现某个功能语句时,如果需要通过某一个条件去判断,则用选择结构。当实现某个功能需要通过循环去实现,则用循环结构。当然循环和选择是可以相互嵌套的。

六、递归讲解

递归算法:

是一种直接或者间接地调用自身的算法。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。

递归算法:在函数或子过程的内部,直接或者间接地调用自己的算法。 递归算法的实质:是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。

递归算法解决问题的特点:  (1) 递归就是在过程或函数里调用自身。  (2) 在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口。  (3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。  (4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

递归的两个条件:

1、可以通过递归调用来缩小问题规模,且新问题与原问题有着相同的形式。(自身调用)

2、存在一种简单情境,可以使递归在简单情境下退出。(递归出口)

递归三要素:

1、一定有一种可以退出程序的情况;

2、总是在尝试将一个问题化简到更小的规模

3、父问题与子问题不能有重叠的部分

数组

一、数组以及数组的声明和创建

数组的定义:

相同数据类型元素的集合、是一种数据类型(引用类型)

数组的声明:

首先必须先声明数组变量,然后才能在程序中使用数组,

数组的四个基本特点:

1、 数组一旦被创建,它的大小将不可以在被改变。

2、 数组元素必须是相同类型的,不允许出现混合类型。

3、 数组中的元素可以是任何类型,包括基本类型与引用类型。

4、 数组属于引用类型,数组可以看成是一个对象,数组中的每一个元素相当于该对象的成员变量,因为数组本身就是对象,Java中对象是存放在堆中的,因此数组无论保存原始类型还是其他类型,数组对象本身都是在堆中。

public class Demo01 {

    public static void main(String[] args) {

        /**

         * 数组定义:

         *      用来存放相同类型的一组数据

         *      数组下标从0开始,对数组元素进行操作是通过数组的下标(索引)

         *      数组一旦被创建,则数组的长度不可被修改

         *    语法:

         *          静态创建数组

         *          数据类型[] 数组名 = {值1,值2....}

         *          数据类型 数组名[] = {值1,值2....}

         *          动态创建数组

         *          数据类型[] 数组名 = new 数据类型[数组长度]

         *          数据类型 数组名[] = new 数据类型[数组长度]

         */

        // 静态创建数组,特点:创建数组的同时给数组元素赋值

        int arr[] = {1, 2, 4, 8, 9};

        // 动态创建数组,特点创建数组时指定数组的长度

        long[] arr1 = new long[5];

​

        int arr2[] = new int[]{1, 5, 8, 9};

​

        // 数组元素赋值:语法,数组名[索引] = 值

        double dArr[] = new double[3];

        // 给数组的第一个元素赋值

        dArr[0] = 3.14159;

        // 给数组的第二个元素赋值

        dArr[1] = 0.618;

        // 使用数组元素

        System.out.println(dArr[0] + 2);// 打印数组的第一个元素

        // 数组元素必须是相同类型的,不允许出现混合类型。

        // dArr[2] = "hello array"; 数组元素类型与数组类型不匹配,语法报错

​

        // 定义引用数据类型数组

        String[] str = new String[5];

        // 创建demo01对象数组

        Demo01[] d1 = new Demo01[10];

        Date date[] = new Date[3];

        // 数组的长度获取方式,array.length

​

​

        // 获取数组d1的长度

        int len = d1.length;

        System.out.println("数组Demo01的长度为:" + len);

    }

}

二、数组三种初始化

1.静态初始化

除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

// 静态初始化基本类型数组

int[] a = {
      1, 2, 3};

2.动态初始化

数组定义与为数组元素分配空间并赋值的操作分开进行

int[] a1 = new int[2];// 动态初始化元素,先分配空间

a1[0] = 1;// 给数组元素赋值

a1[2] = 2;

3.数组的默认初始化

数组是引用类型,他的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化

int a2[] = new int[2];//默认值0,0

boolean[] b = new boolean[2];//默认值 false,false

String[] s = new String[2];//默认值null

三、下标越界异常

数组边界:

数组的下标合法区间为:[0,length-1],如果在这个范围之外将会报错,这种情况称为数组下标越界。例如:

public static void main(String args[]){

       int[]  arr  =  new  int[2];

       // 下列代码将在运行时出现ArrayIndexOutOfBoundsException异常

       System.out.ptintln(arr[2]);

}

注意:

1、 数组是相同数据类型(数据类型可以为任意类型)的有序集合。

2、 数组也是对象,数组元素相当于对象的成员变量。

3、 数组一旦声明,长度就已经确定,不可以再被改变,如果越界,则会报:ArrayIndexOutOfBoundsException异常

四、数组的使用

遍历数组:

遍历数组的意思就是将数组的元素逐个取出来,通常我们使用循环进行遍历。

数组的使用还有很多,例如:查找数组元素中最大的值,数组反序,将数组作为方法的返回值,将数组作为参数等。

 

五、二维数组

1 java中使用 [][] 来定义二维数组,定义数组时也可同时初始化。

两种初始化形式:

1 格式1、动态初始化

数据类型 数组名[][] = new 数据类型[m][n]

数据类型[][]  数组名 = new 数据类型[m][n]

数据类型[]   数组名[] = new 数据类型[m][n]

2 格式2 静态初始化

2

二维数组:

*      数据类型[][] 数组名字 = new 数据类型[m][n]

*

*      本质:数组的元素还是数组

六、Arrays

Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而不用使用对象类调用(注意是不用,而不是不能)。

Arrays类具有以下常用的功能:

给数组赋值:通过调用fill方法。

对数组进行排序:通过sort方法。

比较数组:通过equals方法比较数组中元素的值是否相等。

查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。

将数组转为字符串输出:通过toString方法实现。

数组的复制:

*      System.arraycopy(arr, start, dist, index, length)

​

*   src为原数组,1为复制的起始位置,dest为目的数组,0为目的数组放置的起始位置,6为复制的长度

​

​

*    dest为目的数组,src为原数组,clone复制实现数组全部复制。

*注:clone()比较特殊,对于对象而言,它是深拷贝,但是对于数组而言,它是浅拷贝。
数组扩容与缩容的实质:就是创建一个新的数组,新数组的长度比原来的数组(大,扩容,小,缩容)

七、排序算法

1、算法概述

2、算法分类

十种常见排序算法可以分为两大类:

比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。

非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。

3、相关概念

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。

* Arrays.binarySearch(arr, 96);该方法的返回值为查找到的元素下标

* 注意使用该方法的前提是数组必须要排好序
Arrays.equals(b1, b2)

* 比较数组:通过equals方法比较数组中元素的值是否相等。

4、冒泡排序(Bubble Sort

冒泡排序是一种简单的排序算法。

5、算法描述

1、比较相邻的元素。如果第一个比第二个大,就交换它们两个;

2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;

3、针对所有的元素重复以上的步骤,除了最后一个;

4、重复步骤1~3,直到排序完成。

6、选择排序(Selection Sort

选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

7、算法描述

n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:

1、初始状态:无序区为R[1..n],有序区为空;

2、第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1..i-1]R(i..n)。该趟排序从当前无序区中-选出关键字最小的 记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序 区;

3n-1趟结束,数组有序化了。

8、插入排序(Insertion Sort

插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

9、算法描述

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

1、从第一个元素开始,该元素可以认为已经被排序;

2、取出下一个元素,在已经排序的元素序列中从后向前扫描;

3、如果该元素(已排序)大于新元素,将该元素移到下一位置;

4、重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

5、将新元素插入到该位置后;

6、重复步骤2~5

10、排序方法有:冒泡排序(Bubble Sort)、选择排序(Selection Sort)、插入排序(Insertion Sort)、希尔排序、(Shell Sort)、归并排序、(Merge Sort)、快速排序(Quick Sort)、堆排序(Heap Sort)、计数排序(Counting Sort)、桶排序(Bucket Sort)、基数排序(Radix Sort

八、稀疏数组

稀疏数组介绍:

当一个数组中大部分元素为0时,或者为同一值的数组时,可以使用稀疏数组来保存该数组。

稀疏数组的处理方式是:

1 记录数组一共有几行几列,有多少个不同的值。

2 把具体有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。

稀疏数组定义:

稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组。

Java面向对象——OOP

一、什么是面向对象

面向过程与面向对象:

面向过程思想:

1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值