JavaSE基础(一)

JavaSE

本文是对宋老师以及Java编程的逻辑总结形成的JavaSE基础笔记,分成Java基础核心、面向对象、泛型与容器、文件、并发以及动态与函数式编程六大模块。

一、Java基础核心

第1章 Java语言概述

1 Java基础知识图解

1.1 JavaSE框架

  • Java基础核心:基础语法、数组、分支
  • Java面向对象核心:OPP、封装、继承、多态、异常、API
  • Java泛型与容器:泛型、Collection、
  • 文件处理
  • 并发操作
  • 动态与函数式编程:反射、注解、动态代理

在这里插入图片描述

2 Java语言概述

主要包括Java的技术体系、应用领域、主要特性、核心机制以及Java环境

2.1 Java技术体系

  • Java SE标准版
  • Java EE企业版
  • Java ME小型版
  • Java Card

2.2 Java应用领域

  • 企业级应用
  • Android平台应用
  • 大数据平台开发

2.3 Java主要特性

  • 面向对象:提供类、接口和继承等原语
  • 分布式的:网络应用编程接口
  • 健壮性:内存管理和访问机制
  • 安全的:安全防范机制
  • 跨平台性:JVM

2.4 核心机制:

  • Java虚拟机(Java Virtal machine)

在这里插入图片描述

  • 垃圾收集机制(Carbage Collection)

2.5 Java环境

  • JDK:Java开发工具包

  • JRE:Java运行环境

  • JVM:Java虚拟机

在这里插入图片描述

3 Hello World

/**
 *	1.编写:HelloWorld.java
 *	2.编译:Javac HelloWorld.java
 *	3.运行:java HelloWorld
 */
public class HelloWorld {
    public static void main(String[] args){
         System.out.println("Hello World");
    }
}

4 软件开发及语言介绍

(1)软件开发:

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

(2)人机交互方式:

图形化界面、命令行方式

(3)常用DOS命令

dir : 列出当前目录下的文件以及文件夹
md : 创建目录
rd : 删除目录
cd : 进入指定目录
cd.. : 退回到上一级目录
cd\: 退回到根目录
del : 删除文件
exit : 退出 dos 命令行
 补充:echo javase>1.doc

(4)计算机编程语言:

人与计算机交流的方式。

  • 第一代语言:机器语言。指令以二进制存在。

  • 第二代语言:汇编语言。助记符表示一条机器指令。

  • 第三代语言:高级语言。Java跨平台纯面向对象的语言。

5 数据背后的二进制

5.1 进制

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

(1) 数据存储的单位:

  • 位:bit 最小的单元
  • 字节:byte 机器语言的单位:1byte=8bits

