JAVA学习

Java入门环境搭建

什么是程序

像一个汉字(设计语言)写的红烧肉菜谱(程序),用于指导懂汉字的人来做菜

Win10常用dos操作命令

  • md(make directory): 创建目录
  • rd(remove directory): 删除目录
  • cd空格(change directory): 进入指定目录
  • cd… : 退回到上一级目录
  • cd \ : 退回到根目录
  • exit : 退出dos 命令行
  • Shift+右键->在此处打开命令行窗口**

java的发展历史

  • 1991年,高司令green Oak(橡树)跨平台
  • 1995年,推出了java测试版
  • 1996年.Jdk1.0
  • 1997年jdk 1.1
  • 1998年jdk1.2,被大量的人所使用
  • 2004年,jdk1.5
  • 2006年,jdk1.6
  • 2011年,jdk1.7
  • 2014年jdk1.8企业用的比较多
  • 2018年3月java 10
  • 2018年9月java11
  • 2019年3月java12
  • 2019年9月java13
  • 2020年3月java14

java分支

  1. JavaMe:已经被淘汰,主要去做移动端
  2. JavaSe:java基础,JavaEE的基石,控制台项目,桌面应用程序
  3. JavaEE:企业级应用项目

java语言的特点:

  1. 简单易用
  2. 跨平台性 引入了虚拟机(JVM)的概念,通过JVM可以实现在不同操作系统上运行java程序,每个操作系统都有自己的虚拟机
  3. 面向对象性
  4. 支持多线程

java两大核心机制

  1. java虚拟机
    - JVM是一个虚拟的计算机,具有指令集并使用不同的存储区 域。负责执行指令、管理数据、内存、寄存器
    - JVM用于运行java应用程序
    - 对于不同的操作系统,有不同的虚拟机
    - java虚拟机机制屏蔽了底层运行平台的差别,实现了“一次编译,到处运行”
  2. 垃圾回收机制
    - java不需要程序员负责回收无用的内存

JDK

  1. JDK:java开发工具包,就相当于一个电工的工具包
  2. JRE:java运行环境,开发好的java程序需要通过JRE去运行,包含java程序的API(核心类库)

java编写规则

  1. 类名必须与文件名一致
  2. 一个Java文件中可以定义多个类,但是只能有一个public类
  3. JAVA语言严格区分大小写
  4. 大括号是成对出现的,缺一不可
  5. main方法是java程序的入口,需要执行的代码必须放到main方法里面
  6. 每个语句以分号结束

