JavaSE(尚硅谷视频学习笔记)

本文是关于Java语言的学习笔记,涵盖了从Java语言的基础概念、发展历史、应用领域到环境搭建,再到Java语言的关键字、标识符、变量、进制、运算符、流程控制、数组、面向对象特性和反射机制等全面内容。详细介绍了类、对象、JVM内存结构、注释、API文档、基本语法、异常处理、多线程、常用类库、网络编程以及Java8的新特性。
摘要由CSDN通过智能技术生成

文章目录

Java基础编程

Java语言概述

Java语言简述

1.基础图解

在这里插入图片描述

2.常识

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

  • 1.系统软件:windows,mac os,linux,unix,ios…
  • 2.应用软件:word,ppt…

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

常用DOS命令:

dir:  列出当前目录下的文件以及文件夹
md:   创建目录
rd:   删除目录
cd:   进入指定目录
cd..: 退回到上一级目录
cd\:  退回到根目录
del:  删除文件
exit: 退出dos命令行
3.计算机语言的发展迭代
  • 第一代: 机器语言。指令以二进制代码形式存在。
  • 第二代: 汇编语言。使用助记符表示一条机器指令。
  • 第三代: 高级语言
    • 1.面向过程:C,Pascl、Fortran
    • 2.面向对象:Java,Js,Python,Scala,…
4.Java语言版本迭代概述

在这里插入图片描述

5. Java语言应用的领域
  • ava Web开发:后台开发
  • 大数据开发
  • Android应用程序开发:客户端开发
6.Java语言的特点
  • 面向对象性:
    • 两个要素:类、对象
    • 三个特征:封装、继承、多态
  • 健壮性:
    • 1.去除了C语言中的指针
    • 2.自动的垃圾回收机制—>仍然会出现内存溢出、内存泄漏
  • 跨平台性:
    • once ,run anywhere :一次编译,到处运行
    • 归功于强大Jvm

开发环境的搭建

1. JDK、JRE、JVM的关系

在这里插入图片描述

2. JDK的下载安装
  • 官网:Oracle官方网站( https://www.oracle.com)

  • 配置环境变量

    1. 进入高级系统设置

      • 方法1:选择桌面电脑鼠标右击此电脑,点击属性进入系统信息界面
      • 方法2:通过“控制面板”,选择“系统和安全”,再选择“系统”,在系统信息界面左侧点击 高级系统设置
    2. 在高级系统设置界面,点击环境变量

    3. 环境变量的系统变量设置3项属性,JAVA_HOME,Path,CLASSPATH。若存在则在此基础上“编辑”,不存在则“新建”

      • 新建JAVA_HOME,变量值为JDK安装目录
      • 编辑 Path系统变量,新建值%JAVA_HOME%\bin
  • 验证JDK是否安装成功

    1. win+R快捷键打开运行,输入cmd进入命令提示符
    2. 输入 java -version,(\Java\Javac)查看java版本,有版本信息表示安装成功

注释与API文档

1. 注释Comment
  • 分类:
单行注释://
多行注释:/*     */
文档注释:/**    */
  • 作用:

    • 单行注释和多行注释的作用:

      1. 对所写的程序进行解释说明,增强可读性。方便自己,方便别人
      2. 调试所写的代码
    • 文档注释的使用:

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

    1. 单行注释和多行注释,注释了的内容不参与编译。
      换句话说,编译以后生成的.class结尾的字节码文件中不包含注释掉的信息
    2. 多行注释不可以嵌套使用
2. Java API 文档

API:application programming interface。习惯上:将语言提供的类库,都称为API。
API文档:针对于提供的类库如何使用,给的一个说明书。

3. 良好的编程风格

在这里插入图片描述

基本语法

关键字与标识符

关键字的使用
  • 定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)
  • 特点:关键字中所有字母都为小写
  • 具体有那些关键字:
    在这里插入图片描述
    在这里插入图片描述
保留字

(现Java版本未使用,但以后版本可能会作为关键字使用。)

  • 具体哪些保留字:goto、const(注意:自己命名标识符时要避免使用这些保留字)
标识符的使用

定义:

  1. Java对各种变量、方法和类等要素命名时使用的字符序列称为标识符。
  2. 凡是自己可以起名字的地方都叫标识符。

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

  1. 由26个英文字母大小写,0-9,_或$组成
  2. 数字不可以开头
  3. 不可以使用关键字和保留字,但能包含关键字和保留字
  4. Java中严格区分大小写,长度无限制
  5. 标识符不能包含空格

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

  • 包名:多单词组成时所有字母都小写:xxxyyyzzz
  • 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZxx
  • 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
  • 常量名:所有字母都大写。多单词每个单词用下划线连接:XXX_YYY_ZZZ
  • 注意点:在起名字时为了提高阅读性,要尽量意义,“见名知意”。

变量的使用(重点)

变量的分类:

按数据类型分类:
在这里插入图片描述

详细说明:

  1. 整型:byte(1字节=8bt) \ short(2字节) \ int (4字节) \ long(8字节)
//1.byte范围:-128 ~ 127
byte b1 = 12;
byte b2 = -128;
//b3 = 128;编译不通过

