一段孤独的代码 一段孤独的代码

A Lonely Code

目录
Java初学笔记(很早的笔记,自己最初学习Java时的笔记,记录的可能有些凌乱)
/      

Java初学笔记(很早的笔记,自己最初学习Java时的笔记,记录的可能有些凌乱)

Java特性

  • 跨平台(跨操作系统 windows linux nuix)
  • 一次编译,到处运行
  • 半编译半解释
  • .java------>.class(字节码文件)
  • 面向对象
  • 万物皆对象
  • 健壮性
  • 自动垃圾回收
  • 异常处理机制
  • 安全性
  • 多线程
  • 多个任务同时执行
  • 生存周期

Java虚拟机实例通过调用某个初始类的main()方法来运行一个Java程序

  • main()方法必须是共有的(public)、静态的(static)、返回值为void,并且接受一个字符串数组作为参数
  • 任何一个拥有main()方法的类都可以作为Java程序运行的起点
  • Java程序初始类中的main()方法,将作为该程序初始县城的起点,任何其他的线程都有这个初始线程启动的

Java程序运行的原理

  • 编译源文件:java源代码被java编译器编译(Compile)。如果这是产生错误,我们成为编译错误,如果没有错误,则生成字节码(byte code).
  • 运行字节码:这里,Java字节码被装载到Java虚拟机中,解释成本地代码再运行。如果此时产生错误,我们称之为运行时错误(Runtime)。

Java注释

  • 单行注释// ctrl+/
  • 多行注释/* */ ctrl+shift+/
  • 文档注释/** */ alt+shift+j
  • 文档注释作用:java生成帮助文档,生成时可根据文档注释生成帮助文档

Java程序

//所属包

com.neuedu.study;

//类声明

public class HelloWorld

//方法声明

public static void HelloWorld(String[] args)

//代码区

System.out.println("HelloWorld!");

导入工程:

FILe->Import

生成帮助文档

File->Export->Java->Javadoc

防止中文乱码

VM options设置

-encoding UTF-8 -charset UTF-8

项目目录功能设置

项目右键->BuildPath->Configure Build Path

Java程序结构

Java块->数据类型、变量、运算符、控制流语句

标识符

Java中的包、类、方法、参数和变量的名称

变量必须以字母、下划线(_)或美元符号($)开头

余下的字符可以是下划线、美元符号或任何的字母或数字,长度不限。标识符中不能有空格

不能使用Java中的关键字或者保留字做标识符

命名规则

  • 元素 规范 示例
  • 类名 Pascal规则 Person StudentDemo
  • 变量名 Camel规则 age height avgValue
  • 方法名 Camel规则 getAge setUserName
  • 包名 全部小写 com.neusoft
  • 常量名 全部大写 MAX_VALUE
  • 关键字/保留字
 1abstract continue goto null switch
 2assert default if package synchronized
 3boolean do implements private this
 4break double import protected throw
 5byte else instanceof public throws
 6case extends int return transient
 7catch final interface short try
 8char finally long static void
 9class float native strictfp volatile
10const for new super while

变量

  • 变量类型 变量名[=变量初值]; int x = 3; double b = 0.123; char ch;ch='a';

变量分类:

基本数据类型(4类8种)

  • 数值型:整数类型(byte short int long),浮点类型(float double)

  • byte 1字节 -128~127
  • short 2字节 -2^15~2^15-1
  • int 4字节 -2^31~2^31-1
  • long 8字节 -2^63~2^63-1
  • double 32字节 -3.403E38~3.403E38
  • float 64字节 -1.798E308~1.798E308
  • float f=12.3f 必须加f
  • 字符型:char

  • 单个字符用char类型表示,通常取值可为:
  • 英文字母、数字、庄毅序列、特殊字符等
  • Java中的字符占两个字节(16位),因此可用十六进制编码形式表示
  • Java中的字符类型的值通常用单引号(‘’)括起来
  • ‘a' 字母a
  • ’中‘ 汉子中
  • '\n' 转义字符表示换行
  • '\u????' 特度不高的Unicode字符,用\u+四个确切的16位数字代替
  • '\u03A6' Unicode字符表示希腊字符Φ
  • 转义字符

  • \r 表示接受键盘输入,相当于按下回车键
  • \n 表示换行
  • \t 表示制表符Table键
  • \b 表示退格键,相当于BackSpace
  • \' 相当于单引号'
  • \" 相当于双引号"
  • \\ 表示一个斜杠\
  • 布尔型:boolean

  • 引用数据类型(类,接口,数组)
  • 类:class
  • 接口:inference
  • 数组:array

变量定义:

  • 变量可定义在class级别和方法级别,定义在类级别的可以被类里的其他方法直接引用,如果定义在方法级别里,只能是该方法内使用

进制表示法:

  • 十进制:正常些
  • 十六进制:0x开头
  • 八进制:0开头

进制计算

数据类型的转换

自动转换规则

  • boolean类型不可以转换为其他的数据类型
  • 整数、字符型、浮点型的数据在混合运算中相互转换

转换时遵守以下原则。

  • byte、short、char之间不会互相转换,他们在计算时首先会转换为int类型
  • 强制类型转换(显示类型转换)
  • 变量 = (目标类型)值
  • byte a; int b; a=(byte)b;
  • 注意,在强制转换中,源类型的值可能大于目标类型,因此可能造成精度降低或溢出