(2) 进制:

  • 二进制(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不区分大小写。

5.2 二进制

Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位。

(1)二进制的整数表现形式:

  • 原码:直接将一个数值换成二进制数。最高位是符号位
  • 负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。
  • 负数的补码:其反码加1。

(2)计算机以二进制补码的形式保存所有的整数。

  • 正数的原码、反码、补码都相同
  • 负数的补码是其反码

6 字符与编码

6.1 字符相关概念

  • 字符:是各种文字和符号的总称
  • 字符集:字符集是多个符号的集合,每个字符集包含的字符个数不同。
  • 字符编码:字符集只是规定了有哪些字符,采用哪些字符,每一个字符用多少字节表示等问题,则是由编码来决定的

6.2 常见字符编码:

​ Unicode编码给世界所有字符分配了唯一数字编号,并未规定二进制表示。

  • Unicode编码:UTF-32、UTF-16
  • 非Unicode编码:ASCII、ISO、GB2312

6.3 Unicode编码

Unicode编码给世界上所有的字符都分配了一个唯一的数字编码,并未规定其二进制表示。编号对应二进制表示主要有UTF-32、UTF-16、UTF-8

(1)二进制表示

  • UTF-32:即字符编号是整数二进制形式,4个字节
  • UTF-16:使用变长字节。
  • UTF-8:使用变长字节,unicode编号小的使用字节少,编号大的使用字节多。

UTF-8编号范围对应的二进制格式

在这里插入图片描述

(2)小结

Unicode给世界所有字符都规定了一个统一的编号,并未规定编号对应的二进制形式。

UTF-32、UTF-16、UTF-8均是将Unicode编号对应到二进制格式,但只有UTF-8兼容ASCII

6.4 非Unicode编码

常见的非Unicode编码包括ASCII、ISO、GB2312、GBK等。

  • ASCII码全称为美国信息互换标准代码。
  • GB2312固定两个字节表示汉字,针对简体中文常见字符。
  • GBK则是在GBK2312的基础上,向下兼容GBK2312,

ASCII是基础,使用一个字节表示,最高位为0,其他七位表示128个字符。其他编码兼容ASCII,最高位使用1来进行区分。

6.5 编码转换

有了Unicode之后,每一个字符有多种不同的编码格式,不同的编码格式可以通过Unicode编号进行编码转换。

字符A编码到B编码:A编码通过A编码映射表找到字符对应的Unicode编号,通过字符Unicode编号查询B的映射表,找到其编码格式。

乱码有两种常见原因“:第一种是简单的解析错误,第二种是在错误解析的基础上进行编码转换。

恢复乱码常见方法:

public static void recover(String str) 
    throws UnsupportedEncodingException {
    String[] Charsets = new String[]{"windows-1252","GB18030","Big5","UTF-8"};
    for (int i = 0; i < Charsets.length; i++) {
        for (int j = 0;  j< Charsets.length; j++) {
            if (i!=j){
                String s = new String(str.getBytes(Charsets[i]),Charsets[j]);
                System.out.println("原来编码假设是(A):"+Charsets[j]);
                System.out.println("被错误解读成(B):"+Charsets[i]);
                System.out.println(s);
            }
        }
    }
}

第2章 基本语法

1 注释

Java注释分为单行注释、多行注释以及Java特有的文档注释。

1.1 单行注释

 //注释文字

1 .2 多行注释

/* 注释文字 */ 

1.3 文档注释(Java特有)

/**
  @author 指定java程序的作者
  @version 指定源文件的版本
*/

注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形

式体现的该程序的说明文档

2 标识符

2.1 关键字

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

特点:字母均小写。

分类:数据类型、流程控制、访问权限、类有关、异常处理、包、修饰符

2.2 保留字

现有Java版本尚未使用,但以后版本可能会作为关键字使用。goto 、const

2.3 标识符

Java 对各种变量方法等要素命名时使用的字符序列称为标识符.

命名规范:

  • 包名:多单词组成时所有字母都小写
  • 类名、接口名:多单词组成时,所有单词的首字母大写:
  • 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写
  • 常量名:所有字母都大写。多单词时每个单词用下划线连接:

3 变量

3.1 变量

(1)概念

  • 内存中的一个存储区域,数据可在同一类型中不断变化。
  • 是程序中最基本的存储单元,包含变量类型、变量名和存储的值。
  • 变量可以理解为给数据起名,方便寻找不同数据,值变含义不变。
  • 作用:用于在内存中保存数据

(2)注意事项

  • Java中每个变量必须先声明,后使用。
  • 使用变量名来访问这块区域的数据。
  • 变量的作用域,在定义的{}中才有效

(3)变量的声明与赋值

  • 声明:<数据类型> <变量名称>

  • 声明并赋值: <数据类型> <变量名> = <初始化值>

3.2 按数据类型分类

数据类型用于对数据的归类,以便于理解和操作。每一种数据类型在内存分配不同大小的空间。

在这里插入图片描述

(1)基本数据类型:

  • 整数类型:4种整型,byte/short/int/long
  • 小数类型:2种类型float/double
  • 字符类型:char,表示单个字符。本质是固定两个字节的无符号整数。
  • 真假类型:boolean

(2)引用数据类型

  • 类(class)
  • 接口(interface)
  • 数组([])
  • 字符串(String)
3.3 按声明位置分类

可根据方法与类体内可分为成员变量与局部变量。

在这里插入图片描述

3.4 数据类型转化

数据类型转换包括自动类型转换与强制类型转换。

(1)自动类型转换

在这里插入图片描述

  • 多种数据类型混合运算,系统会将所有数据转换成容量最大的数据类型
  • byte,short,char之间不会相互转换,它们运算时会转换为int类型。
  • 任何基本数据类型与String类型进行连接运算(+),均会自动转换string类型。
  • String属于引用数据类型,可以串接自身以及其他类型数据。

(2)强制类型转换

强制类型转换是将容量大的类型转换为容量小的类型。是自动类型转换的逆过程。

  • 使用时需要加上强制转换符:(),可能会造成精度降低或者溢出
  • 通常,字符串类型不会转换为基本类型,通过包装类可以把对应字符串转换为基本类型。
  • boolean类型不能转换为其它的数据类型

4 运算符

运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。 一般有算术运算符、赋值运算符、比较运算符(关系运算符)、逻辑运算符、位运算符和三元运算符。运算符是有不同优先级的。

4.1 算数运算

算术运算符有加、减、乘、除,符号分别是+、-、*、/,另外还有取模运算符%,以及自增(++)和自减(–)运算符。

在这里插入图片描述

注意:

  • 取模适用于所有数值类型和字符类型。负数取模忽略负号
  • 加、减、乘、除注意结果的范围
  • 小数计算结果不精确
  • “+”除字符串相加功能外,还能把非字符串转换成字符串.
4.2 赋值运算符

赋值运算符有=、+=、 -=、 *=、 /=、%=

注意:

  • 当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理。
  • 支持连续赋值。
4.3 比较运算

比较运算就是计算两个值之间的关系,结果是一个布尔类型(boolean)的值。

在这里插入图片描述

4.4 逻辑运算

逻辑运算包括逻辑与 、逻辑或 、逻辑非、短路与 、短路或 、逻辑异或。

在这里插入图片描述

(1)“&”和“&&”的区别:

  • 单&时,左边无论真假,右边都进行运算;
  • 双&时,如果左边为真,右边参与运算,如果左边为假,那么右边不参与运算。

(2) “|”和“||”的区别

  • 同理,||表示:当左边为真,右边不参与运算

(3)异或( ^ )与或( | )区别:

  • 异或当左右都为true时,结果为false。
  • 理解:异或,追求的是“异”!
4.5 位运算

(1)位运算符

在这里插入图片描述

(2)位运算符细节

在这里插入图片描述

4.6 三元运算符

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

条件表达式为true时,采用表达式1,否则采用表达式2.

5 程序流程控制

流程控制主要有两种,一种是条件控制,一种是循环执行。

5.1 顺序结构

程序从上到下逐行地执行,中间没有任何判断和跳转。

Java中定义成员变量时采用合法的前向引用。

public class Test{
int num1 = 12;
int num2 = num1 + 2;
}
5.2 分支结构

根据条件,选择性地执行某段代码。有if…else和switch-case两种分支语句。

(1)if-else结构

if-else具有三种结构

//满足单个条件
if(条件语句){
    //代码块
}
//满足与不满足条件执行逻辑不同
if(条件语句){
	//代码块1
}else{
    //代码块2
}

//三元运算符
//判断条件 ?  表达式1 : 表达式2
//多个判断条件
if(条件表达式1){
	//代码块1;
}
else if (条件表达式2){
	//代码块2;
}
……
else{
	//代码块n;
}

(2)switch-case结构

switch(表达式){
case 常量1:
	 语句1;
	// break;
case 常量2:
	语句2;
	// break; … …
case 常量N:
	 语句N;
 	// break;
default:
	语句;
	// break;
}

细节

  • switch(表达式)中表达式的值类型必须是:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0);
  • case子句中的值必须是常量
  • break语句用来在执行完一个case分支后使程序跳出switch语句块
  • default子句是可任选的