//2.声明long型变量,必须以"l" \ "L"结尾
//3.通常定义整型时,使用int型。
short s1 = 128;
int i1 = 1234;
long l1 = 341434562L;

  1. 浮点型:float(4字节) \ double(8字节)
//1.浮点型,表示带小数点的数值
//2.float表示数值的范围比long还大
double d1 = 123.3;
//3.定义float类型变量时,变量要以"f" \ "F"结尾
float f1 = 12.3f;
//4.通常,定义浮点型变量时,使用double型
  1. 字符型:char(1字符=2字节)
//1.定义char型变量,通常使用一对 '' ,内部只能写一个字符
char c1 = 'a';
//2.表示方式:1.声明一个字符 2.转义字符 3.直接使用 Unicode 值来表示字符型常量
char c = '\n'; //换行符
c = '\t'; //制表符
  1. 布尔型:boolean
//只能两个值之一:true、false
//常常在条件判断、循环结构中使用

按声明位置分类:
在这里插入图片描述

定义变量的格式:

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

变量使用的注意点:
  • 变量必须先声明,后使用
  • 变量都定义在其作用域内。在作用域内,它是有效的。换句话说,出了作用域,就失效
  • 同一个作用域内,不可以声明两个同名的变量
基本数据类型变量间运算规则:
涉及到的基本数据类型:除了boolean之外的其他7种
自动类型转换(7种)

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

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

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

强制类型转换(7种)

自动类型提升运算的逆运算。

  • 需要使用强转符:()
  • 注意点:强制类型转换,可能导致精度损失
//精度损失1
double d1 = 12.9;
int i1 = (int)d1;//截断操作
//精度损失2
int i2 = 128;
byte b = (byte)i2;//b = -128
//没有精度损失
long l1 = 123;
short s2 = (short)l1;
String与8种基本数据类型间的运算
  • String属于引用数据类型,翻译为:字符串
  • 声明String类型变量时,使用一对 “”
  • String可以和8种基本数据类型变量做运算,且运算只能是连接运算:+
  • 运算的结果仍然是String类型
//避免:
String s = 123;//编译错误
String s1 = "123";
int i = (int)s1; //编译错误