运算符(操作符)

  • 算数运算符:+、-、*、/、%、++、--
  • %左侧为正结果为正,左侧为负结果为负
  • b=a++ b=a,a++;b=++a a++,b=a;
  • --同++
  • 赋值运算符:=、+=、-=、*=、/=、%=
  • x+=y x=x+y
  • -=,*=,/=,%=相同
  • 比较运算符:>、<、>=、<=、==、!=、instanceof
  • ==等于 返回值true,false
  • !=不等于
  • 逻辑运算符:!、&&、||
  • &&与 逻辑&&存在短路操作,当左边为false,右侧将不会执行
  • ||或 逻辑||存在短路操作,当左边为true,右侧将不会执行
  • !非
  • 位运算符:&、|、^、~、>>、<<、>>>
  • &位运算与
  • |位运算于
  • ^位运算异或
  • >>位运算右移
  • 结果除以2^移动位数,符号位为1,移空部分补1,符号位为0,移空部分补0
  • <<位运算左移 结果乘以2^移动位数
  • >>>无符号右位移
  • 条件运算符:?:
  • 可以替代if else
  • ?左边的运算结果为true,:左边的代码执行,否则:右边的代码执行

JUNIT单元测试类:

  • 右键工程BuildPath——ConfigureBuildPath——Libraries——ADDLibraries——Junit
  • 引入jar包
  • import org.junit.Test;
  • 方法前加@Test,方法可以独立运行。

#优先级
#键盘输入:

1Scanner sc=new Scanner(System.in);
2String i=sc.next();

流程控制语句

if语句:if-如果

1语法if(条件表达式){
2//成立执行语句
3}else
4{
5//不成立执行语句
6}

switch多分支

每个分支判断条件类型相同 switch支持byte,int,char,short,String

 1switch (表达式)
 2{
 3case 取值1语句块1
 4break;
 5
 6 case 取值n语句块n
 7break;
 8default:语句块n+1
 9break;
10}

switch具有穿透性,需使用break防止代码进入下一分支,可以采用不使用break使多段代码具有同一处理语句

while循环 先判断后循环

1语法:while(条件表达式)
2{
3执行语句块
4}
5do...while循环	先循环后判断
6语法:do
7{
8执行代码块
9}while(条件代码块)

do...while不管是否满足条件都会执行一次

for循环

1语法:for(初始化表达式;循环条件表达式;循环后操作表达式)
2{
3执行代码块
4}

循环中断

中断整个循环

break;

可以出现在do...while,while,for,switch中

break title;

标签跳出

title:for(){break;}

中断档次循环,进行下一次循环(跳过本次循环,进行下一次)

continue;

只能出现在do...while,while,for中

continue title;

标签跳过

title:for(){continue;}

数组

概念:数组可以看成是多个相同类型数据的组合,实现对这些数据的同一管理

数组的一个元素-数组中的每一个元素

数组中的个数,成为数组的长度

Java中声明数组时不能声明其长度

数组的索引-index 从0开始x[0]

一维数组

定义和创建

数组类型 数组名[]
数组类型[] 数组名
数组名=new 数组元素类型[数组长度]
1int a[];
2int[] a;
3a=new int[5];

初始化:

数组名[下标]=值;
数组类型 数组名[]={元素1,元素2...};
数组类型 数组名[]=new
数组类型[]{元素1,元素2,...}(方括号中不谢数值没根据初始化个数自动确定数组长度)

数组属性:

length长度可以获得数组长度.

二维数组

定义

数组类型 数组名[][];
数组类型[][] 数组名;
数组类型[] 数组名[];

创建

数组名 = new 数组元素类型[行数][列数];
数组名 = new 数组元素类型[行数][];

初始化:

数组类型 数组名[][]={{元素11,元素12,...},{元素21,元素22,...}};
数组类型 数组名[][]=new 数组类型[][]{{元素11,元素12,...},{元素21,...}};

数组的复制和排序

排序引包:import java.until.Arrays

排序

Arrays.sort(arr_name);
排序结果为升序

从指定索引(fromindex)开始到(toindex)结束排序不包括toindex

Arrays.sort(arr_name,fromindex,toindex)
排序结果为升序

数组的复制

System.arraycopy(source,srcPos,dest,destPos,length);
sourec:源数组--复制谁
srcPos源数据位置--从哪个索引处开始复制
dest:目标数组--复制到哪
destPos:目标数组开始位置
length:复制长度

方法定义与调用

定义方法

[访问控制符] [修饰符] 返回值类型 方法名(参数类型 形式参数,参数类型 形式参数,…)
1{
2    方法体
3}

方法分类:

无参无返回值

调用:方法名();

无参有返回值

调用:返回类型 变量名=方法名();

有参无返回值

调用:方法名(参数);

有参有返回值

调用:返回类型 变量名=方法名(参数);

方法重载

方法名名相同,参数类型或者参数个数不同.

面向对象

一种面向过程的语句:通过下指令管理数据 c

一种面向对象的语言:java python

万物皆对象:

 1物体:class
 2身高 体重 肤色:属性
 3动作:方法
 4如何定义一个人:
 5如何定义根据你要做什么事来定的
 6给大龙算命:calss
 7类的属性:
 8姓名:康
 9生辰:1989****
10星座:狮子
11性别:男
12算命:方法-返回值

面向对象的基本概念

抽象(abstract)

从事物中舍弃个别的非本质特征,抽取共同的本质特征

只考虑与问题域相关的信息,而忽略与问题域不相关的部分

对象(object)

可以是有形的,也可以是无形的(如一个客户,一张银行卡,窗体中的一个按等等)

对象是构成世界的一个独立单位

具有自己的静态结构(属性)和动态行为(方法)

每个对象有自己的唯一标识

类(class)

类是一组具有相同属性和行为的对象的抽象,类的作用是用来创建对象,对象类的一个实例

类和对象的关系

抽象和具体的关系。

每一个类在某一时刻都有零个或更多的实例,类是生成对象的模板