注释:单行注释(//) 多行注释(/***/)

java基础语法

关键字

java语言定义的特殊的单词,每个关键字都有自己独有的功能,全是小写

标识符

自己定义的类、方法名、包名、变量名、接口名、、、这些都是标识符
注意事项:

  1. 必须由字母、数字、$组成
  2. 不能以数字开头,不能是关键字,中间不能有空格
  3. 不能包含特殊字符
  4. 定义方法名和变量名首字母小写,如果定义常量,全部大写

变量

定义:在内容中的一块区域,变量的值可以在某一个范围内发生改变

变量的类型:

  1. 按被声明的位置:
    - 成员变量:方法外部、类内部
    - 局部变量:方法内部
  2. 按所属的数据类型:
    - 基本数据类型
    - 引用数据类型

基本数据类型

八种基本数据类型:byte、short、int、long、float、double、boolean、char

类型转换

  1. 自动类型转换,把小的放到大的里面
  2. 强制类型转换,把大的放到小的里面
  3. 把字符串类型转换成其他类型
    每个基本数据类型都有自己对应的包装类,每个包装类中都封装了对应的转换方法,转成什么类型就去到其对应的类里面的方法

运算符

逻辑运算符、算术运算符、位运算符、比较运算符、条件运算符、赋值运算符

顺序结构及条件结构

顺序结构

按照代码的书写顺序,从上往下依次执行

键盘输入数据:

  1. 导入java.util.Scanner包
  2. 创建对象
  3. 接受数据

分支语句

分类:if语句和switch语句

if语句分类

if语句:满足if里面的条件表达式就执行代码块里的代码
if…else语句:如果满足if里面的条件表达式就执行if代码块里的代码,否则执行else里面的代码
if…else,if…else语句:多重判断,先对if语句里的条件表达式进行判断,如果不满足,之后对下面的条件表达式进行判断,直到能够满足条件的,然后去执行其代码里的代码,这一组语句,只能有一个语句执行

switch语句

  • case后面都是常量
  • break:可以选、如果case里面没有break,会继续执行下一个case,直到遇到break停止
  • case 后面的常量是可选的
  • default 可选,如果添加,没有条件表达式中对应的case,则执行default

switch和if的区别

  1. if会一步一步执行表达式的判断,switch根据表达式直接去找对应的case,因为case后面的常量不能进行判断,效率高
  2. if:常用于区间判断;switch:常用于等值判断

while和都do…while

循环:通过循环语句返回执行同一个操作

while和do…while的区别:

  1. while:先判断在执行
  2. do…while:先执行一遍循环体里的内容再进行判断

循环由循环条件和循环操作组成

for循环

三个表达式:初始化表达式,循环条件表达式,累加器

for循环的优点:是代码更容易阅读,循环次数固定的条件

break:一旦执行,立即结束当前循环,只能用于switch语句和循环语句中
continue:跳过此次循环,继续执行下一次循环,只能用于循环语句中

数组

数组是一个容器,它可以存放多个值;数组和变量差不多,都是存放数据的,不同的变量只能保存一条数据,而数组可以保存多条数组,前提这个多条数据必须是同一类型的,数组是引用数据类型

如何定义一个数组

数组类型【】 数组名;
如果定义好数组之后,必须给数组进行初始化
数组是一个引用数据类型

数组的初始化

动态初始化

  • 数组类型【】 数组名 = new 数组类型【数组长度】
  • 数据类型【】 数组名;
    数组名 = new 数组类型【数组长度】;

静态初始化

不是指定数组长度,在定义数组的同时对数组进行赋值

  • 数组类型 【】 数组名 = new 数组类型【】{数据1,数据2…};
  • 数组类型 【】 数组名;
    数组名 = new 数组类型【】{数据1,数据2…};

简洁的方式:数组类型【】 数组名 = {数据1,数据2…}

数组中常见的几种异常:

  1. 数组越界异常(ArrayIndexOutOfBoundsException)
  2. 空指针异常(NullPointerException)

数组的分类

  1. 基本数据类型的数组
    动态初始化数组以后,数组的元素都会赋予一个默认值
    short byte int long double float char boolean char的默认值是空格 Boolean默认值是false
  2. 引用数据类型的数组

java中的内存是怎么分配的

内存的申请和释放都是jvm进行管理的,java程序要运行,jvm会自动的像电脑申请一块内存
把这块内存分为5部分:

  1. 栈:主要存放局部变量
  2. 堆(Heap):凡是new出来的东西都放在堆里面,堆中的数据都有默认原则
    整数0 小数0.0 布尔false char空格 应用数据类型null
  3. 方法区(Method Area):存放的是与 class相关的信息
  4. 本地方法区(Native Method Area):与操作系统有关
  5. 寄存器(Register):与CPU有关

冒泡排序

二维数组

数组中的数组

声明二维数组

1.声明二维数组
数组类型【】【】 数组名;
第一个中括号:二维数组中有几个一维数组 行
第二个中括号:每一个二维数组中有多少元素 列

2.初始化二维数组

  • 动态初始化
  • 静态初始化

方法

把一些相关的语句组织在一起,用于解决特定功能的代码块
好处:提高代码的重用性,维护性,可读性号,执行效率高

含义

  • 访问修饰符(权限修饰符)
    public 公共的,在当前项目下的任何地方都可以访问都可以调用
    private 私有的,只能在当前类下访问
    protected 受保护的,在同一个包或者其他派生类(子类和父类)中可以访问
    default: 缺省,只能在当前包下进行访问
  • 方法的返回值类型:
    方法执行完成以后,最终产生的结果是什么类型的
    方法名:自己定义的名字,首字母小写,驼峰式命名法
    形参列表:由多个形参组成的列表
    形参:用于接收调用者实际传过来的数据
  • return:
    (1)把方法最终处理的结果返回给调用者
    (2)结束当前方法
    注意:返回数据类型必须要返回值类型一致

方法重载

方法名必须相同,参数列表不同
1.参数列表的个数不同
2.和参数名没有任何关系
3.和返回值类型无关
4.参数类型不同
5.参数类型的顺序

类和对象

面向过程

c语言   看中的是过程的开发
在开发一个程序的时候,看中的是中间的过程,每一个过程步	 骤都要自己去做

面向对象

java  c# js.... 看中的是类的设计
当开发一个程序的时候,不看重具体的过程,看中的是谁能帮我去完成这件事,找对象帮我去做
前期去设计类的时候比较复杂,但是后期的复用性和扩展性比较好

面向过程和面向对象的优缺点

  1. 面向过程:面向过程的性能比面向对象的性能高,因为面向对象在实例化时,开销比较大
    缺点:维护性和扩展性没有面向对象好
  2. 面向对象:维护性和扩展性好
    缺点:性能低,开销大

成员变量和局部变量的区别:

  1. 定义的位置不同
  2. 作用域不同:
    成员变量作用于类的内部
    局部变量作用在方法之内
  3. 默认值不同
    成员变量默认值
    局部变量没有默认值
  4. 内存中的位置不同
    成员变量保存在堆里面
    局部变量保存在栈里面
  5. 成员变量有四种访问修饰符:private public protected 缺省
  6. 局部变量没有访问修饰符,默认与方法的修饰符相同

封装

为何要封装

当我创建完对象之后,我如果直接通过“对象名、属性名“的方式给属性固执的话,可能会出现一些不符合实际情况的问题,
所以我们不考虑使用“对象名、属性名“的方式赋值,而是通过“对象名、方法名()”的方式进行赋值,因为我可以在方法里面
加上大量的限制,对属性值进行限制

方法:

  • 将属性私有化
  • 提供公用的(get和set)方法实现属性的取值和赋值

new的其实就是一个构造方法

构造方法

在我们去创建对象的时候,会用到一个特殊的方法叫做构造方法,构造器
无参构造方法:
public 构造方法名(){
}
注意:
1.构造方法没有返回值
2.构造方法名必须和你当前类的名字一致,包括大小写

作用:
1.创建对象,new的时候就是调用了构造方法
2.创建对象的同时可以调用有参构造方法对属性赋值

注意:如果没有显式的构造方法,系统会默认提供一个无参的构造方法
如果显式的定义了一个构造方法,系统不会再提供无参的构造方法,需要我们手动的创建一个无参的构造方法

this关键字

1.this代表当前使用的对象或者是正在创建的对象,通过那个对象调用了方法那个对象就是this
2.this可以修饰构造方法,方法,成员变量 直接在成员变量名或者成员方法名前面加成this
3.可以在构造方法中通过“this(形参)”的方法调用有参构造方法

继承

继承是多态的前提,没有继承就没有多态继承:共性抽取

优缺点:
提高了代码分复用性
由于继承会有多层的继承关系,会提高他们之间的依赖关系,耦合度提高

作用:

  1. 使用继承以后父类所有的属性和方法子类都可以获取到,除了私有的除外
  2. 子类除了通过继承获取父类的属性和方法外,还可以单独定义自己独有的属性和方法
  3. 一个子类可以派生别的子类
  4. .一个父类可以有多个子类,一个子类不可以有多个父类
  5. 方法重写,如果父类的方法满足不了子类要求时,子类可以对父类的方法进行重写

重写规则:

  • 要求子类的重写的方法名,参数列表,返回值类型必须和父类一致
  • 子类重写方法的访问修饰符权限不能低于父类方法修饰符权限
  • 子类方法和父类方法必须同为static或非static

重载(overload)和重写(override)的区别:

  1. 方法重载必须在同一个类中,方法重写必须存在继承关系
  2. 方法重载要求方法名相同,参数列表必须不相同,和返回值无关
  3. 方法重写要求方法名参数列表返回值必须和父类一致

super关键字可以修饰属性、方法、构造方法

  1. 当子类和父类的属性出现重名时,默认会调用子类的属性,可以通过“super.属性名”的方式显式的调用父类声明的属性
  2. 如果子类重写父类中的方法,想重新调用父类中的此方法,可以通过“super.方法”的方式显式的调用父类声明的方法
  3. super可以修改构造方法,通过子类构造方法中使用“super(形参)”来显示的调用父类对应的构造方法

注意

  • super必须生命在首行

  • 说明this和super只能出现一个

  • 在构造方法中,不显示的通过super的方式调用父类中的构造方法
    默认会调用父类无参的无参构造方法

    如果一个类没有显式的继承谁,默认继承object

访问修饰符:修饰类、变量、方法、接口
public:公共的,在当前项目下的任何地方都可以访问到
protected:受保护的,在同一个包下或者在其他子类中可以访问
default:缺省 在同一个包下
private:私有,在当前类下访问

多态

多态:前提必须有继承或者接口的实现

多态性

1.同一个动作与不同的对象产生不同的行为
2.多态值得是一个对象的多种形态

多态的体现方式

使用继承:不同的子类重写父类方法后,体现出来的形式不一样
接口的实现

形成多态的必要条件

  • 继承:存在子类和父类的关系
  • 接口实现:定义一个类实现对应的接口
  • 重写:子类重写了父类的方法
  • 重载:调用相同的方法名,实现的功能不同
  • 子类对象的多态性:父类的应用指向子类的实例

程序分为两种状态,一个是编译状态,一个是运行状态
对于多态来说:

  1. 编译时看左边,你这对象定义的是什么类型就是什么类型,将Pet对象看做是Pet类型,
  2. 运行时看右边,真正执行的对象,也就是子类对象(Dog),执行的也是子类重写后的方法

上转型和下转型

  • 上转型:将子类对象交给父类引用,可以自动转型
  • 下转型:将父类转成子类,强制类型转换

instanceof运算符:在强制类型转换之前可以判断对象的真实实例类型
if(pet instanceof dog){

dog  dog= (Dog)  pet;
dog2.sleep();

}else if(pet instanceof penguin){

penguin pe  =  (Penguin)  pet;
pe.swimming();

}

final关键字:代表最终的意思

可以修饰什么?

  1. 修饰类 最终类,没有子类了,不能别继承,他就是一个太监类,可以继承别的类
  2. 修饰方法 代表这个方法是一个最终方法,不能被重写
  3. 修饰成员变量 成员变量的值不可改变 1.成员变量不会再有默认值 2.如果使用final关键字,必须直接给成员变量赋值
  4. 修饰局部变量 局部变量的值不能被修改,一般修饰一个常量

static关键字:静态的

static修饰成员变量(类本身)

  1. 修饰成员变量,这个变量就不属于对象了,而属于类本身,我们就可以通过“类名.属性名”的方式访问

  2. 只要通过我这个类创建的对象,这些对象都可以共享这个属性

  3. 当其中一个对象对类变量进行更改以后,其他对象的这个类变量也会更改
    VS实例变量(非static的变量,属于对象本身,各个对象都有各自的一套副本)

  4. 类变量是随着类的加载而加载,类变量的生命周期大于实例变量

  5. 类变量放在方法区的静态域里面

static修饰方法(类方法)

  1. 修饰方法,这个方法就属于类本身了,可以通过“类名.方法名()”的方式调用
  2. 随着类而加载
  3. 在静态方法里面只能调用静态变量和静态方法,相反普通普方法里面可以调用静态变量和静态方法,以为静态变量和静态方法加载时机早于
    实例变量和实例方法的加载时机
  4. 在静态方法里面不能使用this和super(因静态方法属于类本身,而this和super属于本对象)

static修饰代码块
代码块的作用完成初始化

  1. 非静态代码块
    可以给类的属性进行初始化操作,同时还可以调用类的方法(静态或非静态都可以)
    里面可以有输出语句
    每创建一个对象,非静态代码块就执行一次
  2. 静态代码块
    里面可以有输出语句
    随着类加载而加载,只会执行一次
    静态代码块的加载时机早于非静态代码块
    静态代码块里面只能调用类变量和类方法

对属性赋值:
(1)默认初始化
(2)显式的初始化
(3)通过set方法或者构造方法
(4)代码块初始化

接口和抽象类

抽象类

1.什么是抽象类?
如果一个类表达的是一种抽象的概念,仅仅作为其他派生类的一个父类,主要有动能的定义,具体的实现交给他的子类来做
2.语法: 在class前面加上一个abstract就是一个抽象类
3.特点:
(1)抽象方法所在的类必须是抽象类
(2)抽象类不能进行实例化
(3)如果要实现一个抽象类,创建一个子类去继承这个抽象类
(4)子类继承抽象类以后,必须重写抽象类里面所有的抽象方法(前提子类不是抽象类)
(5)抽象类中可以创建普通方法
(6)抽象类可以定义构造方法
抽象方法:
在返回值前面加上abstract就是一个抽象方法
特点:
只能方法的定义,没有方法体

接口

什么是接口?
(1)九十多个类之间的公共规范
(2)接口是一个特殊的抽象类型,接口里面的方法就是抽象方法
(3)解决了java单继承的鸡肋

接口的特点
(1)接口里面的属性都是常量
(2)接口里面的方法都是抽象方法
(3)接口不能够实例化
(4)抽象类是继承,接口是用来实现的
(5)一个类实现一个接口,必须实现这个接口里面的所有的抽象方法(前提这个类不是一个抽象类)
(6)一个类可以试想多个接口,中间用逗号隔开
(7)接口不能定义普通方法
(8)接口没有构造方法
(9)接口也可以继承接口,并且可以继承多个接口

实现类
(1)实现接口的类叫做实现类 class A implements B
(2)如果一个类继承了一个父类同时需要实现一个接口,继承重写方法一定要在接口的前面

抽象类和接口的不同点

  1. 抽象类和接口定义不同:抽象类abstract,接口interface
  2. 接口里只能包含抽象方法,不包含已经实现的方法,抽象类则完全可以包含普通的方法
  3. 接口里不能定义静态方法:抽象类可以定义静态方法
  4. 接口里只能定义静态常量属性,不能定义普通属性;抽象类立即可以定义普通属性,也可以定义静态常量
  5. 接口不包含构造方法;抽象类可以包含构造函数,抽象类里的构造函数并不是用于创建对象,而是让其子类调用这些构造函数来完成
    属于抽象类的初始化操作
  6. 接口不包含初始化块,带抽象类可以包含初始化块
  7. 一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补java单继承的不足

java常用类

Object类

是类层次结构的根,java中所有的类都继承自这个类  

特征:

  1. 是java中唯一没有父类的类
  2. 其他所有的类都继承了Object类中的方法,所以其方法的重要性不言而喻

操作符与equals比较
等号 操作符:

  • 引用类型比较引用(是否指向同一个对象)
  • 基本类型比较值
  • 用等号进行比较是,符号两边的数据类型必须一致(可自动转换的基本数据类型除外),否则编译出错

equals方法:

  • 是Object类的方法,由于所有类都继承Object类,也就继承了equals()方法
  • 只能比较引用类型
  • 在Object类的定义中,其作用于“==”相同,比较是否指向同一个对象。
  • 注意:对类File、string、Date、封装类及很多重写equals()方法的类来说,是比较类型及内容而不考虑引用是否指向同一个对象

StringBuffer:

就是字符串缓冲区,用于存储可变字符序列的容器。

特点:可以对字符串进行修改,长度可变。

常用方法:

  • 构造:
    StringBuffer()
    StringBuffer(int size)
    StringBuffer(String str)
  • 添加:
    StringBuffer append(data);
    StringBuffer insert(index,data);
  • 删除:
    StringBuffer delete(start,end):包含头,不包含尾。
    StringBuffer deleteCharAt(int index):删除指定位置的元素
  • 查找:
    char charAt(index);
    int indexOf(string);
    int lastIndexOf(string);
  • 修改:
    StringBuffer replace(start,end,string);
    void setCharAt(index,char);

StringBuffer:可变字符序列、线程安全、效率低
StringBuilder:可变字符序列、线程不安全、效率高

Date&DateFormat类

  • Date类在java.util包中。使用Date类的无参构造方法创建的对象可以获取本地当前时间。
  • SimpleDateFormat可用来实现日期的格式化。
    • public SimpleDateFormat(String pattern):使用参数pattern指定的格式创建一个对象。
    • public String format(Date date):按照构造方法中指定的pattern格式化时间对象date。

日期类

  • java.util.Calendar(日历)类

    • Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能。
  • 获取Calendar实例的方法

    • 使用Calendar.getInstance()方法
    • 调用它的子类GregorianCalendar的构造器。
  • 一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、MINUTE、SECOND

    • public void set(int field,int value)
    • public void add(int field,int amount)
    • public final Date getTime()
    • public final void setTime(Date date)

Java集合框架

java集合概述

  • 前面存储对象,数组,弊端
  • Java 集合就像一种容器,可以把多个对象的引用放入容器中。
  • Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组

在这里插入图片描述

  • Java 集合可分为 Set、List 和 Map 三种体系
    • Set:无序、不可重复的集合,set又是以map为底层实现
    • List:有序,可重复的集合,list接口是以数组为底层实现,是有序的
    • Map:具有映射关系的集合,key-value(键值对),map接口底层是hash函数,无续(不是随机)
  • 在 Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理;从 Java5 增加了泛型以后,Java 集合可以记住容器中对象的数据类型

在这里插入图片描述

使用Iterator接口遍历集合元素

  • Iterator 接口主要用于遍历 Collection 集合中的元素,Iterator 对象也被称为迭代器。
  • Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的统一编程接口。
  • Iterator 仅用于遍历集合,Iterator 本身并不提供存放对象的能力。如果需要创建 Iterator 对象,则必须有一个被迭代的集合。

List

  • List 代表一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引
  • List 允许使用重复元素,可以通过索引来访问指定位置的集合元素。
  • List 默认按元素的添加顺序设置元素的索引。

Set集合

  • Set接口存储一组唯一,无序的对象。
    • HashSet 是Set接口常用的实现类。
    • HashSet允许集合元素值为null
  • 操作数据的方法与List类似,Set接口不存在get()方法。
  • Iterator接口表示对集合进行迭代的迭代器,专门实现集合的遍历。
  • 方法:
    • hasNext():判断是否存在另一个可访问的元素
    • next():返回要访问的下一个元素

Map

  • HashMap是Map接口中最常见的实现类。
  • 存储一组成对的键-值对象,提供key(键)到value(值)的映射,通过key来索引
    • key不允许重复
    • value允许重复
  • 添加的对象将转换为Object类型

HashMap&Hashtable

  • HashMap 和 Hashtable 都是 Map 接口的实现类
  • 区别:
    • Hashtable 是一个古老的 Map 实现类,不建议使用
    • Hashtable 是一个线程安全的 Map 实现,但 HashMap 是线程不安全的。
    • Hashtable 不允许使用 null 作为 key 和 value,而 HashMap 可以
  • 与 HashSet 集合不能保证元素的顺序的顺序一样,Hashtable 、HashMap 也不能保证其中 key-value 对的顺序
  • Hashtable 、HashMap 判断两个 Key 相等的标准是:两个 Key 的hashCode 值相等,并且equals 方法返回 true。
  • Hashtable 、HashMap 判断两个 Value相等的标准是:两个 Value 通过 equals 方法返回 true

TreeMap

  • TreeMap 存储 Key-Value 对时,需要根据 Key 对 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。
  • TreeMap 的 Key 的排序:
    • 自然排序
    • 定制排序

操作集合的工具类

  • Collections 是一个操作 Set、List 和 Map 等集合的工具类
  • Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法
  • 排序操作:(均为static方法)
    • reverse(List):反转 List 中元素的顺序
    • shuffle(List):对 List 集合元素进行随机排序
    • sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
    • sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
    • swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
  • Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
  • Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
  • Object min(Collection)
  • Object min(Collection,Comparator)
  • int frequency(Collection,Object):返回指定集合中指定元素的出现次数
  • void copy(List dest,List src):将src中的内容复制到dest中
  • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值

泛型

  1. 泛型的声明
    interface List 和 class Test<K,V>
    其中,T,K,V不代表值,而是表示类型。这里使
    用任意字母都可以。常用T表示,是Type的缩写。
  2. 泛型的实例化:
    一定要在类名后面指定类型参数的值(类型)。如:
    List strList = new ArrayList();
    Iterator iterator = customers.iterator();
    • T只能是类,不能用基本数据类型填充。

泛型的几个重要使用:

  1. 在集合中使用泛型
  2. 自定义泛型类
  3. 泛型方法
  4. 泛型接口

Java异常

Java程序运行过程中所发生的异常事件可分为两类:

  • Error: JVM系统内部错误、资源耗尽等严重情况//无法控制,不处理
  • Exception: 其它因编程错误或偶然的外在因素导致的一般性问题。比如:空指针访问、试图读取不存在的文件等。

Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。
Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。
Exception(异常):是程序本身可以处理的异常

在这里插入图片描述

异常分类

  • Java的异常(包括Exception和Error)分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。
    • 可查的异常(编译器要求必须处置的异常)
    • 不可查的异常(编译器不要求强制处置的异常)

需要异常处理:除了Error和runtimeexception
checked exceptions(检测时异常)/ 编译异常
不需要处理的:error和runtimeexceptin
unchecked exceptions(非检测时异常)/ 运行时异常

  • Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。
    • 运行时异常:都是RuntimeException类及其子类异常
    • 非运行时异常 (编译异常):是RuntimeException以外的异常

异常处理机制

异常处理是通过try-catch-finally语句实现的。

try {
… //可能产生异常的代码
} catch( ExceptionName1 e ) {
… //当产生ExceptionName1型异常时的处置措施
} catch( ExceptionName2 e ) {
… //当产生ExceptionName2型异常时的处置措施
}
[ finally{
… //无条件执行的语句
} ]

  • try:将可能出现异常的代码放在try语句块中。
  • catch (Exceptiontype e):在catch语句块中是对异常对象进行处理的代码。 ()
  • 如果明确知道产生的是何种异常,可以用该异常类作为catch的参数也可以用其父类作为catch的参数。
  • 每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。

异常处理的语法规则

  1. 必须在 try 之后添加 catch 或 finally 块。
  2. 必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。
  3. catch 块与相应的异常类的类型相关。
  4. 一个 try 块可能有多个 catch 块。
  5. 可嵌套 try-catch-finally 结构。
  6. 在 try-catch-finally 结构中,可重新抛出异常。
  7. 除了下列情况,总将执行 finally 做为结束:JVM 过早终止(调用 System.exit(int));在 finally 块中抛出一个未处理的异常;计算机断电、失火、或遭遇病毒攻击。

Throws抛出异常的规则

  1. 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出。
  2. 必须声明方法可抛出的任何可查异常(checked exception)。
  3. 仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。
  4. 调用方法必须遵循任何可查异常的处理和声明规则。

异常处理的一般原则

  • 能处理就早处理,抛出不去还不能处理的就想法消化掉或者转换为RuntimeException处理。
    事务异常,在持久化层,Dao层只能往上抛。
  • 因为对于一个应用系统来说,抛出大量异常是有问题的,应该从程序开发角度尽可能的控制异常发生的可能。
  • 对于检查异常,如果不能行之有效的处理,还不如转换为RuntimeException抛出。这样也让上层的代码有选择的余地――可处理也可不处理。
  • 对于一个应用系统来说,应该有自己的一套异常处理框架,这样当异常发生时,也能得到统一的处理风格,将优雅的异常信息反馈给用户。

Java IO流

File类

  • File类的常见构造方法:
    • public File(String pathname)
  • 以pathname为路径创建File对象,可以是绝对路径或者相对路径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。
    • public File(String parent,String child)
  • 以parent为父路径,child为子路径创建File对象。
  • File的静态属性String separator存储了当前系统的路径分隔符。
  • 在UNIX中,此字段为‘/’,在Windows中,为‘\’

IO原理

  • IO流用来处理设备之间的数据传输。
  • Java程序中,对于数据的输入/输出操作以”流(stream)” 的方式进行。
  • java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。

IO流的分类

  • IO流是用来处理设备与程序之间的数据传输
  • 按流向(站位到程序的角度):
    • 输入流
    • 输出流
  • 按处理的单位:
    • 字节流(8bit)byte (非文本信息 视频、音频、图像)
    • 字符流(16bit)char(文本文件)
  • 按流的角色
    • 节点流:可以从一个特定的 IO 设备读/写数据的流(访问文件相关,也叫文件流,程序直接作用在文件上)
    • 处理流:对一个已存在的流进行连接和封装,通过封装后的流来实现数据读/写操作 (缓冲流)

字节流文件读写步骤

  • 创建文件对象:File f = new File(“文件路径”);
  • 根据文件对象创建输入输出流
    FileInputStream filein = new FileInputStream(f);
    FileOutputStream fileout = new FileOutputStream(f)
  • 实现对文件的读写
  • 读:filein.read(字节数组);//将文件内容读到指定的字节数组
  • 写:fileout.write(字节数组);//将指定字节数组中的数据写到文件
  • 关闭流
    filein.close();
    fileout.close();

字符流

  • 实现从指定的文件中读取字符和将字符写入指定的文件
  • 抽象类:Reader和Writer
  • 子类:FileReader和FileWriter

InputStream&Reader

  • InputStream 和 Reader 是所有输入流的基类。
  • InputStream(典型实现:FileInputStream):
    • int read()
    • int read(byte[] b)
    • int read(byte[] b, int off, int len)
  • Reader(典型实现:FileReader):
    • int read()
    • int read(char [] c)
    • int read(char [] c, int off, int len)
  • 程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源。

OutputStream&Writer

  • OutputStream 和 Writer 也非常相似:
    • void write(byte write/int c)
    • void []/char[] buff)
    • void write(byte[]/char[] buff, int off, int len);
  • 因为字符流直接以字符作为操作单位,所以 Writer 可以用字符串来替换字符数组,即以 String 对象作为参数
    • void write(String str);
    • void write(String str, int off, int len)