进制(了解

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

在这里插入图片描述

2. 二进制的使用说明:
  • 计算机底层的存储方式:所有数字在计算机底层都以二进制形式存在。
  • 二进制数据的存储方式:所有的数值,不管正负,底层都以补码的方式存储。
  • 原码、反码、补码的说明:
正数:三码合一
负数:
    源码:直接将一个数值换成二进制数。最高位是符号位。
    负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。
    负数的补码:其反码加1。
3. 进制间的转换:

图示:
在这里插入图片描述

图示二进制转换为十进制:

在这里插入图片描述
在这里插入图片描述

图示十进制转换为二进制:

在这里插入图片描述

图示二进制与八进制、十六进制的转换:

在这里插入图片描述
在这里插入图片描述

运算符

算数运算符
+ - * / % (前)++ (后)++ (前)-- (后)--

典型代码

//除号:/
    int num1 = 12;
    int num2 = 5;
    int result1 = num1 / num2; //result1 = 2
//取余运算:%
    //结果的符号与被模数的符号相同
    //开发中,经常使用%判断能否被除尽的情况
    int m1 = 12;
    int n1 = 5;
    System.out.println(m1 % n1);//2

    int m2 = -12;
    int n2 = 5;
    System.out.println(m2 % n2);//-2

    int m3 = 12;
    int n3 = -5;
    System.out.println(m3 % n3);//2

    int m4 = -12;
    int n4 = -5;
    System.out.println(m4 % n4);//-2
    
    //(前)++ :先自增1;后运算。(后)++ :先运算;后自增1
        int a1 = 10;
        int b1 = ++a1;
        System.out.println("a1 = "+ a1 + ",b1 = "+b1);//11,11

        int a2 = 10;
        int b2 = a2++;
        System.out.println("a2 = "+ a2 + ",b2 = "+b2);//11,10

        int a3 = 10;
        ++a3;//a3++;
        int b3 = a3;

        //注意点:
        short s1 = 10;
        //s1 = s1 + 1;//编译失败
        //s1 = (short) (s1 + 1);//正确的
        s1++;//自增1不会改变本身的数据类型
        System.out.println(s1);//11

        byte bb1 = 127;
        bb1++;
        System.out.println(bb1);//-128

        //(前)-- :先自减1;后运算。(后)-- :先运算;后自减1
        int a4 = 10;
        int b4 = a4--;
        System.out.println("a4 = "+ a4 + ",b4 = "+b4);//9,10
        int a5 = 10;
        int b5 = --a5;
        System.out.println("a5 = "+ a5 + ",b5 = "+b5);//9,9
赋值运算符
=  +=  -=  *=  /=  %=

典型代码

//=
        int i1 = 10;
        int j1 = 10;

        int i2 , j2;
        //连续赋值
        i2 = j2 = 10;
        int i3 = 10 , j3 = 20;

        int num = 10;
        num += 2;//num = num + 2;

        num %= 5;//num = num % 5;

        short s1 = 10;
        //s1 = s1 + 2;编译失败
        s1 += 2;//不会改变变量本身的数据类型

        //开发中,如果希望变量实现+2的操作,一般推荐num += 2;
        //开发中,如果希望变量实现+1的操作,一般推荐num++;

        int m = 3;
        int n = 6;
        //n *= m++;
        n *= ++m;
        System.out.println(n);
        System.out.println(m);
比较运算符
或关系运算符:==  !=  >  <  >=  <= instanceof

典型代码

        int i = 10;
        int j = 20;
        System.out.println(i == j);//false
        System.out.println(i = j);//20

        boolean b1 = true, b2 = false;
        System.out.println(b2 == b1);//false
        System.out.println(b2 = b1);//true
        
        //**说明**
        1. 比较运算符的结果是boolean类型。
        2. > < >= <= :只能使用在数值类型的数据之间。
        3. ==和!= :不仅可以使用在数值类型数据之间,还可以使用在其他引用类型变量之间。
逻辑运算符
 &  &&  |  ||  !  ^

典型代码

    //区分& 与 &&
    //相同点:1.& 与 && 的运算结果相同。 2.当符号左边是true时,二者都会执行符号右边的运算
    //不同点:当符号左边是false时,&继续执行符号右边的运算,&&不再执行符号右边的运算。
    //开发中,推荐使用&&
        boolean b1 = true;
        b1 = false;
        int num1 = 10;
        if (b1 & (num1++ > 0)){
            System.out.println(1);
        }else {
            System.out.println(2);
        }
        System.out.println(num1);//11

        boolean b2 = true;
        b2 = false;
        int num2 = 10;
        if (b2 && (num2++ > 0)){
            System.out.println(1);
        }else {
            System.out.println(2);
        }
        System.out.println(num2);//10

    //区分| 与 ||
    //相同点:1.| 与 || 的运算结果相同。 2.当符号左边是false时,二者都会执行符号右边的运算
    //不同点:当符号左边是true时,|继续执行符号右边的运算,||不再执行符号右边的运算。
    //开发中,推荐使用||
        boolean b3 = false;
        b3 = true;
        int num3 = 10;
        if (b3 | (num3++ > 0)){
            System.out.println(1);
        }else {
            System.out.println(2);
        }
        System.out.println(num3);//11

        boolean b4 = false;
        b4 = true;
        int num4 = 10;
        if (b4 || (num4++ > 0)){
            System.out.println(1);
        }else {
            System.out.println(2);
        }
        System.out.println(num4);//10

在这里插入图片描述

位运算符
 <<   >>   >>>  &  |  ^  ~

典型代码

     /*
        0000 0000 最高位为0,是正数,最高位为1,是负数
        A = 0011 1100
        b = 0000 1101

        A&B = 0000 1100   有一个为0,则结果为0,同时为1时结果才是1
        A|B = 0011 1101   有一个为1,则结果为1,同时为0时结果才是0
        A^B = 0011 0001   相同时结果为0,不相同结果为1
        ~B = 1111 0010    与B完全相反

        >>   右移
        <<   左移
    */

        System.out.println(2<<3);
    /*
        2的二进制为  0000 0010
        左移相当于把数字往做移动3位
        得到        0001 0000    相当于16
    */
    
    /*
       面试题:最高效2 * 8 的实现方式?
       2 << 3 或 8 << 1
       
       1.位运算符操作的都是整型的数据
       2.<<:在一定范围内,每向左移1位,相当于 *2
         >>:在一定范围内,每向右移1位,相当于 /2
    */
三元运算符
 (条件表达式) ? 表达式1 : 表达式2

典型代码

    //1.如果条件表达式为true,运算后的结果是表达式1;
    //2.如果条件表达式为false,运算后的结果是表达式2;
        int a = 99;
        int b = 10;
        int result = a > b ? a++ : b--;  //表达式1  先赋值后自增
        System.out.println(result);//输出99
        System.out.println("a = " + a);//输出 100
        System.out.println("b = " + b);//输出10
    
    //表达式1和表达式2要为可以赋给接受变量的类型(或可以自动转换)
        int a = 3;
        int b = 8;
        int c = a > b? 2.2 : 3.3;//改为    int c = a > b?(int) 2.2 : (int)3.3;
        System.out.println(c);
        double d = a > b ? a : b + 3;//满足 int --> double
        
    //可以嵌套使用(实现三个数的最大值)
        int a = 56;
        int b = 122;
        int c = 100;
        int max1 = a > b ? a : b;
        int max2 = max1 > c ? max1 : c;//推荐使用第一种
        // int max = (a > b? a : b) > c ?(a > b? a : b):c;
        System.out.println(max2);
        
    //凡是可以用三元运算符的地方,都可以改if-else,反之不成立
    //开发中,即可用三元运算符又可以用if-else的地方,优先用三元运算符。原因:简介、执行效率高。

流程控制

  1. 顺序结构:程序从上到下执行
  2. 分支结构:if-else switch-case
  3. 循环结构:for while do-while
分支结构
if-else
==结构一:==
if(条件表达式){
    执行表达式
}

==结构二:==
if(条件表达式){
    执行表达式1
}else{
    执行表达式2
}

==结构三:==
if(条件表达式){
    执行表达式1
}else if(条件表达式){
    执行表达式2
}else if(条件表达式){
    执行表达式3
}
...
else{
    执行表达式n
}

说明:

  1. else结构是可选的。
  2. 针对条件表达式:
    • 如果多个条件表达式之间“互斥”关系(或没有交集的关系),哪个判断和执行语句说明在上面或下面无所谓。
    • 如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面。
    • 如果多个条件表达式之间有包含的关系,通常情况下,需要把范围小的声明在范围大的上面。否则,范围小的就没机会执行了。
  3. if-else结构是可以相互嵌套的。
  4. 如果if-else结构中的执行语句只有一行时,对应的{}可以省略的。但是,不建议。
switch-case

结构

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

说明:

  1. 根据switch表达式中的值,依次匹配case中的常量,一旦匹配成功,则进入相应的case结构中,调用执行语句。当执行完以后,则仍然继续向下执行case结构,直到遇到break关键字或结构末尾结束为止。
  2. break,可以在switch-case结构中使用,表示一旦执行到break,则跳出结构。
  3. switch结构中的表达式,只能是6种类型之一:byte、short、char、int、枚举(5.0)、String类型(7.0) 。
  4. case后声明的只能是常量,不能声明范围。
  5. break关键字是可选的。
  6. default:相当于if-else结构中的else;default结构是可选的,而且位置是灵活的。
    注意:
//当case执行语句一样是可以考虑合并的,如下:
switch(表达式){
    case 0:
    case 1:
    case 2:
        执行语句;
        break;
    case 3:
    case 4:
    case 5:
        执行语句;
        break;    
    
}
循环结构

循环结构的四要素:

  1. 初始化条件
  2. 循环条件 —》是boolean类型
  3. 循环体
  4. 迭代条件
    说明:通常情况下,循环结束都是因为循环条件中返回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
    说明:
    1. 写while循环千万不要丢了迭代条件。一旦丢失,就可能导致死循环!
    2. 我们写程序要避免程序出现死循环。
    3. for循环和while循环时可以相互转换的!
        区别:for循环和while循环的初始化条件部分的作用范围不同。

do-while循环结构

    1
    do{
        3;
        4;
    }while(2);
    
    执行过程:1-3-4-2-3-4-...-2
    说明:do-while循环至少会执行一次循环体!

无限循环结构:while(true)或for(; ; )
如何结束一个循环结构:
1. 当循环条件是false时
2. 在循环体中,执行break

嵌套循环

  1. 嵌套循环:将一个循环结构A声明在另一个循环结构B的循环体中,就构成了嵌套循环。
    • 内层循环:循环结构A
    • 外层循环:循环结构B
  2. 说明:
    1. 内层循环结构遍历一遍,只相当于外层循环循环体执行了一次。
    2. 假设外层循环需要执行m次,内存循环需要执行n次。此时内层循环的循环体一共执行了m*n次。
    3. 外层循环控制行数,内层循环控制列数。
关键字:break和continue
使用范围 循环中使用的作用(不同点) 相同点
break: switch-case
循环结构中 结束当前循环 关键字后面不能声明执行语句
continue: 循环结构中 结束当次循环 关键字后面不能声明执行语句

补充:带标签的break和continue的使用

补充:Scanner类的使用

具体实现步骤:

  1. 导包:import java.util.Scanner;
  2. 实例化:Scanner scan = new Scanner(System.in);
  3. 调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量。
  4. 注意:需要根据相应的方法,输入指定类型的值。如果输入数据类型与要求的类型不匹配,会报异常:.InputMismatchException ,导致程序终止。

数组

数组的概述

定义:数组是相同类型数据的有序集合,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
特点:

  1. 数组是有序排列的;
  2. 数组属于引用数据类型变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型;
  3. 创建数组对象会在内层中开辟一整块连续的空间;
  4. 数组的长度一旦确定,就不能更改。
    数组的分类:
  5. 照维数:一维数组、二维数组、。。。
  6. 照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组
数据结构:
  1. 数据与数据之间的逻辑关系:集合、一对一、一对多、多对多
  2. 数据的存储结构:
    • 线性表:顺序表(比如:数组)、链表、栈、队列
    • 树形结构:二叉树

一维数组

声明与初始化

//声明:
    dataType[] arrayRefVar;         //首选的方法
    dataType arrayRefVar[];
//创建
    dataType[] arrayRefVar=new dataType[arraySize];
//静态初始化
    int[] array=new int[]{1,2,3};//int[] array={1,2,3};//类型推断
    Man[] mans={new Man(1,1),new Man(2,2)};  //Man是类
//动态初始化
    int[] array=new int[2];
    array[0]=1;
    array[1]=2;
//注意错误的方式:
    int[] arr1 = new int[];
    int[5] arr2 = new int[5];
    int[] arr3 = new int[3]{1,2,3};

一维数组元素的引用
通过角标的方式调用:下标合法区间—[0,length-1]

属性:length
数组一旦初始化,其长度就是确定的。arr.length

一维数组的遍历

    for (int i = 0; i < arr.length; i++){
        System.out.println(arr[i]);
    }

一维数组元素的默认初始化

  • 数组元素是整型:0
  • 数组元素是浮点型:0.0
  • 数组元素是char型:0或’\u0000’,而非’0’
  • 数组元素是boolean型:false
  • 数组元素是引用数据类型:null

一维数组的内存解析
在这里插入图片描述

二维数组

概述

  1. 二维数组其实就是一个特殊的一维数组,一维数组中每个元素就是一个一维数组.
  2. 三维数组又是一个特殊的二维数组.

声明与初始化

    int[][] a = new int[10][10];
    String[][] b = new String[10][10];
    
//静态初始化
    int[][] a = {
  {1,2,3},{4,5},{6,7,8}};
//动态初始化
//1.
    String[][] b = new String[3][2];
//2.
    String[][] b1 = new String[3][];
//也是正确的写法
    int[] arr[] = {
  {1,2,3,4},{4,5,6,7},{8,9,10,11}};

如何调用二维数组元素

     System.out.println(a[0][1]);//2
     System.out.println(b[1][1]);//null
     
     b1[1] = new String[4];
     System.out.println(b1[1][0]);

二维数组的属性

     System.out.println(arr.length);//3
     System.out.println(arr[0].length);//4

二维数组的遍历

public class Text0 {
    public static void main(String[] args) {
        //静态初始化
        int[][] a={
  {1,2,3,4},{4,5,6,7},{8,9,10,11}};
       //遍历
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                System.out.print(a[i][j]+" ");
            }
            System.out.println();
        }
    }
}