一个类定义了使用哪些数据来描述属性,每一个对象都有相应的属性值数据,一个类通过一系列方法来定义行为,这些方法能在每个对象中被激活

面向对象主要特征

封装(encapsulation)

所谓封装是把对象的属性和行为结合在一个独立的系统单位内部

尽可能隐蔽对象的内部细节,只向外部提供接口

降低对象间的耦合度

封装的重要意义:

使对象能够集中而完整地描述并对应一个具体事物

体现了事物的相对独立性,使对象外部不能随意存取对象的内部数据

继承(inheritance)

也称泛化,继承性是子类自动共享父类属性和方法的机制,在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入自己若干新的内容

继承简化了人们对事物的认识和描述,有益于软件复用,是OO技术提高软件开发效率的重要原因之一

是类之间的一种关系,一般类与特殊类之间的关系

继承关系的语义:“is a kind of”

多态(polymorphism)

指同一个命名可具有不同的语义

OO方法中,常指在一般类中定义的属性或方法被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为,对于子类,可用不同的方法替代实现父类的服务的方法

类私有属性getset访问器

右键source-getter/setter创建访问器

构造器

与类同名,的公共无返回值修饰可有参的方法,在对象实例化时执行

对象创建的内存模型

栈stack:在栈内保存基本数据类型的局部变量和对象的引用值.

堆heap:堆保存堆空间要求较大的变量.如对象的属性和数组的元素.在堆内存中开辟空间,只能通过内存分配操作符号new,凡是出现关键字new的地方必定分配了一个堆内存

在实例化一个对象时,同事操作了栈内存和堆内存,在栈内保存对象的首地址,即 引用;在堆内存中保存了对象的属性.对对象的所有操作只能通过引用完成,一旦引用出栈释放没有任何引用指向该对象,对象就编程垃圾失效.

对象何时变成垃圾

对象的引用被赋值为null;

Person p = new Person(); p=null;

一次性使用的匿名对象;

new Person().sayHello();

超出生命周期的;

for(int I=0;i++;i++) Person p=new Person();

每结束一次循环,变量p就超出生命周期,对象变成垃圾.

Java的垃圾回收机制是自动的,它保证程序健壮的主要手段,避免了由于程序员忘记回收内存而引起的内存泄漏,同时也避免了回收内存带来的代码繁琐。

垃圾回收机制仅仅作用于堆内存,于栈内存无关。

访问修饰符

默认friendly

变量初始化顺序

隐式赋予变量默认值

显示赋予初始值

通过构造器体赋予新值

this关键字

使用this关键字访问类中与局部变量相同的变量

通过构造器中使用this调用其他重载构造器

面向对象高级

继承

在Java中定义一个类时,让该类通过关键字extends继承一个已有的类,这就是类的继承(泛化)。

被继承的类称为父类(超类(超级的类),基类(基础类)),新的类称为子类(派生类)。

子类继承父类的所有属性和方法,同时也可以增加自己的属性和方法。

父类有的子类都有,子类有的父类不一定有

继承的好处

使代码更高效

易维护

代码的重用

super和this关键字

super()

作用:调用父类的构造器

只能出现在子类的构造器中,且必须是第一行

super()中的参数,决定了调用父类哪个构造器

如果子类构造器中没有出现super,那么编译器会默认加上super(),即调用父类的空构造器,如果父类没有空构造器,编译器提示错误。

this()

作用:调用本类的构造器

只能写在构造器的第一行

在同一个构造器中super()和this()不能同时出现

包的概念及应用

将类放入包中

注意:

在java中位于包中的类,在文件系统中的存放位置,必须有与包名层次相对应的目录结构

package语句作为java源文件的第一条语句

每个源文件只能声明一个包

如果没有package语句,则默认为无名包

访问修饰符

用来控制类的成员和类的使用范围

类成员的访问权限修饰符:private、default、protected、public

类的访问权限修饰符:public、default

方法覆盖

方法的覆盖(override)

重写(rewrite)

对从父类中继承来的方法进行改造

在子类继承父类时发生

方法覆盖的规则

在子类中的覆盖方法与父类中被覆盖的方法应具有

相同的方法名

相同的参数列表(参数数量、参数类型、参数顺序都要相同)

相同的返回值类型

子类覆盖方法的访问权限要不小于父类中被覆盖方法的访问权限

抽象

用abstract(抽象的)修饰的,只有方法声明,没有方法的实现(无方法的)

接口

用interface(接口的)修饰的,里面所有方法都是抽象的没有方法体的

命名时以I(大写i)开头,业界习惯

implements实现接口

与抽象类的对比

接口不能含有任何非抽象方法,而抽象类可以

类可以实现多个接口,但只能有一个父类

接口和接口之间可以多继承

抽象类可以理解为抽象方法和非抽象方法的混合体,而接口中的方法完全是抽象方法,是一套纯粹的规范。一般来说,有关系的类才能继承同一个抽象类,而无关的类不可能有同一个抽象父类,但是无关的类可以实现同一个接口。

转型

向上转型(Upcasting)

由子类转换为父类

自动转换

子类独有的属性和方法将被隐藏,无法访问

向下转型(Downcasting)

由父类转换为子类

需要强制转换

只有进行过向上转型的对象才可以进行向下转型

多态

简单来说,多态是具有表现多种形态的能力的特征

同一个实现接口,使用不同的实例而执行不同操作

多态实现的三个条件

要有继承,或实现

要有重写

父类引用指向子类对象

instanceof

判断对象是否属于一个类或者接口

for(类型 类型名:类型数组){}

static(静态)

static修饰的内容系统启动时就会加载进来,适合做一些初始化工作

static修饰的元素主要用来实现各个类之间共享,特别是属性

static可以修饰

  • 属性
  • 方法
  • 代码块