多线程

Thread类

  • 构造方法
    • Thread():创建新的Thread对象
    • Thread(String threadname):创建线程并指定线程实例名
    • Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run方法
    • Thread(Runnable target, String name):创建新的Thread对象

创建线程的两种方式

  1. 继承Thread类
  1. 定义子类继承Thread类。
  2. 子类中重写Thread类中的run方法。
  3. 创建Thread子类对象,即创建了线程对象。
  4. 调用线程对象start方法:启动线程,调用run方法。
  1. 实现Runnable接口
    1)定义子类,实现Runnable接口。
    2)子类中重写Runnable接口中的run方法。
    3)通过Thread类含参构造器创建线程对象。
    4)将Runnable接口的子类对象作为实际参数传递给
    Thread类的构造方法中。
    5)调用Thread类的start方法:开启线程,调用
    Runnable子类接口的run方法。

线程的生命周期

在这里插入图片描述
Synchronized的使用方法

  1. synchronized (对象){
    // 需要被同步的代码;
    }

  2. synchronized还可以放在方法声明中,表示整个方法
    为同步方法。
    例如:
    public synchronized void show (String name){
    ….
    }

Java反射机制

而反射则是一开始并不知道我要初始化的类对象是什么,自然也无法使用 new 关键字来创建对象了。这时候,我们使用 JDK 提供的反射 API 进行反射调用:

Class clz = Class.forName("com.hpe.reflect.Apple"); 
Method method = clz.getMethod("setPrice", int.class); 
Constructor constructor = clz.getConstructor(); 
Object object = constructor.newInstance();
 method.invoke(object, 4);

反射相关的主要API:

java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造方法

通过反射调用类的完整结构

使用反射可以取得:

  1. 实现的全部接口

    • public Class<?>[] getInterfaces()
      确定此对象所表示的类或接口实现的接口。
  2. 所继承的父类

    • public Class<? Super T> getSuperclass()
      返回表示此 Class 所表示的实体(类、接口、基本类型)的父类的 Class。
  3. 全部的构造器

    • public Constructor[] getConstructors()
      返回此 Class 对象所表示的类的所有public构造方法。
    • public Constructor[] getDeclaredConstructors()
      返回此 Class 对象表示的类声明的所有构造方法。
  • Constructor类中:
    • 取得修饰符: public int getModifiers();
    • 取得方法名称: public String getName();
    • 取得参数的类型:public Class<?>[] getParameterTypes();
  1. 全部的方法
    • public Method[] getDeclaredMethods()
      返回此Class对象所表示的类或接口的全部方法
    • public Method[] getMethods()
      返回此Class对象所表示的类或接口的public的方法
  • Method类中:
    • public Class<?> getReturnType()取得全部的返回值
    • public Class<?>[] getParameterTypes()取得全部的参数
    • public int getModifiers()取得修饰符
    • public Class<?>[] getExceptionTypes()取得异常信息
  1. 全部的Field
  • public Field[] getFields()
    返回此Class对象所表示的类或接口的public的Field。
  • public Field[] getDeclaredFields()
    返回此Class对象所表示的类或接口的全部Field。