二维数组元素的默认初始化

  1. 规定:二维数组分为外层数组的元素,内层数组的元素
    • int[][] arr = new int[4][3];
    • 外层元素:arr[0],arr[1]等
    • 内层元素:arr[0][0],arr[1][2]等
  2. 数组元素的默认初始值
    1. 针对于初始化方式一:比如:int[][] arr = new int[4][3];
      • 外层元素的初始化值为:地址值
      • 内层元素的初始化值为:与一维数组初始化情况相同
    2. 针对于初始化方式二:比如:int[][] arr = new int[4][];
      • 外层元素的初始化值为:null
      • 内层元素的初始化值为:不能调用,否则报错。

二维数组的内存解析
在这里插入图片描述

数组的常见算法

一、数组元素的赋值(杨辉三角)//面试中考察较多
		Scanner number=new Scanner(System.in);
		System.out.println("输入杨辉三角形的行数");
		int numbers= number.nextInt();
		
		int[][] arr1=new int [numbers][numbers];
		for(int i=0;i<numbers;i++){
			for(int j=0;j<=i;j++){
				
				if(i==j||j==0){
					arr1[i][j]=1;
					
				}else if(i>=2){
					arr1[i][j]=arr1[i-1][j]+arr1[i-1][j-1];
				}
				System.out.print(arr1[i][j]);
			}
			System.out.print("\n");
		}