5.3 循环结构

根据循环条件,重复性的执行某段代码。有while、do…while、for三种循环语句。JDK1.5提供了foreach循环,方便的遍历集合、数组元素。

(1)循环语句组成部分

​ 循环语句的四个组成部分

  • 初始化部分(init_statement)

  • 循环条件部分(test_exp)

  • 循环体部分(body_statement)

  • 迭代部分(alter_statement)

(2)循环1:for循环

  • 在for中,每条语句都是可以为空的
for (①初始化部分; ②循环条件部分; ④迭代部分){
	③循环体部分;
}
//执行顺序:1-2-3-4-2-3-4...

(3)循环2:while循环

①初始化部分
while(②循环条件部分){
	③循环体部分; 
	④迭代部分; 
}
//执行顺序:1-2-3-4-2-3-4...

(4)循环3:do-while循环

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

①初始化部分;
do{
	③循环体部分
	④迭代部分
}while(②循环条件部分);
//执行顺序:1-2-3-4-2-3-4...

(5)循环4:foreach

/**
 * element一般每次会自动更新
 */
int[] arr = {1,2,3,4};for(int element : arr){
     System.out.println(element);
}

(6)循环控制

​ 特殊关键字:break、continue、return

特殊流程控制语句1:break

  • break只能用于switch语句和循环语句
  • break是终止本层循环。