需要注意

只能修饰类成员,不能修饰局部变量

用static修饰变量(属性)

所有对象共享

也称为类变量

用static修饰的成员变量,他们在类被载入时创建,只要类存在,static变量就存在(参考java虚拟机视频)

两种方式访问

直接访问:类名.属性

实例化对象访问:对象名.属性

用static修饰方法

不需要实例化,可以直接访问

也称为类方法

两种方法访问

直接访问:类名.方法名()

实例化后访问:对象名.方法名()

注意事项

  • 静态方法里只能直接访问静态成员,而不能直接访问类中的非静态成员
  • 静态方法中不能使用this、super关键字
  • 静态方法不能被非静态方法覆盖,静态方法不能修饰构造器

静态代码块

一个类中由static关键字修饰的,不包含在任何方法体中的代码块

当类被载入时,静态代码块被执行,且只被执行一次

静态块经常用来进行类属性的初始化

final(终极,不可修改)

可以修饰的内容
类:不能被继承
变量(属性或者局部变量):不能被重新复制(永久不变的 ##### 适合做常量)
在声明是赋值,或在构造器中赋值(初始化时赋值)
系统不会对final属性默认的赋初始值
方法:不能在子类中被覆盖,即不能修改.

##单例

单例模式实现:

拥有一个私有构造方法

提供一个自身静态私有的成员变量

提供一个公有的静态的方法(返回实例化后的对象)

内部类

类中套类

内部类特性

普通类的访问权限修饰符

  • default
  • public

内部类的访问权限修饰符

  • default-friendly
  • public
  • protected
  • private
1class One{
2    class Two{
3        class Three{
4        }
5    }
6}

实例化

One.Two.Three ott=new One().new Two().new Three();

静态的类

实例化时

One.Two.Three ott=new Onr.Two.Three();

普通内部类

静态内部类

局部内部类

异常

异常的定义

运行期间发生的错误,而不是编译时的语法错误.

异常种类

编译器异常

运行期异常

异常的规则:底层个向上抛,顶层处理.一般如果调用业务方法,我们自己封装异常如AppRxception BusinexxException

异常继承自Exception

处理异常

API(Application Programming Interface)

第一章 工具类 java.util.*

第二章 集合 java.util.*

第三章 文件与流 java.io.*

第四章 多线程编程 java.net.*

第五章 网络编程 java.net,*

java.lang.*包是不需要手动导入的 String Math System

java.util 包含一些使用的工具类(包含 list map set calendar date 等类)

java.awt 图形用户界面包

java.io 提供多种输入/输出功能的类

java.net 提供网络应用的类

Object

祖宗类,他是所有类的父类

在Object类中定义的方法,在所有类中都可以使用。

hashCode

Object a=new Object();

System.out.println(a.hashCode());

== equals

--- equals ==
比较对象 引用类型 引用类型,基本类型
比较的值 比较引用的值String方法重写了equals,用于比较字面值 比较基本类型 比较值是否相等比较引用类型时,比较引用的值
是否可被重 写 可以 不可以

基本类型和包装类

boolean Boolean
byte Byte
char Character
double Double
float Float
int Integer
long Long
short Short

基本数据类型不是类,把它包装成类,称为包装类

字符串类

分类

String:final 不可变的

StringBuffer:可变的

创建

String s1="abc";常亮串池

String s2=new String("abc");(创建了新的堆字符串对象)

String 类的常用方法:

indexOf(子字符串)
charAt返回指定索引处的 char 值。
equals(Object anObject) 将此字符串与指定的对象比较。
equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,忽略大小写
getBytes()结果存储到一个新的 byte 数组中
getBytes(Charset charset) 使用给定的 指定编码方式将String存储到新的 byte 数组。
indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。用来检查字符串中是否包括指定的子字符串
indexOf(int ch, int fromIndex) 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。
indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引。
indexOf(String str, int fromIndex) 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
isEmpty() 当且仅当 length() 为 0 时返回 true。
lastIndexOf(int ch) 返回指定子字符在此字符串中最后一次出现处的索引。用indexOf 和lastIndexOf 混合使用,实现判断指定字符串是否只出现一次
length() 返回此字符串的长度。
replace(char oldChar, char newChar) 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
split(String regex) 根据给定正则表达式的匹配拆分此字符串。
startsWith(String prefix) 测试此字符串是否以指定的前缀开始。
toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
trim() 返回字符串的副本,忽略前导空白和尾部空白。

StringBuffer

可变字符串

创建对象的创建

append()追加

delete()删除

insert()插入

StringBuilder

类是一个可变的字符串序列

他与其他两个字符串类最大的区别:线程不安全的

Reverse方法Stringbuffer和StringBuiler有,String没有

String和StringBuffer类的比较

都在java.lang保重

String不可变字符串

StringBuffer是可变字符串

StringBuffer类与StringBuilder类的比较

StringBuffer和StringBuilder都是长度可变的字符串

两者操作基本一致

StringBuffer是线程安全的

StringBuilder是线程不安全的

Math类

常量

PI

E

方法

abs()绝对值

floor()截取整数

ceil()返回小数进一位的整数

round()返回四舍五入的整数

random()

Date类

获得系统当前时间

Date now=new Date();

Calender类

SimpleDataFormat类中的模式字母 -
字母 日期或时间元素
y
M 年中的月
d 月中的日
E 星期中的天数
a am\pm标记
H 一天中的小时数
h am\pm中的小时数
m 小时中的分钟数
s 分钟中的描述
S 毫秒数
1Calender c=Calender.getInstance();
2c.set(2018,4,25);
3System.out.println(c.get(c.YEAR)+""+c.get(c.MONTH));
4TimeZone.setDefault(TimeZone.getTimeZone("GMT +8");
5set(int year, int month, int date);//年月日
6set(int year, int month, int date, int hourOfDay, int minute);//年月日时分
7set(int year, int month, int date, int hourOfDay, int minute, int second);//年月日时分秒

集合

list set map

数组是定长的,可以存放基本类型和引用类型,访问较快

集合是可变长度的,集合只能存放引用类型,java.util

Iterator接口

Iterator对象称作迭代器,用来方便的实现对容器内的元素进行遍历操作

set,无序的集合--不允许重复数据,去重--HashSet

list有序的集合--允许重复--ArrayList,LinkedList

map,key/value集合.

Set

HashSet 按照hash码排序

HashSet的特性在于其内部对象的散列存取,即采用哈希技术

TreeSet 按照自然顺序排序

TreeSet存入的顺序跟存储的顺序不同,但是存储是按照排序存储的

对比

集合对比

集合常用方法

size()获取集合大小

isEmpty()判断集合是否为空

contains()判断集合当中是否包含制定元素

toArray()转换成对象数组

List

ArrayList 基于数组的 线性表 按照存入的顺序放置的 适合随机查询的场合 建议用普通for循环读取

LinkedList 基于链表的 对象间彼此串连起来的一个链表 LinkedList元素的插入和删除操作性高 功能上LinkedList要多一些 用迭代器读取会比较快

可以模拟队列(先进先出)和栈(先进后出)

泛型

泛型的使用 可以限制集合只能存入指定类型的数据

List l=new ArrayList();

使用泛型做约束,随机读取时不需要强转

泛型的使用可以限制集合只能存入指定类型的数据

LinkedList(基于链表实现的add remove queue stack随机读取比较慢)

用迭代器读取会比较快

相对于List来说,LinkedList最主要的功能方面的增强是可以在List的头部和尾部添加,删除,取得元素,直接提供了致谢方法的实现.所以他可以非常方便的实现我们数据结构中的藏剑的Stack(栈,先进后出),queue(队列先进先出)等

ListInterator

可以顺序迭代,也可以逆序迭代

可以使用add,remove

文件与流

持久化操作:

  • 文件里
  • 数据库里
  • Java.io包里

文件分隔符

以下两种路径书写方式windows操作下都可以

File path1=new File("d:/io");
File path2=new File("d:\io");

linux下路径是

File linux_path=new File("/root/home");

如果我想两种系统都通用

第一种方式用/方式
第二种方式 用File.separator
1File path_ty=new File("d:"+File.separator+"io");
2System.out.println(path_ty);

文件操作

1exists() 判断是否存在
2isDirectory() 是否目录
3isFile() 是否文件
4listFiles() 文件列表

文件流

输入流: 从文件--->内存或程序(in.read )

输出流:从程序或内存-->文件(out.write)

按处理数据的单位不同

字节流(以字节形式byte[]读取的 音频视频word excel)

字符流(char String 文本类型文件)

按功能不同

节点流(直接跟文件交互的 低级流)

处理流(缓冲流 高级流)

高级流要用到低级流的功能

Java语言中,控制数据流的类都放在java.io包中

Scanner sc=new Scanner(System.in)

抽象基类 低级流(节点流)高级流(缓冲流)

抽象基类 低级流(节点流) 高级流(缓冲流)
字节流 InputStream FileInputStream BufferedInputStream
OutputStream FileOutputStream BufferedOutputStream
字符流 Reader FileReader BufferedReader
Writer FileWriter BufferedWriter(PrintWriter)

对象序列化

1fos=new FileOutputStream("d:/io/kangdl.txt");
2oos=new ObjectOutputStream(fos);
3oos.writeObject(kangdl);

对象反序列化

1fis=new FileInputStream("d:/io/kangdl.txt");
2ois=new ObjectInputStream(fis);
3Student s=(Student) ois.readObject();

多线程

多线程作用:

提高并发处理问题的能力,提升性能,多个人干同一件事。

用到的技术:继承(Thread类) 实现(接口Runnable)

无论是继承还是实现,最后都要写run()方法

线程级别:

Thread.MIN_PRIORITY //1

Thread.NORM_PRIORITY // 5

Thread.MAX_PRIORITY // 10

缺省时线程具有NORM_PRIORITY

方法

sleep()方法

睡眠

wait()方法

等待

yield方法

让行

join方法

加入

网络编程

java.net包中

UDP

Udp (User Datagram Protocal)

 1public class UdpServer {
 2	public static void main(String[] args) throws IOException {
 3        //一是启动一个监听端口,用来监听客户端连接
 4		//接收客户端报文,打印出来
 5		//1、建立基于udp的socket服务,监听指定端口
 6		DatagramSocket server=new DatagramSocket(5000);
 7		//构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
 8		//byte[] buf, int length, InetAddress address, int port
 9		//buf-要接收的数据包
10		//length-接收到的的数据包的长度
11		byte[] buf=new byte[1024];
12		DatagramPacket packet=new DatagramPacket(buf, buf.length);
13		while(true){
14		server.receive(packet);
15		//收到包以后,要转成string形式
16		//String 在一介构造方法,可以转换byte数组为字符串,而且可以指定编码方式
17		String str=new String(buf,0,buf.length);
18		System.out.println("服务端收到的报文"+str);
19		}
20		server.close();
21	}
22}
23
24
25public class UdpClient {
26	public static void main(String[] args) throws IOException {
27        //一是启动一个监听端口,用来监听客户端连接
28		//接收客户端报文,打印出来
29		//1、客户端绑定到本地主机上任何可用的端口。用于发送
30		DatagramSocket client=new DatagramSocket();
31		//构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
32		//byte[] buf, int length, InetAddress address, int port
33		//buf-要接收的数据包
34		//length-接收到的的数据包的长度
35		//我要接送用户从控制台输入
36		while(true){
37		System.out.println("请输入您要发送到服务端的内容:");
38		Scanner sc=new Scanner(System.in);
39		//得到字符串
40		String sendStr=sc.nextLine();
41		InetAddress address=InetAddress.getByName("127.0.0.1");
42		//实际收到的数据包
43		DatagramPacket packet=new DatagramPacket(sendStr.getBytes(), sendStr.getBytes().length,address,5000);
44		//调用 DatagramSocket的send方法进行发送
45		client.send(packet);
46		}
47		//server.close();
48	}
49}

TCP

Tcp(Transmission Control Protocol)

Tcp三次握手(四次)
MINA (心跳包 如果三秒发一次心跳 如果发三次对方无应答 认为这个连接死 自动重连 sessionOpen sessionClose sessionException )
Socket编程 封包时封包头和包体 包头:什么包括指令类型1001 包总长(20+包体长度)
Tcp三次握手保证连接可靠性 以后靠心跳包维持连接
Tcp连接之后,自带输入流和输出流 ----
 1public class TcpServer {
 2public static void main(String[] args) throws IOException {
 3	ServerSocket ss=new ServerSocket(5051);
 4	System.out.println("服务端已启动,等待客户端连接");
 5	while(true){
 6	Socket socket=ss.accept();
 7	System.out.println("收到客户端信息");
 8	//输入流socket.getInputStream() 低级流
 9	DataInputStream dis=new DataInputStream(socket.getInputStream());
10	//读取信息
11	String str=dis.readUTF();
12	//打印
13	System.out.println("收到客户端发送的消息"+str);
14	//关闭socket和流
15	socket.close();
16	dis.close();
17	}
18}
19}
20
21public class TcpClient {
22
23	public static void main(String[] args) throws UnknownHostException, IOException {
24		//通过new Socket建立与服务端的连接
25		Socket socket=null;
26		
27		//接受控制台输入
28		while(true){
29		//通过socket内置的输出流(outputStream给服务端发消息---->封成高级流)
30		socket=new Socket("127.0.0.1", 5051);
31		System.out.println("请输入要发送到服务端的消息");
32		Scanner sc=new Scanner(System.in);
33		String str=sc.nextLine();
34		DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
35		dos.writeUTF(str);
36		dos.flush();
37		dos.close();
38		}
39		//socket.close();
40	}
41
42}

多线程的service

 1服务端程序
 2public class TcpServer4Thread {
 3public static void main(String[] args) throws IOException {
 4	ServerSocket ss=new ServerSocket(5051);
 5	System.out.println("服务端已启动,等待客户端连接");
 6	while(true){
 7	Socket socket=ss.accept();
 8	Services services= new Services(socket);
 9	Thread t=new Thread(services);
10	t.start();
11	}
12}
13}
14public class Services implements Runnable {
15	Socket socket;
16	Services(Socket socket) {
17		super();
18		this.socket = socket;
19	}
20	@Override
21	public void run() {
22		// TODO Auto-generated method stub
23		System.out.println("收到客户端信息");
24		//输入流socket.getInputStream() 低级流
25		DataInputStream dis=null;
26		DataOutputStream dos=null;
27		try {
28		dis= new DataInputStream(socket.getInputStream());
29		dos=new DataOutputStream(socket.getOutputStream());
30		while(true){
31		//读取信息
32		String str=dis.readUTF();
33		//打印
34		System.out.println("收到客户端发送的消息"+str);
35		//-----------------------------------------------------以下是回路(给客户端发送消息的)
36		//System.out.println("请输入要回传给客户端的信息");
37		//Scanner sc=new Scanner(System.in);
38		//String result=sc.nextLine();
39		
40		dos.writeUTF("处理后的消息--------->"+str);
41		dos.flush();
42		
43		}
44		} catch (IOException e) {
45			// TODO Auto-generated catch block
46			e.printStackTrace();
47		}finally{
48			try {
49				//关闭socket和流
50				socket.close();
51				dis.close();
52				dos.close();
53			} catch (IOException e) {
54				// TODO Auto-generated catch block
55				e.printStackTrace();
56			}
57			
58		}
59	}
60
61}
62客户端程序
63
64public class TcpClient {
65
66	public static void main(String[] args) throws UnknownHostException, IOException {
67		//通过new Socket建立与服务端的连接
68		Socket socket=null;
69		socket=new Socket("127.0.0.1", 5051);
70		//接受控制台输入
71		while(true){
72		//通过socket内置的输出流(outputStream给服务端发消息---->封成高级流)
73		System.out.println("请输入要发送到服务端的消息");
74		Scanner sc=new Scanner(System.in);
75		String str=sc.nextLine();
76		DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
77		dos.writeUTF(str);
78		dos.flush();
79		//---------------------------以下是读取服务端发送过来的消息
80		//输入流socket.getInputStream() 低级流
81		DataInputStream dis=new DataInputStream(socket.getInputStream());
82		//读取信息
83		String str1=dis.readUTF();
84		//打印
85		System.out.println(str1);
86		/*socket.close();
87		dis.close();
88		dos.close();*/
89		}
90		}
91}

jdbc编程

Step1 把ojdbc14.jar放到d:

Step2 在工程里引入jar

右键工程-build path-configure build path

什么是JDBC

JDBC(Java DataBase Connectivity) 称为Java数据库连接,它是一种用于数据库访问的应用程序API,由一组用Java语言编写的类和接口组成

为什么用JDBC?

有了JDBC就可以用同一的语法对多种关系数据库进行访问,而不用担心其数据库操作语言的差异。(前提是需要提供不同的数据库驱动)简化了数据库开发

注意:JDBC用于访问关系型数据库(mysql(免费) sql server(收费) oracle(收费) db2(收费的 IBM))

JDBC优缺点

优点:

JDBC使得编程人员从复杂的驱动器调用命令和函数中解脱出来,可以致力于应用程序中的关键地方。

JDBC支持不同的关系数据库,这使得程序的可移植性大大加强。

JDBC API是面向对象的,可以让用户把常用的方法封装为—个类,以备后用

缺点:

使用JDBC,访问数据记录的速度会受到一定程度的影响。

JDBC结构中包含不同厂家的产品,这就给更改数据源带来了很大的麻烦。

JDBC核心类库包含在java.sql包中。

DriverManager:负责管理JDBC驱动程序。使用JDBC驱动程序之前,必须先将驱动程序加载并注册后才可以使用,同时提供方法来建立与数据库的连接。

SQLException-有关数据库操作的异常

接口:

Connection:特定数据库的连接(会话)。在连接上下文中执行SQL语句并返回结果。

PreparedStatement:表示预编译的 SQL 语句的对象。(安全级别高)

Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。

ResultSet :表示数据库结果集的数据表,通常通过执行查询数据库的语句生成 。

CallableStatement :用于执行 SQL 存储过程的接口(了解)

创建JDBC应用

创建JDBC应用程序的步骤

1. 载入JDBC驱动程序 (DrvierManager)
2. 定义连接URL
3. 建立连接 (Connection 第2步是为第3步做准备)
4. 创建Statement对象 (Statement(静态)/ PreparedStatement(动态))
5. 执行查询或更新 (executeQuery(select)/executeUpdate(添加 修改删除))
6. 结果处理 (ResultSet )
7.关闭连接

Class.forname参考链接

Statement

 1public class JdbcQuery {
 2	public static void main(String[] args) {
 3		// 第一步加载数据库驱动(OracleDriver完全限定名,包名+类名 包名小写,类名大驼峰)
 4		Connection conn = null;
 5		Statement st = null;
 6		ResultSet rs = null;
 7		try {
 8			// 利用反射原理,注册驱动
 9			Class.forName("oracle.jdbc.driver.OracleDriver");
10			// step2定义url 本机ip:localhost 127.0.0.1
11			String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
12			String user = "scott";
13			String password = "tiger";
14			// step3 建立与数据库的连接
15			conn = DriverManager.getConnection(url, user, password);
16			if (conn != null) {
17				System.out.println("数据库连接成功");
18			}
19			// ORA-12505异常参见https://blog.csdn.net/king0406/article/details/73929163
20			// 4.创建Statement对象 (Statement(静态)/ PreparedStatement(动态))
21			st = conn.createStatement();
22			// 5.执行查询或更新 (executeQuery(select)/executeUpdate(添加 修改删除)) 不用加;
23			rs = st.executeQuery("select * from emp where deptno=10");
24			// 6.结果处理 (ResultSet )
25			while (rs.next()) {
26				int empno = rs.getInt("empno");
27				String ename = rs.getString("ename");
28				System.out.println(empno + "   " + ename);
29			}
30		} catch (ClassNotFoundException | SQLException e) {
31			// TODO Auto-generated catch block
32			System.out.println("连接异常" + e.getMessage());
33			e.printStackTrace();
34		} finally {
35			try {
36				// 7.关闭连接 做一个判空处理,防止产生空指针异常
37				if(rs!=null){rs.close();}
38				if(st!=null){st.close();}
39				if(conn!=null){conn.close();}
40			} catch (SQLException e) {
41				// TODO Auto-generated catch block
42				System.out.println("关闭数据库连接异常");
43				e.printStackTrace();
44				
45			}
46		}
47
48	}
49}
50public class JdbcUpdate {
51public static void main(String[] args) {
52	Connection conn=null;
53	Statement st=null;
54	//1
55	try {
56		Class.forName("oracle.jdbc.driver.OracleDriver");
57	//2
58		String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";
59		String user="scott";
60		String password="tiger";
61     //3		
62		conn=DriverManager.getConnection(url, user, password);
63	 //4
64		st=conn.createStatement();
65	 //5 insert update delete 我们需要调查用statement.executeUpdate 返回值是int 操作成功了几条
66		int count=st.executeUpdate("update emp set ename='汪汪',deptno=20 where empno=888");
67		System.out.println("操作成功了"+count+"条");
68	//6没有
69	} catch (ClassNotFoundException|SQLException e) {
70		// TODO Auto-generated catch block
71		e.printStackTrace();
72	}finally{
73		try {
74			if(st!=null){st.close();}
75			if(conn!=null){conn.close();}
76		} catch (SQLException e) {
77			// TODO Auto-generated catch block
78			e.printStackTrace();
79		}
80
81	}
82}
83}

PreparedStatement

1. statement适合静态语句 preparedStatement适合动态sql 灵活性高

2. preparedStatement可读性高

3. 安全性高,可以防止sql注入

4. 执行效率高

CallableStatement

1. 存储过程

1CREATE PROCEDURE add_pro(a int,b int,out sum int)
2BEGIN
3set sum = a + b;
4END;

2.调用

 1/**
 2 * Created by Jiqing on 2016/12/20.
 3 */
 4public class ConnMySql {
 5    public static void main(String[] args) throws Exception {
 6        // 1.加载驱动
 7        Class.forName("com.mysql.jdbc.Driver");
 8
 9        // try() {} 语法中小括号中的资源会自动回收
10
11        try (
12            // 2.连接数据库
13            Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/tpshop","root","123456");
14            CallableStatement cstmt = conn.prepareCall("{call add_pro(?,?,?)}")
15        )
16        {
17            cstmt.setInt(1,4);
18            cstmt.setInt(2,5);
19            cstmt.registerOutParameter(3,Types.INTEGER);
20            cstmt.execute();
21            System.out.println("执行结果是:"+cstmt.getInt(3));
22        }
23    }
24}

executeQuery、executeUpdate 和 execute

 1Statement 接口提供了三种执行 SQL 语句的方法:executeQuery、executeUpdate 和 execute。使用哪一个方法由 SQL 语句所产生的内容决定。
 2方法executeQuery 
 3用于产生单个结果集的语句,例如 SELECT 语句。 被使用最多的执行 SQL 语句的方法是 executeQuery。这个方法被用来执行 SELECT 语句,它几乎是使用最多的 SQL 语句。
 4方法executeUpdate
 5用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE 语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。
 6使用executeUpdate方法是因为在 createTableCoffees 中的 SQL 语句是 DDL (数据定义语言)语句。创建表,改变表,删除表都是 DDL 语句的例子,要用 executeUpdate 方法来执行。你也可以从它的名字里看出,方法 executeUpdate 也被用于执行更新表 SQL 语句。实际上,相对于创建表来说,executeUpdate 用于更新表的时间更多,因为表只需要创建一次,但经常被更新。
 7方法execute:
 8用于执行返回多个结果集、多个更新计数或二者组合的语句。因为多数程序员不会需要该高级功能
 9execute方法应该仅在语句能返回多个ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用。当执行某个已存储过程或动态执行未知 SQL 字符串(即应用程序程序员在编译时未知)时,有可能出现多个结果的情况,尽管这种情况很少见。
10因为方法 execute 处理非常规情况,所以获取其结果需要一些特殊处理并不足为怪。例如,假定已知某个过程返回两个结果集,则在使用方法 execute 执行该过程后,必须调用方法 getResultSet 获得第一个结果集,然后调用适当的 getXXX 方法获取其中的值。要获得第二个结果集,需要先调用 getMoreResults 方法,然后再调用 getResultSet 方法。如果已知某个过程返回两个更新计数,则首先调用方法 getUpdateCount,然后调用 getMoreResults,并再次调用 getUpdateCount。
11对于不知道返回内容,则情况更为复杂。如果结果是 ResultSet 对象,则方法 execute 返回 true;如果结果是 Java int,则返回 false。如果返回 int,则意味着结果是更新计数或执行的语句是 DDL 命令。在调用方法 execute 之后要做的第一件事情是调用 getResultSet 或 getUpdateCount。调用方法 getResultSet 可以获得两个或多个 ResultSet 对象中第一个对象;或调用方法 getUpdateCount 可以获得两个或多个更新计数中第一个更新计数的内容。
12当 SQL 语句的结果不是结果集时,则方法 getResultSet 将返回 null。这可能意味着结果是一个更新计数或没有其它结果。在这种情况下,判断 null 真正含义的唯一方法是调用方法 getUpdateCount,它将返回一个整数。这个整数为调用语句所影响的行数;如果为 -1 则表示结果是结果集或没有结果。如果方法 getResultSet 已返回 null(表示结果不是 ResultSet 对象),则返回值 -1 表示没有其它结果。也就是说,当下列条件为真时表示没有结果(或没有其它结果):
 1stmt.execute(queryStringWithUnknownResults);
 2while (true) {
 3    int rowCount = stmt.getUpdateCount();
 4    if (rowCount > 0) { // 它是更新计数
 5        System.out.println("Rows changed = " + count);
 6        stmt.getMoreResults();
 7        continue;
 8    }
 9    if (rowCount == 0) { // DDL 命令或 0 个更新
10    System.out.println(" No rows changed or statement was DDL command");
11    stmt.getMoreResults();
12    continue;
13}
14// 执行到这里,证明有一个结果集
15// 或没有其它结果
16ResultSet rs = stmt.getResultSet;
17if (rs != null) {
18    . . . // 使用元数据获得关于结果集列的信息
19while (rs.next()) {
20    . . . // 处理结果
21    stmt.getMoreResults();
22    continue;
23}
24break; // 没有其它结果

项目阶段:

1. 立项

2. 需求分析(参考者 各种参考者都完成哪些功能

1. 用例图USER-CASE

2. 《需求规约》)

3. 概要设计(界面原型 部署图 架构图《概要设计说明书》)

4. 详细设计(接口 类 方法 属性 流程图 时序图 数据库表《详细设计说明书》《数据库设计说明书》)

5. 编码(源代码 文件 )

6. 测试(单元测试和集成测试(功能测试) 性能测试 bug修正)

7. 部署实施 上线运行

数据库设计的三大范式:

第一范式(1NF)

所谓第一范式(1NF)是指在关系模型中,对域添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。简而言之,第一范式就是无重复的域。

第二范式(2NF)

在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分(要有主键)。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。例如在员工表中的身份证号码即可实现每个一员工的区分,该身份证号码即为候选键,任何一个候选键都可以被选作主键。在找不到候选键时,可额外增加属性以实现区分,如果在员工关系中,没有对其身份证号进行存储,而姓名可能会在数据库运行的某个时间重复,无法区分出实体时,设计辟如ID等不重复的编号以实现区分,被添加的编号或ID选作主键。(该主键的添加是在ER设计时添加,不是建库时随意添加)

第三范式(3NF) (消除冗余)

在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性,也就是在满足2NF的基础上,任何非主属性不得传递依赖于主属性。


标题:Java初学笔记(很早的笔记,自己最初学习Java时的笔记,记录的可能有些凌乱)
作者:GunVeda
地址:http://gunveda.top/articles/2019/10/23/1571821550637.html