二、求数值型数组元素中的最大值、最小值、平均数、总和等等

算法的考查:求数值型数组中元素的最大值、最小值、平均值、总和等
题目:
定义一个int型的一维数组,包含10个元素,分别赋一些随机数,然后求出所有元素的最大值、最小值、和值 、平均值并输出。
要求:所有的随机数都是两位数。
提示:获取[a,b]范围内的随机数 Math.random()*(b-a+1)+10 ; //radom 获取的值为double类型可以根据需求进行强制转换。

		int [] arr =new int [10];
		for(int i=0;i<arr.length;i++){
			arr[i]=(int)(Math.random()*(99-10+1)+10);
		}
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
		System.out.print("\n");
		//求数组元素的最大值
		int maxValue=arr[0];
		for(int i=0;i<arr.length;i++){
			if(maxValue<arr[i]){
				maxValue=arr[i];
			}
		}
		System.out.println("最大值为:"+maxValue);
		//求数组元素的最小值
		int minValue=arr[0];
		for(int i=0;i<arr.length;i++){
			if(minValue>arr[i]){
				minValue=arr[i];
			}
		}
		System.out.println("最小值为:"+minValue);
		//求数组元素的总和
		int sum=0;
		for(int i=0;i<arr.length;i++){
			sum+=arr[i];
		}
		System.out.println("总和"+sum);
		//求数组元素的平均值
		int value=sum/arr.length;
		System.out.println("平均值"+value);

三、数组的复制、反转、查找(线性查找、二分法查找)

1. 数组的复制(区别于数组的赋值)

    //声名arr1和arr2两个int型的数组。
		int [] arr1,arr2;
	//使用静态初始化将arr1中的8个元素初始化为:2,3,5,7,11,13,17,19.
		arr1=new int []{2,3,5,7,11,13,19};
	//显示arr1中的内容。
		for(int i=0;i<arr1.length;i++){
			System.out.print(arr1[i]+" ");
		}
	//赋值arr1变量等于arr2,修改arr2中的偶索引元素使其等于索引值。打印出arr1。
		arr2=arr1;
		for(int i=0;i<arr2.length;i++){
			if(i%2==0){
				arr2[i]=i;
			}
		}
		System.out.println();
		for(int i=0;i<arr1.length;i++){
			System.out.print(arr1[i]+" ");
		}
	//思考问题:arr1和arr2有什么关系
	//我们可以发现该程序的输出结果和变化后的arr2中的值相同,所以arr2=arr1并不是一个数组间的复制操作,而是通过arr1对arr2进行了一步赋值操作。
	//但是经过arr2=arr1这一操作后,使arr1和arr2的地址值相同,都指向了堆空间内的唯一的一个数组实体。
	