Field方法中:

  • public int getModifiers() 以整数形式返回此Field的修饰符
  • public Class<?> getType() 得到Field的属性类型
  • public String getName() 返回Field的名称。

通过反射调用类中的指定方法、指定属性

调用指定方法

通过反射,调用类中的方法,通过Method类完成。步骤:
1.通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
2.之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。

Object invoke(Object obj, Object … args)
说明:
1.Object 对应原方法的返回值,若原方法无返回值,此时返回null
2.若原方法若为静态方法,此时形参Object obj可为null
3.若原方法形参列表为空,则Object[] args为null
4.若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法。

调用指定属性

在反射机制中,可以直接通过Field类操作类中的属性,通过Field类提供的set()和get()方法就可以完成设置和取得属性内容的操作。

  • public Field getField(String name) 返回此Class对象表示的类或接口的指定的public的Field。
  • public Field getDeclaredField(String name)返回此Class对象表示的类或接口的指定的Field。

在Field中:

  • public Object get(Object obj) 取得指定对象obj上此Field的属性内容
  • public void set(Object obj,Object value) 设置指定对象obj上此Field的属性内容

注:在类中属性都设置为private的前提下,在使用set()和get()方法时,首先要使用Field类中的setAccessible(true)方法将需要操作的属性设置为可以被外部访问。

