Java学习总结
提示:Java基础
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
Java语法基础
标识符: 用来标识类名、对象名、变量名、方法名、类型名、数组名、文件名的有效字符序列。
合法的标识符:
- 由字母、数字、下划线“_”、美元符号“$”或者“¥”组成,并且首字符不能是数字。
- 不能把java关键字和保留字作为标识符。
- 标识符对大小写敏感。
变量:程序运行期间可以被改变的量。在程序中使用变量,必须先创建它并为它取一个名字,并且指明它能够存储信息的类型,这称为“变量声明”,也叫容器的创建。
变量的使用:
- 变量的声明:数据类型 变量名;
- 变量的赋值:变量名 = 数据;
- 变量的操作:放入打印语句进行输出或者进行运算
Java 中的注释:
- 单行注释: // 注释内容
- 多行注释 :/* 注释内容 */
- 文档注释 :/** 注释内容 */
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
Java中的数据类型
Java流程控制语句
- 选择结构
if语句: if(条件表达式) { 一条或多条语句 };
if-else语句: if(条件表达式) {语句块1} else {语句块2}
if多分支语句:
switch开关语句:
- 循环结构
在程序中当要重复性的做某项工作时可以使用循环语句,包括:for循环、while循环、do…while循环。
for循环:
while循环:
do…while循环:
流程跳转语句: break,continue
- break:在switch中结束case条件判断,在循环体中结束循环
- continue:作用在循环体中,结束循环体的本次循环,而进入下次循环
数组
数组是数据的集合,一个容器,用来存储任何类型的数据,包括原始数据类型和引用数据类型,但是一旦指定了数组的类型之后,就只能用来存储指定类型的数据。
数组声明的三种方式:
- 数据类型[] 数组名 = new 数据类型[长度];
- 数据类型[] 数组名 = {数据,数据,…,数据};
- 数据类型[] 数组名 = new 数据类型长度[] {数据,数据,…,数据};
类的声明
注意:
①构造器名必须和类名一致
②构造器没有返回值类型
③任何类都含有构造器。如果没有显式地定义类的构造器,
④则系统会为该类提供一个默认的无参的构造器。一旦在类中显式地定义了构造器,系统就不会再为这个类提供默认的构造器了。
成员变量与局部变量:
- 成员变量:声明在类中方法体之外、可以有缺省值、可以使用修饰符。作用域:整个类
- 局部变量:声明在方法体或代码块中、没有缺省值、只能使用final修饰。作用域:当前方法体
方法的重载OverLoading: 同一个类中定义了多个方法名相同而参数不同的方法
重载在同一个类中,方法名相同,参数不同(参数的个数、顺序、类型不同)
关键字
this关键字:
this关键字是一种特殊的引用,指向当前对象
static关键字:
静态变量: 使用static修饰的成员变量叫做静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static成员变量的初始化顺序按照定义的顺序进行初始化。
静态方法: 使用static修饰的成员方法叫做静态方法,静态方法可以不依赖于任何对象进行访问(对于静态方法来说,是没有this的),由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
静态内部类(static 修饰类的话只能修饰内部类): 静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非 static 成员变量和方法。
静态代码块:是一个以static为前导的代码块,一般用于为类的工作做一些初始化工作,如初始化一些静态变量。一个类中可以有许多静态初始化块,并且它们可以出现在类体的任何地方。运行时系统会保证静态初始化块会按照它们在源代码中出现的顺序被调用
static块可以用来优化程序性能:因为它只会在类加载的时候执行一次
super关键字:
super代表的是父类对象,每一个子类的构造方法在没有显示调用super()系统都会提供一个默认的super(),super()必须是构造器的第一条语句
final关键字:
final 关键字,意思是最终的、不可修改的,最见不得变化 ,用来修饰类、方法和变量,具有以下特点:
修饰类: 类不能继承,final 类中的所有成员方法都会被隐式的指定为 final 方法;
修饰符变量: 该变量为常量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能让其指向另一个对象。
修饰符方法: 方法不能重写
Java访问权限修饰符
Java 三大特性
1. 封装
封装也称信息隐藏,是指利用抽象数据类型把数据和基于数据的操作封装起来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能的隐藏数据细节,只保留一些接口使其与外界发生联系。也就是说用户无需知道内部的数据和方法的具体实现细节,只需根据留在外部的接口进行操作就行。
2. 继承
继承是类与类的一种关系,比较像集合中的从属于关系。比如说,狗属于动物。就可以看成狗类继承了动物类,那么狗类就是动物类的子类(派生类),动物类就是狗类的父类(基类)。在Java中是单继承的,也就是说一个子类只有一个父类。
3. 多态
java程序中定义的引用变量所指向的具体类型和通过该引用类型发出的方法在调用时不确定,该引用变量发出的方法到底调用哪个类的实现的方法,必须在程序运行期间才能决定,这就是多态。
Java 集合学习
1.1 什么是集合
Java是面向对象的语言,我们在编程的时候自然需要存储对象的容器,数组可以满足这个需求,但是数组初始化时长度是固定的,但是我们往往需要一个长度可变化的容器,因此,集合出现了。
Java集合在java.util包中,这些集合可以看作是容器,用来存储、获取、操纵和传输具有相同性质的多个元素。
现实中的容器主要是添加对象、删除对象、清空对象等。衣柜里面的衣服,可以放入和取出,也可以有序摆放,以便快速的查找,Java集合也是如此,有些是方便插入和删除的,有些是为了方便查找数据。
1.2 集合类的继承关系
1.3 集合和数组的区别
-
长度区别:数组是静态的,一个数组实例长度不可变,一旦创建了就无法改变容量;集合是可以动态扩展容量,集合长度可变,可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求;在编写程序时不知道对象个数时,在空间不足的情况下要做到自动扩增容量,优先使用集合来实现,数组此时不适用
-
内容区别:集合不声明可存储元素类型,集合可存储不同类型元素;数组声明了它容纳的元素的类型且只可存放单一类型元素
-
元素区别:集合只能存储引用类型元素,数组可存储引用类型,也可存储基本类型
-
数组是java语言中内置的数据类型,是线性排列的,执行效率或者类型检查都是最快的。
List 接口及实现类:
- ArrayList:List继承了Collection接口,有三个实现的类,底层是数组,查询快,但是增删慢
- LinkedList:数组列表,数据采用数组方式存储,底层是链表,增删慢,但查询快
- Vect:数组列表,添加同步锁,线程安全的
ArrayList的常用方法
- add(int index, E element)
- get(int index)
- indexOf(Object o)
- lastIndexOf(Object o)
- remove(int index) 删除并返回指定位置元素
- removeRange(int fromIndex, int toIndex) 删除指定区间的元素
- set(int index, E element)
LinkedList的常用方法
- add(int index,Object element)
- addFirist(Object element)
- addLast(Object element)
- get(int index)
- removeFirst()
- removeLast()
- remove(int index)
- getFirst()
Set 接口:
Set接口继承了Collection接口。 Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的。
Set接口有两个实现类
● HashSet
HashSet类中的元素不能重复,即彼此调用equals方法比较,都返回false。
底层数据结构是哈希表+链表。
哈希表依赖于哈希值存储
● TreeSet
可以给Set集合中的元素进行指定方式的排序。存储的对象必须实现Comparable接口。
TreeSet底层数据结构是二叉树(红黑树是一种自平衡的二叉树)。
Map 接口 :
将键映射到值的对象 ,一个映射不能包含重复的键 ,每个键最多只能映射到一个值
Map接口常用方法
- V put(K key,V value)
- V remove(Object key)
- void clear()
- boolean containsKey(Object key)
- boolean containsValue(Object value)
- boolean isEmpty()
- int size()
- V get(Object key)
- Collection values()
- Set keySet()
- Set<Map.Entry<K,V>> entrySet()
IO流
IO流分类:
- 按照“流”的数据流向,可以将其化分为:输入流和输出流。
- 按照“流”中处理数据的单位,可以将其区分为:字节流和字符流。在java中,字节是占1个Byte,即8位;而字符是占2个Byte,即16位。而且,需要注意的是,java的字节是有符号类型,而字符是无符号类型!
字节流的抽象基类:
- InputStream
- OutputStream
字符流的抽象基类:
- Reader
- Writer
Writer:字符输出流
Writer是字符输出流的基类,Writer的主要方法如下:
-
Writer append(char c) 将指定的字符附加到此作者
-
Writer append(CharSequence csq) 将指定的字符序列附加到此作者
-
Writer append(CharSequence csq, int start, int end) 将指定字符序列的子序列附加到此作者
-
abstract void close() 关闭流,先刷新
-
abstract void flush() 刷新流
-
void write(char[] cbuf) 写入一个字符数组。
-
abstract void write(char[] cbuf, int off, int len) 写入字符数组的一部分
-
void write(int c) 写一个字符
-
void write(String str) 写一个字符串
-
void write(String str, int off, int len) 写一个字符串的一部分
FileWriter
FileWriter 的主要方法如下:
-
Writer append(CharSequence csq) 将指定的字符序列附加到此作者。
-
Writer append(CharSequence csq, int start, int end) 将指定字符序列的子序列附加到此作者。
-
void close() 关闭流,先刷新。
-
void flush() 刷新流。
-
String getEncoding() 返回此流使用的字符编码的名称。
-
void write(char[] cbuf, int off, int len) 写入字符数组的一部分。
-
void write(int c) 写一个字符
-
void write(String str, int off, int len) 写一个字符串的一部分。
BufferedWriter
BufferedWriter 是缓冲字符输出流。它继承于Writer。
BufferedWriter 的作用是为其他字符输出流添加一些缓冲功能,使用BufferedWriter可以提高我们写入文件的效率。
BufferedWriter的方法列表:
-
void close() 关闭流,先刷新。
-
void flush() 刷新流。
-
void newLine() 写一行行分隔符。
-
void write(char[] cbuf, int off, int len) 写入字符数组的一部分。
-
void write(int c) 写一个字符
-
void write(String s, int off, int len) 写一个字符串的一部分。
FilterWriter
FilterWriter是字符类型的过滤输出流。
FilterWriter的方法列表:
-
void close() 关闭流,先刷新。
-
void flush() 刷新流。
-
void write(char[] cbuf, int off, int len) 写入字符数组的一部分。
-
void write(int c) 写一个字符
-
void write(String str, int off, int len) 写一个字符串的一部分。
Reader:字符输入流
Reader是字符输入流的基类,Reader的方法列表如下:
-
abstract void close() 关闭流并释放与之相关联的任何系统资源。
-
void mark(int readAheadLimit) 标记流中的当前位置。
-
boolean markSupported() 告诉这个流是否支持mark()操作。
-
int read() 读一个字符
-
int read(char[] cbuf) 将字符读入数组。
-
abstract int read(char[] cbuf, int off, int len) 将字符读入数组的一部分。
-
int read(CharBuffer target) 尝试将字符读入指定的字符缓冲区。
-
boolean ready() 告诉这个流是否准备好被读取。
-
void reset() 重置流。
-
long skip(long n) 跳过字符
FileReader
FileReader的构造方法:
-
FileReader(File file) 创建一个新的 FileReader ,给出 File读取。
-
FileReader(FileDescriptor fd) 创建一个新的 FileReader ,给予 FileDescriptor从中读取。
-
FileReader(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。
BufferedReader
BufferedReader的方法列表:
-
void close() 关闭流并释放与之相关联的任何系统资源。
-
Stream lines() 返回一个 Stream ,其元素是从这个 BufferedReader读取的行。
-
void mark(int readAheadLimit) 标记流中的当前位置。
-
boolean markSupported() 告诉这个流是否支持mark()操作。
-
int read() 读一个字符
-
int read(char[] cbuf, int off, int len) 将字符读入数组的一部分。
-
String readLine() 读一行文字。
-
boolean ready() 告诉这个流是否准备好被读取。
-
void reset() 将流重置为最近的标记。
-
long skip(long n) 跳过字符
InputStream字节输入流
InputStream类是字节输入流的抽象类,是所有字节输入流的父类,InputStream类具有层次结构如下图所示:
InputStream的常用方法:
-
int available() 从下一次调用此输入流的方法返回可从该输入流读取(或跳过)的字节数,而不会阻塞。
-
void close() 关闭此输入流并释放与流相关联的任何系统资源。
-
void mark(int readlimit) 标记此输入流中的当前位置。
-
boolean markSupported() 测试此输入流是否支持 mark和 reset方法。
-
abstract int read() 从输入流读取数据的下一个字节。
-
int read(byte[] b) 从输入流中读取一些字节数,并将它们存储到缓冲器阵列 b 。
-
int read(byte[] b, int off, int len) 从输入流读取最多 len个字节的数据到字节数组。
-
byte[] readAllBytes() 从输入流读取所有剩余字节。
-
int readNBytes(byte[] b, int off, int len) 将所请求的字节数从输入流读入给定的字节数组。
-
void reset() 将此流重新定位到最后在此输入流上调用 mark方法时的位置。
-
long skip(long n) 跳过并丢弃来自此输入流的 n字节的数据。
-
long transferTo(OutputStream out) 从该输入流中读取所有字节,并按读取的顺序将字节写入给定的输出流。
FileInputStream
FileInputStream 的方法列表
-
int available() 返回从此输入流中可以读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
-
void close() 关闭此文件输入流并释放与流相关联的任何系统资源。
-
protected void finalize() 已过时。
-
finalize方法已被弃用。 为了执行清理而覆盖finalize子类应该修改为使用替代清理机制,并删除覆盖的finalize方法。 当覆盖finalize方法时,其实现必须明确确保按照super.finalize()所述调用super.finalize() 。 有关迁移选项的更多信息,请参阅Object.finalize()的规范。
-
FileChannel getChannel() 返回与此文件输入流相关联的唯一的FileChannel对象。
-
FileDescriptor getFD() 返回表示与此 FileInputStream正在使用的文件系统中的实际文件的连接的 FileDescriptor对象。
-
int read() 从该输入流读取一个字节的数据。
-
int read(byte[] b) 从该输入流读取最多 b.length个字节的数据到一个字节数组。
-
int read(byte[] b, int off, int len) 从该输入流读取最多 len个字节的数据到字节数组。
-
long skip(long n) 跳过并从输入流中丢弃 n字节的数据。
OutputStream 字节输出流
OutputStream字节输出流的方法:
-
void close() 关闭此输出流并释放与此流相关联的任何系统资源。
-
void flush() 刷新此输出流并强制任何缓冲的输出字节被写出。
-
void write(byte[] b) 将 b.length字节从指定的字节数组写入此输出流。
-
void write(byte[] b, int off, int len) 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
-
abstract void write(int b) 将指定的字节写入此输出流。
FileOutPutStream
FileOutPutStream 的方法列表:
-
void close() 关闭此文件输出流并释放与此流相关联的任何系统资源。
-
protected void finalize() 已过时。
-
finalize方法已被弃用。 为了执行清理,覆盖finalize子类应被修改为使用替代的清理机制,并删除覆盖的finalize方法。 当覆盖finalize方法时,其实现必须明确确保按照super.finalize()中所述调用super.finalize() 。 有关迁移选项的更多信息,请参阅Object.finalize()的规范。
-
FileChannel getChannel() 返回与此文件输出流相关联的唯一的FileChannel对象。
-
FileDescriptor getFD() 返回与此流相关联的文件描述符。
-
void write(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流。
-
void write(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。
-
void write(int b) 将指定的字节写入此文件输出流。
File
JavaIo流中还有一个非常常用的类:File。
File 是“文件”和“目录路径名”的抽象表示形式。
File 直接继承于Object,实现了Serializable接口和Comparable接口。实现Serializable接口,意味着File对象支持序列化操作。而实现Comparable接口,意味着File对象之间可以比较大小;File能直接被存储在有序集合(如TreeSet、TreeMap中)。
File的构造方法:
-
File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例。
-
File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
-
File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。
-
File(URI uri) 通过将给定的 file: URI转换为抽象路径名来创建新的 File实例。
MySQL数据库知识点
1、什么是MySQL:
MySQL 是⼀种关系型数据库,在 Java 企业级开发中⾮常常⽤,因为 MySQL 是开源免费的,并
且⽅便扩展。阿⾥巴巴数据库系统也⼤量⽤到了 MySQL ,因此它的稳定性是有保障的。 MySQL
是开放源代码的,因此任何⼈都可以在 GPL(General Public License) 的许可下下载并根据个性
化的需要对其进⾏修改。 MySQL 的默认端⼝号是 3306 。
2、为什么要使用数据库:
- 因为MySQL数据库将数据保存在文件中,可以永久保存;
- 使用SQL语句,查询方便效率高;
- 使用MySQL数据库管理数据方便。
3、SQL语句的分类:
- 数据定义语言DDL(Data Ddefinition Language):CREATE,DROP,ALTER 主要为以上操作即对逻辑结构等有操作的,其中包括表结构,视图和索引。
- 数据查询语言DQL(Data Query Language):SELECT 这个较为好理解 即查询操作,以select关键字。各种简单查询,连接查询等 都属于DQL。
- 数据操纵语言DML(Data Manipulation Language):INSERT,UPDATE, DELETE 主要为以上操作 即对数据进行操作的,对应上面所说的查询操作 DQL与DML共同构建了多数初级程序员常用的增删改查操作。而查询是较为特殊的一种 被划分到DQL中。
- 数据控制功能DCL(Data Control Language):GRANT,REVOKE,COMMIT,ROLLBACK 主要为以上操作 即对数据库安全性完整性等有操作的,可以简单的理解为权限控制等。
4、SQL常见约束
- NOT NULL: 用于控制字段的内容一定不能为空(NULL)。
- UNIQUE: 控件字段内容不能重复,一个表允许有多个 Unique 约束。
- PRIMARY KEY: 也是用于控件字段内容不能重复,但它在一个表只允许出现一个。
- FOREIGN KEY: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
SpringBoot框架 知识点
- 什么是SpringBoot
springboot 是 spring 快速开发脚手架,通过约定大于配置的方式,快速构建和启动 spring 项目.
springboot根据我们项目中所引入的依赖,比如引入了springmvc构件,就会判断出是要进行springmvc的web开发,就会把springmvc的相关基本配置自动配置好了,不需要我们在xml中配置。 比如配置前端控制器DispatcherServlet、配置视图解析器、配置静态资源访问、处理器映射器、处理器适配器等一系列组件,
- SpringBoot解决了哪些痛点
1、复杂的配置
项目各种配置是开发时的损耗, 写配置挤占了写应用程序逻辑的时间。
2、混乱的依赖管理
项目的依赖管理非常的繁琐。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这是一个棘手的问题。并且,一旦选错了依赖的版本,随之而来的就是各种的不兼容的bug
常用注解:
- @SpringBootApplication:申明让spring boot自动给程序进行必要的配置,包含@Configuration、@EnableAutoConfiguration、@ComponentScan通常用在主类上。
- @Component、@Service、@Controller、@Repository:这几个注解放在一起是因为功能基本一样的,都是将类注入到spring容器中,只不过它们使用的场景不同,被@Component,@Service,@Controller,@Repository注解标注的类,这些类会被纳入进spring容器中管理。
- @RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。
- @RestController:用于标注控制层组件,@ResponseBody和@Controller的合集。
- @AutoWired、@Qualifier、@Resource:这3个注解都是基于注解方式进行自动装配,在容器里面将查找到的bean返回,一般@AutoWired用得最多,@Qualifier则需要配合@AutoWired使用,@Resource则是可以通过名字进行自动装配
- @GetMapping:与@RequestMapping功能类似的,只是这个限定了只能是Get请求
- @PostMapping:与@RequestMapping功能类似的,只是这个限定了只能是Post请求
- @Value:用于获取bean的属性,一般用于读取配置文件的数据,作用在变量上
- @Configuration:作用于类上面,表明这是一个配置类,@Bean产生一个Bean对象加入Spring IOC容器。
- @PathVariable:该注解主要用于获取路径参数,像url/{id}/{name}这种形式的参数都可以,get获取post请求均可
SpringMVC 的执行流程
SpringMVC 常用组件
- DispatcherServlet
是一种前端控制器,由框架提供。
作用:统一处理请求和响应。除此之外还是整个流程控制的中心,由 DispatcherServlet 来调用其他组件,处理用户的请求
- HandlerMapping
处理器映射器,由框架提供。
作用:根据请求的 url、method 等信息来查找具体的 Handler(一般来讲是Controller)
- Controller
处理器,注意,这个需由工程师自己开发。
作用:在 DispatcherServlet 的控制下,Handler对具体的用户请求进行处理
- HandlerAdapter
处理器适配器 ,由框架提供。
作用:根据映射器找到的处理器 Handler 信息,按照特定的规则去执行相关的处理器 Handler。
- ViewResolver
视图解析器,由框架提供。
作用: ViewResolver 负责将处理结果生成 View 视图。 ViewResolver 首先根据逻辑视图名解析成物理图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
- View
视图,工程师自己开发
作用:View接口的职责就是接收model对象、Request对象、Response对象,并渲染输出结果给Response对象。
具体的流程:
- 用户通过浏览器发起 HttpRequest 请求到前端控制器 (DispatcherServlet)。
- DispatcherServlet 将用户请求发送给处理器映射器 (HandlerMapping)。
- 处理器映射器 (HandlerMapping)会根据请求,找到负责处理该请求的处理器,并将其封装为处理器执行链 返回 (HandlerExecutionChain) 给 DispatcherServlet
- DispatcherServlet 会根据 处理器执行链 中的处理器,找到能够执行该处理器的处理器适配器(HandlerAdaptor) --注,处理器适配器有多个
- 处理器适配器 (HandlerAdaptoer) 会调用对应的具体的 Controller
- Controller 将处理结果及要跳转的视图封装到一个对象 ModelAndView 中并将其返回给处理器适配器 (HandlerAdaptor)
- HandlerAdaptor 直接将 ModelAndView 交给 DispatcherServlet ,至此,业务处理完毕
- 业务处理完毕后,我们需要将处理结果展示给用户。于是DisptcherServlet 调用 ViewResolver,将 ModelAndView 中的视图名称封装为视图对象
- ViewResolver 将封装好的视图 (View) 对象返回给 DIspatcherServlet
- DispatcherServlet 调用视图对象,让其自己 (View) 进行渲染(将模型数据填充至视图中),形成响应对象 (HttpResponse)
- 前端控制器 (DispatcherServlet) 响应 (HttpResponse) 给浏览器,展示在页面上。