//那么下面我们修改代码实现arr2对arr1数组的复制
		int [] arr1,arr2;
		arr1=new int []{2,3,5,7,11,13,19};
		for(int i=0;i<arr1.length;i++){
			System.out.print(arr1[i]+" ");
		}
    //修改处:
    //如果想要arr有独立的数值空间 就先用new给arr2开辟一个堆空间
		arr2=new int[arr1.length];
		for(int i=0;i<arr1.length;i++){
			arr2[i]=arr1[i];
		}
    //
		for(int i=0;i<arr2.length;i++){
			if(i%2==0){
				arr2[i]=i;
			}
		}
		System.out.println();
		for(int i=0;i<arr1.length;i++){
			System.out.print(arr1[i]+" ");
		}

2. 数组的反转

		String [] arr=new String []{"AA","BB","CC","DD","GG","EE"};
		
		String temp;
		for(int i=0;i<arr.length/2;i++){
			temp=arr[i];
			arr[i]=arr[arr.length-1-i];
			arr[arr.length-1-i]=temp;
		}
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}

3. 数组的查找

	//查找
	//线性查找:
		String dest="BB";
		boolean isflage=true;
		String [] arr=new String []{"AA","BB","CC","DD","GG","EE"};
		for(int i=0;i<arr.length;i++){
			if(dest.equals(arr[i])){
				System.out.println("找到了  ,指定元素的位置为:"+i);
				isflage=false;
				break;
			}
		}
		if(isflage){
			System.out.println("未找到指定元素的位置");
		}
	//二分法查找
	//前提:所要查找的数组必须有序
		int [] arr2=new int []{-98,-32,2,34,54,66,79,105,210,333};
		int dest1=-32;
		int head=0;//初始的首索引
		int end=arr2.length-1;
		boolean isFalse=true;
		while(head<=end){
			int middle=(head+end)/2;
			if(dest1==arr2[middle]){
				System.out.println("找到了指定元素位置为:"+middle);
				isFalse=false;
				break;
			}else if(arr2[middle]>dest1){
				end=middle-1;
			}else {
				head=middle+1;
			}
		}
		if(isFalse){
			System.out.println("未找到指定元素");
		}
四、数组元素的排序算法//面试中考察较多
  • 通常来说,排序的目的是快速查找
  • 衡量排序算的优劣:1.时间复杂度 2.空间复杂度3.稳定性

比如冒泡排序的排序思想:

  1. 比较相邻的元素。如果第一个比第二个大(升序),交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这个步骤做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何邮递数字需要比较为止。
    //冒泡排序的实现
		int temp;
		int [] arr=new int[]{43,32,76,-98,0,64,33,-21,32,99};
		for(int i=0;i<arr.length-1;i++){
			for(int j=0;j<arr.length-i-1;j++){
				if(arr[j]>arr[j+1]){
					temp=arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=temp;
				}
			}
		}
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}

Arrays工具类的使用

  1. 理解:
    1. 定义在java.util包下。
    2. Arrays:提供了很多操作数组的方法。
  2. 使用:
    //boolean equals( int[] a, int[]b):判断两个数组是否相等
        int[] arr1 = new int[]{1,2,3,4};
        int[] arr2 = {2,1,3,4};
        boolean isEquals = Arrays.equals(arr1, arr2);
        System.out.println(isEquals);
    //输出数组信息
        System.out.println(Arrays.toString(arr1));
    //将指定值填充到数组之中
        Arrays.fill(arr1,10);
        System.out.println(Arrays.toString(arr1));
    //对数组进行排序
        Arrays.sort(arr2);
        System.out.println(Arrays.toString(arr2));
    //int binarySearch(int[] a, int key),查找
        int[] arr3 = {-98,-34,2,34,54,66,76,87,99,145};
        int index = Arrays.binarySearch(arr3,87);
        if (index >= 0){
            System.out.println(index);
        }else {
            System.out.println("-1");
        }

数组的常见异常

.ArrayIndexOutOfBoundsException数组角标越界异常

    int[] a = {1,2,3,4};
    System.out.println(a[4]);

.NullPointerException空指针异常

   /* String[][] str = new String[4][];
        System.out.println(str[0][0]);*/

    /*int[] a = {1,2,3,4};
        a = null;
        System.out.println(a[0]);*/

        String[] b = {"AA","BB"};
        b[0] = null;
        System.out.println(b[0].toString());

面向对象-上