//break语句用于终止某个语句块的执行
{ 	……
	break;
	……
}
//break语句出现在多层嵌套的语句块中时,通过标签设置
label1: { ……
label2: 	{ ……
label3: 		{ ……
				break label2;
				……
                } 
            } 
        }

特殊流程控制语句2:continue:

  • continue只能使用在循环结构
  • continue是终止本次循环。
  • continue语句用于跳过其所在循环语句块的一次执行,继续下一次循环
  • continue语句出现在多层嵌套的循环语句体中时,可以使用标签
//单层循环语句
for (int i = 0; i < 100; i++) {
	if (i%10==0)
	continue;
	System.out.println(i); 
}

特殊流程控制语句3:return:

  • retun并非结束循环体,而是结束方法。

第3章 数组

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

1 数组概述

数组就是存储数据长度固定的容器,存储多个数据类型要一致

1.1 数组常见概念

  • 数组名
  • 下标(或索引)
  • 元素
  • 数组的长度

1.2 数组特性

  • 数组是引用数据类型,而数组中的元素可以是任何数据类型
  • 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
  • 我们可以通过下标访问指定位置的元素
  • 数组长度一旦确定,就不能修改

1.3 数组的分类

  • 按照维度:一维数组、二维数组、三维数组…
  • 按照元素数据类型:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)

2 一维数组

2.1 声明

//第一种:数据类型[] 数组名
int[] arr;

//第二种:数据类型 数组名[]
int arr[]

2.2 初始化

动态初始化:

//动态初始化:数组声明且为数组元素分配空间与赋值的操作分开进行
int[] arr = new int[3];
arr[0] = 3;
arr[1] = 9;
arr[2] = 8;

静态初始化:

//静态初始化:在定义数组的同时就为数组元素分配空间并赋值。
int arr[] = new int[]{ 3, 9, 8};
int[] arr = {3,9,8};

2.3 数组元素的引用

  • 定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;
  • 数组元素的引用方式:数组名[数组元素下标]
  • 每个数组都有一个属性length指明它的长度,数组一旦初始化,其长度是不可变的

2.4 数组元素的默认初始化值

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

在这里插入图片描述

注意:

  • 对于基本数据类型而言,默认初始化值各有不同
  • 对于引用数据类型而言,默认初始化值为null(注意与0不同!)