网络编程

网络编程的目的:
直接或间接地通过网络协议与其它计算机进行通讯。
网络编程中有两个主要的问题
如何准确地定位网络上一台或多台主机
找到主机后如何可靠高效地进行数据传输。

网络通信协议

在这里插入图片描述
通讯要素:IP和端口号

  • IP 地址:InetAddress
    唯一的标识 Internet 上的计算机
    本地回环地址(hostAddress):127.0.0.1 主机名(hostName):localhost
    不易记忆
  • 端口号标识正在计算机上运行的进程(程序)
    不同的进程有不同的端口号
    被规定为一个 16 位的整数 065535。其中,01023被预先定义的服务通信占用(如MySql占用端口3306,http占用端口80等)。除非我们需要访问这些特定服务,否则,就应该使用 1024~65535 这些端口中的某一个进行通信,以免发生端口冲突。
  • 端口号与IP地址的组合得出一个网络套接字。

InetAdress代码示例
在这里插入图片描述
通讯要素2:网络通信协议

  • 网络通信协议
    计算机网络中实现通信必须有一些约定,即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。
  • 通信协议分层的思想
    由于结点之间联系很复杂,在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展。

TCP和UDP

  • TCP协议:
    使用TCP协议前,须先建立TCP连接,形成传输数据通道
    传输前,采用“三次握手”方式,是可靠的
    TCP协议进行通信的两个应用进程:客户端、服务端
    在连接中可进行大数据量的传输
    传输完毕,需释放已建立的连接,效率低
  • UDP协议:
    将数据、源、目的封装成数据包,不需要建立连接
    每个数据报的大小限制在64K内
    因无需连接,故是不可靠的
    发送数据结束时无需释放资源,速度快