类与对象

  1. 面向对象学习的三条主线:

    1. Java类及类的成员:属性、方法、构造器:代码块、内部类
    2. 面向对象的大特征:封装性、继承性、多态性、(抽象性)
    3. 其他关键字:this、super、static、final、abstract、interface、package、import等
  2. 面向对象和面向过程的理解:

    1. 面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。
    2. 面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
  3. 完成一个项目(或功能)的思路:

    1. 根据问题需要,选择问题所针对的现实世界中的实体。
    2. 从实际中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类
    3. 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构成计算机能够识别和处理的数据结构。
    4. 类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
  4. 面向对象中两个重要的概念:

    • 类:对一类事物的描述,是抽象的、概念上的定义
    • 对象:是实际存在的该类事物的每个个体,因而也称为实例(instance)
      • 面向对象程序设计的重点是类的设计
      • 设计类,就是设计类的成员
    • 二者的关系:对象,是由类new出来的,派生出来的。
  5. 类和对象的使用(面向对象思想落地实现的规则一)

    1. 创建类,设计类的成员
    2. 创建类的对象
    3. 通过“对象.属性”或“对象.方法”调用对象的结构

补充:设计类,就是设计类的成员(几个概念的使用说明:)

  • 属性 = 成员变量 = field = 域、字段
  • 方法 = 成员方法 = 函数 = method
  • 创建类的对象 = 类的实例化 = 实例化类
  1. 对象的创建于对象的内存解析

典型代码:

Person p1 = new Person();
Person p2 = new Person();
Person p3 = p1;//没有新创建一个对象,共用一个堆空间中的对象实体

说明:
如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)
意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。
内存解析:
在这里插入图片描述

  1. 匿名对象:我们创建的对象,没显示的赋给一个变量名。即为匿名对象
    特点:匿名对象只能调用一次。
    举例:
new Phone().sendEmail();
new Phone().price = 1999;

应用场景:

PhoneMall mall = new PhoneMall();
//匿名对象的使用
mall.show(new Phone());

其中,
class PhoneMall{
    public void show(Phone phone){
        phone.sendEmail();
        phone.playGame();
    }
}
  1. 理解“万事万物皆对象”
    1. 在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构。
      • Scanner,String等
      • 文件:File
      • 网络资源:URL
    2. 涉及到Java语言与前端Html、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。
JVM的内存结构
  • 编译完源程序以后,生成一个或多个字节码文件。
  • 我们使用JVM中的类的加载器和解析器对生成的字节码文件进行解析运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。

内存解析
在这里插入图片描述