3 多维数组

多维数组可以理解为一维数组中每个元素还可以是一个数组。从数组底层运行机制来说多维数组并不存在,

3.1 初始化

动态初始化:

/**
 *	格式1(动态初始化):
 *		1.定义了名称为arr的二维数组
 *		2.二维数组中有3个一维数组
 *		3.每一个一维数组中有2个元素
 */
int[][] arr = new int[3][2];

/**
 *	格式2(动态初始化)
 *		1.二维数组中有3个一维数组。
 *		2.每个一维数组都是默认初始化值null 
 *		3.可以对这个三个一维数组分别进行初始化
 */
int[][] arr = new int[3][];

静态初始化:

//格式3(静态初始化):
int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};

注意特殊写法情况

  • int[] x,y[]; x是一维数组,y是二维数组。
  • Java中多维数组不必都是规则矩阵形式

4 常见算法

4.1 二分查找

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wAYjxQtI-1657707944906)(img/3.4_2.png)]

4.2 排序

(1)概述

排序:

  • 假设含有n个记录的序列为{R1,R2,…,Rn},其相应的关键字序列为{K1,K2,…,Kn}。将这些记录重新排序为{Ri1,Ri2,…,Rin},使得相应的关键字值满足条Ki1<=Ki2<=…<=Kin,这样的一种操作称为排序。

衡量排序算法的优劣:

  • 1.时间复杂度:分析关键字的比较次数和记录的移动次数

  • 2.空间复杂度:分析排序算法中需要多少辅助内存

  • 3.稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的

(2)分类

排序算法分类:内部排序和外部排序。

**内部排序:**所有排序操作均在内存中完成

- **选择排序:**直接选择排序、堆排序
- 交换排序:冒泡排序、快速排序
- **插入排序:**直接插入排序、折半插入排序、Shell排序
  • 归并排序
  • 桶式排序
  • 基数排序

**外部排序:**数据量多,需要用到外部存储器,可以认为外部排序是由多次内部排序组成

(3)算法5大特征

在这里插入图片描述

(4)冒泡排序

​ 冒泡排序的原理非常简单,它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

  • 1.比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。

  • 2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

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

  • 4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较为止。

(5)快速排序

快速排序通常明显比同为O(nlogn)的其他算法更快,因此常被采用,快排采用了分治法的思想。

  • 1.从数列中挑出一个元素,称为"基准"(pivot)
  • 2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  • 3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
  • 4.递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。

(6)内部排序性能

  • 1.从平均时间而言:快速排序最佳。但在最坏情况下时间性能不如堆排序和归并排序。

  • 2.从算法简单性看:由于直接选择排序、直接插入排序和冒泡排序的算法比较简单,将其认为是简单算法。对于Shell排序、堆排序、快速排序和归并排序算法,其算法比较复杂,认为是复杂排序。

  • 3.从稳定性看:直接插入排序、冒泡排序和归并排序时稳定的;而直接选择排序、快速排序、 Shell排序和堆排序是不稳定排序

  • 4.从待排序的记录数n的大小看,n较小时,宜采用简单排序;而n较大时宜采用改进排序。

(7)排序算法的选择

  • 若n较小(如n≤50),可采用直接插入直接选择排序
  • 若文件初始状态基本有序(指正序),则应选用直接插入冒泡或随机的快速排序为宜;
  • 若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序堆排序归并排序

5 Arrays

​ Java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。


boolean equals(int[] a,int[] b) //判断两个数组是否相等。
String toString(int[] a) //输出数组信息。
void fill(int[] a,int val) //将指定值填充到数组之中

void sort(int[] a) //对数组进行排序。
int binarySearch(int[] a,int key) //对排序后的数组进行二分法检索指定的值。

6 Java中常见异常

  • 数组脚标越界异常(ArrayIndexOutOfBoundsException)
  • 空指针异常(NullPointerException)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值