基于Socket的TCP编程

客户端Socket的工作过程包含以下四个基本的步骤:
- 创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
- 打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流,进行数据传输
- 按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
- 关闭 Socket:断开客户端到服务器的连接,释放线路

客户端建立socketAtClient对象的过程就是向服务器发出套接字连接请求

Socket s = new Socket(192.168.40.165,9999);
OutputStream out = s.getOutputStream();
out.write(“hello”.getBytes());
s.close();

服务器程序的工作过程包含以下四个基本的步骤:
- 调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
- 调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
- 调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
- 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。

所谓“接收”客户的套接字请求,就是accept()方法会返回一个 Socket 对象

ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept ();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = in.read(buf);
String str = new String(buf,0,num);
System.out.println(s.getInetAddress().toString()+:+str);
s.close();
ss.close();

序列化和反序列化

在这里插入图片描述

// 序列化
FileOutputStream fos = new FileOutputStream("temp.out");// 临时目录
ObjectOutputStream oos = new ObjectOutputStream(fos);
City jn = new City();
jn.setState("中国");
jn.setProvince("山东");
jn.setCity("济宁");

oos.writeObject(jn);
oos.flush();
oos.close();
// 反序列化
FileInputStream fis = new FileInputStream("temp.out");
ObjectInputStream oin = new ObjectInputStream(fis);
try {
Object obj = oin.readObject();
System.out.println("province=" + ((City) obj).getProvince());
System.out.println("city=" + ((City) obj).getCity());
} catch (Exception e) {
System.out.println("error");
}
oin.close();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值