类的结构之一:属性

  • 对比:属性 VS 局部变量
    1. 相同点:
      1. 定义变量的格式:数据类型 变量名 = 变量值
      2. 先声明,后使用
      3. 变量都其对应的作用域
    2. 不同点:
      1. 在类中声明的位置不同
        • 属性:直接定义在类的一对{}内
        • 局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
      2. 关于权限修饰符的不同
        • 属性:可以在声明属性时,指明其权限,使用权限修饰符。常用的权限修饰符:private、public、缺省、protected --》封装性
        • 局部变量:不可以使用权限修饰符。
      3. 默认初始化值的情况:
        • 属性:类的属性,根据其类型,都默认初始化值。
          • 整型(byte、short、int、long:0
          • 浮点型(float、double:0.0
          • 字符型(char:0(或 ‘\u0000’
          • 布尔型(boolean:false
          • 引用数据类型(类、数组、接口:null
        • 局部变量:没默认初始化值。意味着,我们在调用局部变量之前,一定要先赋值。特别的:形参在调用时,我们赋值即可。
      4. 在内存中加载的位置:
        • 属性:加载到堆空间中(非static
        • 局部变量:加载到栈空间

类的结构之二:方法

方法:描述类应该具备的功能。
比如:Math类:sqrt()\random() \ … Scanner类:nextXxx()…
举例:

public void eat(){}
public void eat(int hour){}
public String getName(){}

方法的声明:权限修饰符 返回值类型 方法名(形参列表){
    方法体
}
注意:static、final、abstract来修饰方法的

说明:

  1. 关于权限修饰符:默认方法的权限修饰符先都使用public
    • Java规定的4种权限修饰符:private、public、缺省、protected
  2. 返回值类型:有返回值 VS 没有返回值
    • 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量:“return 数据”。
    • 如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不需要使用return,都是,如果使用的话,只能“return;”表示结束此方法的意思。
    • 我们定义方法时该不该返回值?
      1. 题目要求
      2. 凭经验:具体情况具体分析
  3. 方法名:属于标识符,遵循标识符的规则和规范,“见名知意”
  4. 形参列表:方法可以声明0个,1个或多个形参。
    • 格式:数据类型 形参1 ,数据类型 形参2,…
    • 我们定义方法时该不该定义形参?
      1. 题目要求
      2. 凭经验:具体情况具体分析
  5. 方法体:方法功能的体现
  6. 方法的使用中,可以调用当前类的属性或方法
    • 特殊的:方法A中调用了方法A:递归方法。
    • 方法中:不可以定义方法。
关键字:return

return关键字:

  1. 使用范围:使用在方法体中
  2. 作用:
    1. 结束方法
    2. 针对于返回值类型的方法,使用“return 数据”方法返回所有的数据。
  3. 注意点:return关键字后面不可以声明执行语句。
方法的重载
  1. 方法的重载概念
    • 定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
    • 总结:“两同一不同”:同一个类、相同方法名;参数列表不同,参数类型不同。
  2. 举例
    public void getSum(int i,int j){
        System.out.println(1);
    }
    public void getSum(double d1,double d2){
        System.out.println(2);
    }
    public void getSum(String s,int i){
        System.out.println(3);
    }
  1. 如何判断是否构成方法的重载?
    • 严格按照定义判断:两同一不同。
    • 跟方法的权限修饰符、返回值类型、形参变量名、方法体都没关系!
  2. 如何确定类中某一个方法的调用:
    • 方法名 ----》参数列表
    • 面试题:方法的重载与重写的区别?
可变个数形参的方法
  1. 使用说明
    1. jak5.0新增的内容
    2. 具体使用:
      1. 可变个数形参的格式:数据类型 … 变量名。
      2. 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,。。。
      3. 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载。
      4. 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
      5. 可变个数形参在方法的形参中,必须声明末尾。
      6. 可变个数形参在方法的形参中,最多只能声明一个可变形参。
  2. 举例
    public void show(int i){}
    public void show(String s){
        System.out.println("show(String)");
    }
    public void show(String ... strs){
        System.out.println("show(String ... strs)");

        for (int i = 0;i < strs.length;i++){
            System.out.print(strs[i]);
        }
    }
    //不能与上一个同时存在
//    public void show(String[] strs){}

调用时
 ObjectOrientedTest test = new ObjectOrientedTest();
        test.show("hello","ad");
        test.show();
        test.show(new String[]{"AA","aa","dd"});
Java的值传递机制
  1. 针对于方法内变量的赋值举例:
    //基本数据类型
        int m = 10;
        int n = m;
        System.out.println("m=" + m + ",n=" + n);

        n = 20;
        System.out.println("m=" + m + ",n=" + n);
    //引用数据类型
        ValTest v1 = new ValTest();
        v1.valId = 1001;

        ValTest v2 = v1;//赋值以后,v1和v2的地址值相同,都指向堆空间中同一个对象实体
        System.out.println(v1.valId+","+v2.valId);
        v2.valId = 1002;
        System.out.println(v1.valId+","+v2.valId);

规则:

  • 如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
  • 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
  1. 针对于方法的参数概念
    • 形参:方法定义时,声明的小括号内的参数
    • 实参:方法调用时,实际传递给形参的数据
  2. Java中参数传递机制:值传递
    • 规则:
      • 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值
      • 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值
  3. 典型例题与内存解析
    在这里插入图片描述
    在这里插入图片描述
递归方法
  1. 定义:一个方法体内调用它自身。
  2. 如何理解递归方法?
    • 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无需循环控制。
    • 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
  3. 举例:
    public int getSum(int n){//计算1-n之间所有自然数的和
        if (n == 1){
            return 1;
        }else {
            return n + getSum(n - 1);
        }
    }

面向对象的特征一:封装性

封装与隐藏

  1. 为什么要引入封装性?
    • 我们程序设计追求 “高内聚,低耦合”。
      • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
      • 低耦合:仅对外暴露少量的方法用于使用。
    • 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把改隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。
  2. 问题引入:
    • 当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。这里,赋值操作要受到属性的数据类型和存储范围的制约。除此之外,没其他制约条件。但是,在实际问题中,我们往往需要给属性赋值加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。(比如:setLegs()同时,我们需要避免用户再使用“对象.属性”的方式对属性进行赋值。则需要将属性声明为私有的(private))。—》此时,针对于属性就体现了封装性。
  3. 封装性思想具体的代码体现:
    1. 将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值。
    private double r;
    public void setR(double r){
        this.r = r;
    }
    public double getR(){
        return r;
    }
    
    1. 不对外暴露的私有的方法。
    2. 单例模式。(将构造器私有化)
    3. 如果不希望类在包外被调用,可以将类设置为缺省的。
  4. Java规定的四种权限修饰符
    1. 权限从小到大顺序为:private 《 缺省 《 protected 《 public

    2. 具体的修饰范围:
      在这里插入图片描述

    3. 权限修饰符可用来修饰的结构说明:4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类;修饰类的话,只能使用:缺省、public。

类的结构:构造器Corstructor

  1. 构造器(或构造方法):Constructor
    • 构造器的作用:1.创造对象 ;2.初始化对象信息。
  2. 使用说明:
    1. 如果没显示的定义类的构造器的话,则系统默认提供一个空参的构造器;
    2. 定义构造器的格式:权限修饰符 类名(形参列表){};
    3. 一个类中定义的多个构造器,彼此构成重载;
    4. 一旦我们显示的定义了类的构造器之后,系统就不再提供默认的空参构造器;
    5. 一个类中,至少会有一个构造器。
  3. 举例:
    public PackageTest(){
        System.out.println(1);
    }
    public PackageTest(double n){
        r = n;
    }
    public PackageTest(double n,int a){
        r = n;
        i = a;
    }
    
属性赋值的顺序

总结:属性赋值的先后顺序:1.默认初始化;2.显示初始化;3.构造器中初始化;4.通过 “对象.方法” 或 "对象.属性"的方式,赋值。
以上操作的先后顺序:1–2–3–4 。

JavaBean的概念
  1. JavaBean是一种Java语言写成的可重用组件。
  2. 所谓JavaBean,是指符合如下标准的Java类:
    • 类是公共的
    • 有一个无参的公共构造器
    • 有属性,且有对应的get、set方法

关键字:this

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值