Java 的配置: 

JAVA_HOME 指向JDK的安装目录(可以使用软连接) 

PATH 要包含JDK的bin目录 

CLASSPATH 可以简单的使用"." 


一个Linux 实例: 

JAVA_HOME=$HOME/java 

PATH=$JAVA_HOME/bin:$PATH 

CLASSPATH=. 

export JAVA_HOME PATH CLASSPATH 


使用source 测试profile 脚本 

source .bash_profile 


使用命令测试是否成功: 

java -version (应该是1.5的) 

mv 

cd 


经验是需要通过实践(训练)来获得! 


编译Java源文件, 生成.class 字节码文件 

工具:javac 

javac -d 目标目录 filename.java 

如: javac -d bin HelloWorld.java 

这个命令把HelloWorld.java编译成.class 

输出到bin文件夹中,在文件夹bin中还生成包 


执行Java 类文件。 

进入bin目录。执行:java day01.HelloWorld 


包名.类名:全限定名 


java 包名.类名 

Java类的执行过程:Java会利用CLASSPATH搜索 

类(全限定名),找到类对应的类文件, 

加载并执行。 


CLASSPATH是Java类的搜索路径 



package day01; 

public class HelloWorld{ 

 public static void main(String[] args){ 

 System.out.println("Hello World!"); 

 } 

} 

编译: javac -d bin HelloWorld.java 

运行: cd bin 

 java day01.HelloWorld 

 cd .. 

 export CLASSPATH=.:$HOME/sd1009/bin 

 java day01.HelloWorld 


jar: Java发布包管理。 

jar -cvf jarfile.jar package1 package2... 

jar -xvf jarfile.jar 


Java可以搜索CLASSPATH上配置的jar文件内容 


打包实验 

cd bin 

jar -cf ../demo.jar day01 

cd 

export CLASSPATH=.:$HOME/sd1009/demo.jar 

java day01.HelloWorld 


解包实验,找到rt.jar, 释放开,找到里面的 

String.class 文件,在包:java.lang中。 


mkdir rt 

cd rt 

jar -xf $JAVA_HOME/jre/lib/rt.jar 

cd java/lang 

ls | String.class 


Java 注释,是被Javac忽略的部分 

经常用来为添加对代码的解释,提高软件的 

可读性。还可以取消代码的功能。 


1 多行注释 /* ... */ 

2 单行注释 //... 

3 文档注释 /** ... */ 


可以使用javadoc导出java源代码中的文档注释 

,生成Javadoc手册。(简单掌握) 

javadoc -d doc String.java 


二进制基础 


192(10)-> 11000000(2) 


128 64 32 16 8 4 2 1 

1 1 0 0 0 0 0 0 


计算机处理二进制:采用Byte为单位! 

1Byte = 8bit 

1(10) -> 00000001 


16进制(0~9a~f) 

41(16) -> 4*16^1 + 1*16^0 = 65(10) 

0100 0001(2)=65(10) 

 4 1 (16) 


16进制是二进制的简写形式! 


数字式计算机只认识二进制数字! 

16进制是为了方便人类简写二进制提供的 

一种编码方案! 


中(4e2d) 

0100 1110 0010 1101 


二进制补码 

计算机内部只有二进制补码是数字! 

正数的补码就是这个数本身 

负数的补码是这个数取反加一 

最高位是符号位,0表示正数,1表示负数 

二进制补码 可以保证符号位参与运算, 

并且保证结果是正确的。 


byte:-65(10)-> bf(16) 


65(10)-> 0100 0001(2)-> 41(16) 

-65(10)-> -100 0001(2)->1011 1111(2)->bf(16) 

-1(10)-> - 000 0001(2)->1111 1111(2)->ff 


8位补码: 

1111 1111(2补)-> - 000 0001(2)=-1 

0111 1111 MAX 127 7f 

1000 0000 MIN -128 80 


16位补码表示 

-1:ffff 

MAX: 7fff; 

MIN: 8000; 


32位补码表示 

-1:ffffffff 

MAX: 7fffffff; 

MIN: 80000000; 


-97(10)-> - 110 0001(2) 

 -> 1001 1111(2补) 

 -> 9f(16) 

96(10)->0110 0000(2) 


 96 01100000 

 -97 10011111 

----------------------------------- 

 11111111 


 -97 10011111 

X -1 11111111 

------------------------------------ 

 10011111 

 10011111 

 10011111 

 10011111 

 10011111 

 10011111 

 10011111 

 10011111 

------------------------------------ 

 01100001 -> 97 


package day02; 


public class BinDemo{ 

 public static void main(String[] args){ 

 int a = (byte)0xbf ;//1011 1111 

 System.out.println(a);//-65 

 } 

} 


运算符 


数学运算符 

1 封闭性:同种数据类型参与运算, 

 得到同种类型的结果 

2 比int类型小的数据类型运算, 

 实际上是int类型运算。 

3 常量运算是被Javac优化的运算, 

 相当于运算以后的字面量。 

4 四则运算有溢出风险, 

 Java不对溢出进行检查 


 byte b = 5; 

 byte c = 6; 

 byte e = 5+6;//被Javac优化为11 

 //byte d = b+c;//错,实际上是int运算 

 //byte d = (byte)b+c;//错 

 byte d = (byte)(b+c); //对 

 System.out.println(e); 

 System.out.println(d); 

 int x = 1024*1024*1024*2;//上溢出 

 long l = 1024*1024*1024*2;//上溢 

 //long j = 1024*1024*1024*2*2L;//上溢 

 long j = 1024L*1024*1024*2*2;//正确 

 System.out.println(x); 

 System.out.println(l); 

 System.out.println(j); 

 int g = 3/2;//1,下溢出,舍掉余数,整除 

 double f = 3D/2;//1.5 



% 求余数,取模运算 

取余运算是周期函数 

y=f(x)= x%5 

x:0 1 2 3 4 5 6 7 8 9 10 11 12 ... n 

y:0 1 2 3 4 0 1 2 3 4 0 1 2 ... 


//逻辑运算 

int age = 18; 

char sex = '男'; 

boolean isChild = age<16;//false 

boolean isMan = sex=='男'; 

boolean isBoy = isChild && isMan; 

boolean isGirl = isChild && ! isMan; 

boolean isChilden = isBoy || isGirl; 


if(isBoy){ 

 System.out.println("你好,小伙子!"); 

} 


位运算 

取反运算 

int i = -1; 

int j = ~i;//0 

i = 0x7fffffff; 

i = ~i;//0x80000000 


按位与 

1&1->1, 0&1->0, 0&1->0, 0&0->0 

掩码运算 

int mask = 0xf;// 0x0000000f 

int c = '中'; // 0x00004e2d; 

int l = c & mask;// 0x0000000d; 


或运算 

1|1-> 1, 0|1->1, 0|1->1, 0|0->0 


把中国两个字拼成一个int数据 

再拆开 

int c1 = 0x4e2d0000;// 0x4e2d0000 

int c2 = '国';// 0x0000xxxx 

int c3 = c1 | c2;// 0x4e2dxxxx 

int mask = 0x0000ffff; 

char cx = (char)(c3 & mask); 



移位 

>> 有符号移位,相当于数学除法, 

高位:正数补0,负数补1,保证符号位不变 

如: -2 >> 1 结果是 -1,相当于数学 -2/2 

-2:11111111 11111111 11111111 11111110 

-2 移位以后,高位补1: 

-1:111111111 11111111 11111111 1111111 


<< 数学乘法 每次乘2 

给定n 产生n位的掩码 

n=4; 

mask = ~(-1<<n); 


>>> 无符号右移, 高位永远补0 

比较如下表达式: 

-1>>>1 -> 0x8fffffff, 

-1>>1 -> 0xffffffff, 

1>>1 -> 0x00000000 


++, -- 

先++(++a):先将a加1,然后a的值作为整个 

 表达式的值。 

后++(a++):先将a的值作为整个表达式的值 

 然后再将a加1。 

int a = 1; 

int b = a++; 

int c = ++a; 

a=a++; 

a=++a; 


int i = 0; 

int x = i++%5; 

x = i++%5; 

x = i++%5; 

x = i++%5; 

x = i++%5; 

x = i++%5; 

x = i++%5; 

x = i++%5; 

x = i++%5; 


条件运算符: ? : 

String msg = isBoy ? "小伙子" : "小姑娘"; 

计算查询结果显示页数的实例: 

int rows = 31;//查询结果数量 

int size = 15;//每页数量 

int pages = 

 rows%size==0 ? rows/size : rows/size+1; 


运算符的优先级 

运算符的结合型 

int a = b+c+d; 

int a = b = c = 1; 

int a=3; 

int b = 2 + (a+=5); 


作业: 

1 把ABCD字符拼成一个int类型数据 

 然后再拆开 

2 实现华氏度到摄氏度的转换: 


提示: 

Scanner console = 

 new Scanner(System.in); 

int val = console.nextInt(); //读取温度 

String t = console.next(); //读取温度类型 

char c = t.charAt(0);//获得温度类型的字符 

if(c == 'f'){//比较稳定类型 


} 

double d = 1.78; 

int x = (int)(d+0.5)//四舍五入 


选择流程控制 

1 尽量减少使用否定条件作为条件表达式 

2 尽量减少使用else 

3 尽量减少嵌套使用! 


判断某一天是否有航班(if 位运算) 

3 

byte 00010101 

byte 00001000 


for循环 

练习: 

 从控制台读取数字字符串,转换为整数 

 如:"23765" -> 23765 

提示: 

for(int i=0; i<str.length(); i++){ 

 //每个字符 

 char c = str.charAt(i); 

 int n = c - '0'; 

 sum = sum*10 + n; 

} 


while循环 

实例: 

输出一个整数的二进制字符串 

如:0x15 -> "10101" 

提示: 

int a = console.nextInt(); 

int mask = 1; 

String s = ""; 

int last = a & mask; 

s = last + s; 

a>>>=1; //a = a>>>1; 

last = a & mask; 

s = last + s; 

a>>>=1; 

last = a & mask; 

s = last + s; 

a>>>=1; 

//a==0 结束 

//... 


do ... while 循环 

实例: 

 整数转十六进制字符串 

如:20013 -> 4e2d 

提示: 

do{ 

 last>9 

 last -> 'a'~'f'; 'a' + (last-10) 

}while(num != 0); 


调试: 

1 利用输出语句输出软件的状态(数据) 

2 运行软件,把输出的状态和理想数据比较 

 找出问题所在。 


void listFiles(String path){ 

 //循环当前目录内容{ 

 //如果当前项目是目录 

 // 再列出这个目录内容listFiles(目录) 

 //} 

} 


数组: 


int score1 = console.nextInt(); 

int score2 = console.nextInt(); 

int score3 = console.nextInt(); 

int score4 = console.nextInt(); 

int score5 = console.nextInt(); 

//... 


int[] score = new int[100]; 

for(int i=0; i<score.length; i++){ 

 score[i]=console.nextInt(); 

} 


1 数组长度固定,元素类型相同 

2 数组声明: 

 int[] ary;//推荐使用 

 int ary[];//不建议使用!符合C程序员的习惯 

3 初始化: 

 int[] ary = {1,3,3,'1'};//{}静态初始化 

 直接使用{} 只能在初始化时候使用, 

 不能作为赋值语句出现 

 int[] ary = new int[]{1,2,4};//动态初始化 


 //ary = {2,4}; //错,{}不能作为赋值语句 

 ary = new int[]{2,4};//对 


 数组初始化必须明确长度! 

 int[] ary = new ary[100]; 

 //int[] ary = new ary[];//错误 

 int[] ary = {};//对,0长度 

 int[] ary = new int[0];//对,0长度 


 数组元素默认自动初始化,初始化为“零”值 

 “零”值: 

 int, long, byte, short, float, double->0 

 char -> '\u0000' ==0 

 boolean -> false 

 引用类型 -> null 


 int[] ary = new ary[10]; 

 System.out.println(ary[3]);//0 //对 


 int[] ary = new ary[4]; 

 ary[3]=1; 

 ary[2]=2; 

 //ary[4]=5; //错误,运行时候,越界 

 int[] a2 = ary; 

 System.out.println(a2[0]); 


4 如果访问超过数组下标范围, 

 运行时会出现数组越界错误 


5 数组变量的赋值,是引用地址的复制, 

 赋值结果是两个变量引用同一数组对象实例 

 int[] a2 = ary; 


6 如果需要复制一个数组实例,需要如下 

 int[] ary = {1,2,4,5}; 

 int[] ary1 = new int[ary.length]; 

 for(int i=0; i<ary.length; i++){ 

 ary1[i] = ary[i]; 

 } 

 ary1 就是 ary的副本了! 


 Java 提供了数组复制到方法System.arraycopy(); 

 int[] ary = {1,2,4,5}; 

 int[] ary1 = new int[ary.length]; 

 System.arraycopy(ary, 0, ary1, 0, ary.length); 


二维数组 

初始化: 

 int[][] ary = new int[2][3]; 

 int[] ary1 = ary[0]; 

 静态初始化 

 int[][] ary = {{1,2},{3,4,5},{4,5,6,8}}; 

 初始化同时指定元素 

 int[][] ary = new int[][]{{1,2},{3,4,5},{4,5,6,8}}; 

 只指定第一维的长度 

 int[][] ary = new int[2][]; 

 ary[0] = new int[5]; 

 ary[1] = new int[2]; 


数组实例: 

1 EAN-13码的检查码的算法 ,例如假设一EAN-13码各码代号如下: 

N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 N12 C 

  检查码之计算步骤如下: 

  C1 = N1+ N3+N5+N7+N9+N11 

 C2 = (N2+N4+N6+N8+N10+N12)× 3 

  CC = (C1+C2) 取个位数 

  C (检查码) = 10 - CC (若值为10,则取0) 


2 身份证第18位计算法 

 身份证第18位(校验码)的计算方法 


  1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。 

  2、将这17位数字和系数相乘的结果相加。 

  3、用加出来和除以11,看余数是多少? 

  4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X-9-8-7-6-5-4-3-2。 

 5、通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。 

  例如:某男性的身份证号码是34052419800101001X。我们要看看这个身份证是不是合法的身份证。 

  首先我们得出前17位的乘积和是189,然后用189除以11得出的结果是17+2/11,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的数字是x。所以,可以判定这是一个合格的身份证号码。 


3 实现文字的竖排 


排序: 

1 选择排序:通过n-1轮比较,每轮找到一个最小的放到前面。 


2 冒泡排序:每次比较相邻的元素,如果前一个大交换,每轮比较会把最大的交换到最后,完成一个最大的排序。经过n-1轮比较排序完毕。冒泡就是比喻每次有一个大数飘到最后。 


插入式排序:把后半部的每个元素插入到前 

 半部已经排序的序列中。 


eclipse:日食、月食 


www.eclipse.org 


Eclipse 是用Java开发。不是纯Java开发 

图形界面使用SWT 包含一定的C代码,不是绝对 

的跨平台的。 

SWT 提供了几乎全部的主流平台的支持 

Eclipse可以在所有主流平台(OS)上运行 

下载要注意平台(OS)版本 


下载:Java 开发版本。 


Eclipse就是一个压缩包。释放就可以 

Linux 安装实例: 

tar -xzf /opt/eclipse-SDK-3.2.2-linux-gtk.tar.gz 

./eclipse/eclipse 


Eclipse 中的概念: 

 workspace: 一个项目默认保存目录 

 默认: /home/soft01/workspace 

 Project: 代表一个软件工程 


类:逻辑上用来描述具体实体概念的。 

如:图书馆中的书,一卡通 

具体概念(类)是一个系统所管理的事务的抽象。 


具体概念的实例叫:对象。 


引用(变量):用来操作对象的句柄。 


构造器:描述创建一个对象的过程。 

构造器的参数,是创建一个对象依赖的条件 

默认构造器:如果类没有声明任何构造器 

 Javac 默认提供一个无参数构造器,反之 

 如果声明了任何的构造器,Javac将不再提供。 


Java 调用方法,一定的存在。Java根据“方法 

签名” 识别调用方法 

方法签名: 方法名称和参数列表。 


方法的重载:方法名相同,方法参数不同(参数 

类型,参数顺序,和参数名称无关!) 

构造器可以重载,经常重载 


不能在空(null)引用上访问属性和方法 

否则的话会出现空指针异常。 

Debug 提示: 找在那个引用 

调用了方法或者属性,研究这个引用在哪里 

赋值的对象! 


一个Java源文件只能有一个共有类,文件名必须和公有类名一致 

 1 一个Java文件可以有多个类 

 2 如果没有公有类文件名和任意类名一致 

 3 建议一个文件一个类,并且都是公有类 


文件中的关键字顺序: 

 1 有包的话,必须在首行 

 2 import 有的话必须在package之后 

 3 class 在 import之后 

 4 方法要声明在类中。 

 5 语句要写在方法中。 

 6 类中可以声明变量,但是不是语句! 



this 的用法: 

 1 引用当前对象本身 

 2 this() 调用当前类的其他构造器,根据参数类型选择, 

 合适的构造器。经常用来进行重载构造器代码的重用。 

 this()必须写在构造器的第一行! 


访问修饰: 

 默认修饰: 类内部和同包内部可以访问,包外部不可见。 

 私有的: 只在类的内部可以访问。 

 公有的:在任何地方都可以访问。 

 保护的:在子类和同包中可以访问 


 1 习惯上属性,方法,尽可能私有的。 

 2 提供适当是属性访问方法(getXXX, setXXX) 

 XXX 被称为Java Bean属性 

 3 建议一个文件一个类,并且都是公有类 

 4 在继承中为了子类准备的资源,使用保护的修饰。 


关于Java Bean: 

 1 是一个普通的Java类, 但是要符合一些语法约定 

 2 需要有package 

 3 需要有无参数构造器 

 4 需要实现序列化接口(在IO中仔细学习) 

 5 可以包含由getXxx 和 setXxx 说明的Bean属性 

 boolean Bean属性 的getXxx 可以是 isXxx 

 Bean属性的名称: xxx 

 6 JavaBean 有时候也被称为POJO(老Java对象) 



继承: 语法: class A extends B 

 1 A类是B类的扩展,其中A叫子类,B叫父类。 

 2 子类继承父类的特征和行为。 

 3 语义上表达A是B的字类型,就是:A是一种B 

 如: 蟑螂是昆虫 

 4 Java只允许单继承 

 只有一个父类 

 父类有多个子类 

 5 如果类没有继承任何类,默认继承于Object 


继承中的实例构造 

 1 构造器是不能继承的! 

 2 子类构造器默认递归调用父类无参数构造器。 

 3 创建子类实例默认先递归分配父类空间 

 4 子类实例默认是父类型的实例 

 5 如果父类没有无参数构造器,必须显示的调用 

 父类有参数构造器,使用super() 调用父类构造器 

 6 为了减少麻烦,建议所有类都提供无参数构造器。 

 7 super() 必须写在构造器第一行,和this()互斥 

 在构造器的第一行默认存在super(); 


super: 

 1 调用父类的构造器: super() 

 2 明确访问当前实例父类中的声明属性或方法: super.name 

 super.isRuning(); 


属性 <=> 字段(Field) 


覆盖(重写)Override: 

 1 子类修改父类的行为 

 2 子类提供一个与父类一样方法签名的方法 


Object(东西)对象 


继承中多态现象: 父类型引用子类实例, 会出现多态现象 

 重载和覆盖会造成行为的多态。 

 如:问题有多种实例,可能是单选或者多选 

 汽车是有多种的。 


引用类型转换: 

 1 父类型可以引用子类型实例。子类型实例一定是父类型实例。 

 2 子类型的引用可以赋值给父类型引用,发生自动类型转换 

 3 反之需要强制类型转换,如果不成功,会抛出异常。 

 4 小到大自动完成,大到小需要强制类型转换 

 5 类型转换也叫“造型” 


属性静态绑定(声明时候确定),方法动态绑定(覆盖的结果) 

以上现象造成同一个对象上 

 1 同名属性值会出现不同的结果 

 2 方法的调用都是同一个结果。 

解决方案: 

 1 习惯上子类尽量不定义与父类相同的属性。 

 2 属性尽量私有,使用属性访问方法存取属性。 


总之:按照JavaBean习惯定义任何一个类! 


动态:在运行期分配的资源都是动态的:如对象的属性和方法。 

静态:是指在对象创建之前存在的属性,方法,是属于全体类的。 


static 静态修饰 

 1 可以修饰变量,表示属于类的属性,全体实例共享一份静态 

 变量。 

 2 静态变量可以使用类名访问。 

 3 静态变量可以修饰方法,表示属于类的方法。 

 4 静态方法可以使用类名访问。静态方法属于类全体的公共 

 方法,一般都是不依赖对象工具方法。 

 5 静态方法只能访问静态资源(属性和方法) 

 6 静态代码块,在类的加载后执行, 可以用来初始化一些 

 配置信息,应用的不是非常广泛的。 

 静态属性实例:Math.PI, Math.E, Integer.MAX_VALUE 

 静态方法实例:Math.sqrt() Integet.parseInt() 


类的加载: 

 1 在第一次使用时候加载,按需加载。 

 2 类加载以后分配类的静态变量。 

 3 加载以后立即执行静态代码块。 


final (最终的) 

 1 final修饰属性,不能修改! 

 2 final修饰的局部变量/方法型参数 只能初始化 

 3 final修饰类,类不能再继承 

 4 final修饰方法,方法不能再被覆盖(写出测试代码) 

 5 强烈不建议使用 3,4 ! 


关于常量: 

 1 Java中没有真正的语言意义的常量 

 2 使用static final 声明的成员变量,代表常量。 

 3 习惯上 ”static final 声明的是常量“ 


 abstract 抽象 

 1 abstract 修饰抽象方法,抽象方法不能有方法体 

 2 包含抽象方法的类,一定是抽象类,使用 abstract修饰 

 3 抽象类不能直接实例化,使用抽象概念可以声明引用变量, 

 抽象概念的引用变量可以引用具体的子类实例。 

 4 抽象类只能被继承,子类需要实现抽象类的抽象方法。 


接口(interface) 

 1 所有方法都是抽象的类可以声明成接口。 

 2 接口表达是纯抽象的概念。 

 3 接口中声明的变量只能是常量。默认就是常量(static final)。 

 4 接口中的方法默认都是公有抽象的(public abstract) 

 5 接口不能实例化,只能被实现 

 6 实现一个接口,必须实现所有方法。 

 7 如果不全部实现,这个类一定是抽象类。 

 8 接口可以定义变量,可以引用实现类的实例 

 9 接口相当于实现类的父类型! 

 10 接口之间可以继承,一定是概念的具体化 

 11 类可以实现多个接口,实现多继承,表达:也是概念 


在商业软件中,实体概念之间不推荐使用继承。 

在软件的体系结构中会大量的使用接口,抽象类,继承,实现 

等“继承关系” 维护一个可以扩展到架构。 


关于接口: 

 1 接口的是约定 

 系统分析员定义了接口,程序员实现接口,要实现接口 

 所有的方法,这样分析员就通过接口约束了程序员的实现! 

 接口就是分析员与程序员之间的约定! 


 OOA/OOD -> OOP 

 2 接口也是标准 

 JDBC、JSP/Servlet, DOM ... 



关于equals 

 1 默认是==比较, 

 2 建议覆盖equals,根据对象内容(属性)进行比较 

 自反性:对于任何非空引用值 x,x.equals(x) 

 都应返回 true。 

 对称性:对于任何非空引用值 x 和 y, 

 当且仅当 y.equals(x) 返回 true 时, 

 x.equals(y) 才应返回 true。 

 传递性:对于任何非空引用值 x、y 和 z, 

 如果 x.equals(y) 返回 true,并且 y.equals(z) 

 返回 true,那么 x.equals(z) 应返回 true。 

 一致性:对于任何非空引用值 x 和 y,多次调用 

 x.equals(y) 始终返回 true 或始终返回 false, 

 前提是对象上 equals 比较中所用的信息没有被修改。 

 对于任何非空引用值 x,x.equals(null) 

 都应返回 false。 


方法:hashCode() 

 1 如果覆盖了equals方法,就必须一同覆盖hashCode() 

 2 如果两个对象 equals 比较为true,他们的hashCode返回 

 结果必须一样 

 3 如果两个对象 equals 比较为false,他们的hashCode返回 

 结果必须不一样 

 4 值是一个整数。 

 5 一个对象创建以后,hashCode() 结果要稳定不变! 

 6 在Object中默认的hashCode的值是与堆对象地址对应的一 

 个整数 


JDK 类库中的类,一般都覆盖了equals() 和 hashCode() 

如:String 覆盖了equals, 两个相同内容的String, 

 hashCode() 一定一样。 


toString() 方法 

 1 返回当前对象的"文本描述",按照“习惯”书写. 如:方块A,(x,y) 

 2 默认的输出语句和字符串连接会调用toString() 方法,作为结果 

 3 Object 默认的toString() 的值是: 

 全限定名@hashCode 

 4 Java建议覆盖toString() 提供合理是值。 

 5 Java的类库基本都覆盖了toString(). 


0~n 对应X的运算可以采用数组完成: 

 //char[] c = {'0', '1', '2'... 'f'}; 

 //char[] ch = {'零','壹', ... , '玖'}; 

 //char[] cx = {'元','拾','佰'... , '玖'}; 

 //String[] rankName = 

 {"2", "3","4", "5", "6", "7", "8", "9" 

 , "10", "J", "Q", "K", "A"}; 


clone() 克隆方法, 就是复制 

 1 需要覆盖父类提供的clone方法,要开放为公共的。 

 2 Object 提供的clone方法 是保护方法,默认不能公共调用 

 3 覆盖时候经常把异常处理掉 

 4 如果需要使用父类的clone()方法,必须实现Clonable接口 

 5 Object 提供的clone() 方法是浅层复制。 

 6 object克隆提供对象的浅层复制, 

 7 * java 系统提供的复制, 基本都是浅层复制 

 8 clone方法不是经常被覆盖! 


finalize() 方法 

 1 和垃圾收集器有关。 

 2 finalize()在对象销毁之前由垃圾收集器调用。 

 3 可以被覆盖,但是不推荐覆盖 

 4 如果要覆盖,必须在代码中调用super.finalize() 

 5 Object .finalize() 方法会执行一些重要的内存回收操作 

 6 垃圾回收:一个对象不被任何引用所引用的时候。这个对象就是 

 内存垃圾,垃圾回收器会在系统空闲,或者特定时机(可以配置) 

 7 垃圾回收可以通过JVM的配置进行优化。 

 8 System.gc() 可以让JVM 尽快启动 GC(垃圾回收器) 

 9 不推荐在finalize() 里面写一些逻辑,执行不是很可靠 


String 类,StringBuffer(旧),StringBuilder(新) 

 1 关于静态String,一般情况下相同内容的静态String(字面量) 

 是同一个对象。 

 2 大多数字符串运算返回的都是新String 实例 

 3 静态String 是指静态字面量,动态字符串是指运行期分配的String 

 4 String 使用“不变模式” 设计,字符串对象一旦创建了, 

 内容永远不变!字符串对象不变,不是引用不可改变。 

 引用值不变使用final 修饰 

 5 因为String是不变模式,所以String的方法返回都是新对象 

 (除了toString()) 


关于“不变模式” 

 1 保证任何情况下对象一旦创建,对象的属性就再也不能修改了 

 通过语法来约束实现。 


使用第三方的API 

 1 获取API,并且释放到一个目录下 

 2 把API的类库(.jar 文件)配置到CLASSPATH 

 在eclipse: Project(右键)->Properties-> 

 Java Buide Path->Libraries->Add Jar 

 3 查看API手册 

 4 根据手册,导入到代码中使用 


字符的编码 

 关于编码方案: 

 1 ASCII 128个英文+符号, 后来扩展到256字符,如:A->65 

 2 IS0_8859-1 就是 ASCII, 如:A:41 

 3 GB2312中文编码(6000+汉字),是变长编码(1~2Btye) 

 其中1Byte时候和ASCII兼容,没有:玥,喆,镕,焗 

 常用艺术的字库都是(GB2312)的, 如:中:d6d0 A:41 

 4 GBK扩展了GB2312标准(兼容),1~2Byte编码,定义了 

 20000+汉字,几乎包括所有汉字,包括全部的CJK 

 WIN XP 中文采用是GBK,如:中:d6d0 A:41 

 5 UNICODE 是国际化组织 全球范围内文字,和ASC兼容 

 超过80000,包括CJK。Unicode 定义了多种编码方案 

 UTF-16BE, 采用16位定长编码,任何文字都一样。 

 能够表示 65535字 

 如:A= 0041 中: 4e2d 

 UTF-8, 采用:1~4Byte 的变长编码,表示全部的80000+字 

 英文采用,1Byte编码,与AscII一致,中文是3个Byte 

 如:A:41, 中:e4 b8 ad 


 1 Java的字符串内部编码Unicode(UTF-16BE), 

 Java 经常需要将GBK->UTF-16BE, 一般情况下Java会默认支持 

 本地编码到Java内码的转换 

 如: byte[] gbk = {(byte)d6,(byte)d0,41,42}; 

 String str = new String(gbk); 


正则表达式: 


字符 

x 字符 x 

\\ 反斜线字符 

\0n 带有八进制值 0 的字符 n (0 <= n <= 7) 

\0nn 带有八进制值 0 的字符 nn (0 <= n <= 7) 

\0mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7) 

\xhh 带有十六进制值 0x 的字符 hh 

\uhhhh 带有十六进制值 0x 的字符 hhhh 

\t 制表符 ('\u0009') 

\n 新行(换行)符 ('\u000A') 

\r 回车符 ('\u000D') 

\f 换页符 ('\u000C') 

\a 报警 (bell) 符 ('\u0007') 

\e 转义符 ('\u001B') 

\cx 对应于 x 的控制符 


字符类 

[abc] a、b 或 c(简单类) 

[^abc] 任何字符,除了 a、b 或 c(否定) 

[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围) 

[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集) 

[a-z&&[def]] d、e 或 f(交集) 

[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去) 

[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去) 


预定义字符类 

. 任何字符(与行结束符可能匹配也可能不匹配) 

\d 数字:[0-9] 

\D 非数字: [^0-9] 

\s 空白字符:[ \t\n\x0B\f\r] 

\S 非空白字符:[^\s] 

\w 单词字符:[a-zA-Z_0-9] 

\W 非单词字符:[^\w] 


POSIX 字符类(仅 US-ASCII) 

\p{Lower} 小写字母字符:[a-z] 

\p{Upper} 大写字母字符:[A-Z] 

\p{ASCII} 所有 ASCII:[\x00-\x7F] 

\p{Alpha} 字母字符:[\p{Lower}\p{Upper}] 

\p{Digit} 十进制数字:[0-9] 

\p{Alnum} 字母数字字符:[\p{Alpha}\p{Digit}] 

\p{Punct} 标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ 

\p{Graph} 可见字符:[\p{Alnum}\p{Punct}] 

\p{Print} 可打印字符:[\p{Graph}\x20] 

\p{Blank} 空格或制表符:[ \t] 

\p{Cntrl} 控制字符:[\x00-\x1F\x7F] 

\p{XDigit} 十六进制数字:[0-9a-fA-F] 

\p{Space} 空白字符:[ \t\n\x0B\f\r] 


java.lang.Character 类(简单的 java 字符类型) 

\p{javaLowerCase} 等效于 java.lang.Character.isLowerCase() 

\p{javaUpperCase} 等效于 java.lang.Character.isUpperCase() 

\p{javaWhitespace} 等效于 java.lang.Character.isWhitespace() 

\p{javaMirrored} 等效于 java.lang.Character.isMirrored() 


Unicode 块和类别的类 

\p{InGreek} Greek 块(简单块)中的字符 

\p{Lu} 大写字母(简单类别) 

\p{Sc} 货币符号 

\P{InGreek} 所有字符,Greek 块中的除外(否定) 

[\p{L}&&[^\p{Lu}]] 所有字母,大写字母除外(减去) 


边界匹配器 

^ 行的开头 

$ 行的结尾 

\b 单词边界 

\B 非单词边界 

\A 输入的开头 

\G 上一个匹配的结尾 

\Z 输入的结尾,仅用于最后的结束符(如果有的话) 

\z 输入的结尾 


Greedy 数量词 

X? X,一次或一次也没有 

X* X,零次或多次 

X+ X,一次或多次 

X{n} X,恰好 n 次 

X{n,} X,至少 n 次 

X{n,m} X,至少 n 次,但是不超过 m 次 


Reluctant 数量词 

X?? X,一次或一次也没有 

X*? X,零次或多次 

X+? X,一次或多次 

X{n}? X,恰好 n 次 

X{n,}? X,至少 n 次 

X{n,m}? X,至少 n 次,但是不超过 m 次 


Possessive 数量词 

X?+ X,一次或一次也没有 

X*+ X,零次或多次 

X++ X,一次或多次 

X{n}+ X,恰好 n 次 

X{n,}+ X,至少 n 次 

X{n,m}+ X,至少 n 次,但是不超过 m 次 


Logical 运算符 

XY X 后跟 Y 

X|Y X 或 Y 

(X) X,作为捕获组 



实验: 

 1 控制台输入验证方法实现: 

 1.1 定义方法 

 Location read(String msg) 

 Loaction 包含一个位置坐标: i, j 

 msg: 是输入提示信息,如: “输入坐标位置i,j” 

 1.2 要求: 

 如果输入错了要求反复输入 

 ij是一个16进制字符, 

 ij之间是“,”或者“空格” 


 ^[0-9a-f](\s+|,)[0-9a-f]$ 

 1,2 

 a,b 

 a b 

 a b 


StirngBuilder 和StringBuffer 

 1 StirngBuilder 是Java5以后提供的,是一个新版本 

 性能好于StringBuffer。因为:StringBuffer 是线程 

 安全对象,方法需要检查线程的安全性,速度稍慢。 

 Java5 以后推荐使用StirngBuilder。 

 2 String 类的动态链接(+)的底层是使用StringBuilder 

 的append()实现。 

 Stirng a = "5"; 

 String b = a+a+a+a; 

 String b = new StringBuilder(a).append(a) 

 .append(a).append(a).toSting(); 

 字符串的动态会参数一个垃圾对象(StringBuilder) 

 问题代码: 

 Stirng a = "5"; 

 a+=a; 

 a+=a; 

 a+=a; 

 优化: 

 Stirng a = "5"; 

 StringBuilder buf = new StringBuilder(a); 

 buf.append(a); 

 buf.append(a); 

 buf.append(a); 

 a = buf.toString(); 


Java 包装类 

 1 实现基本类型<->对象类型的转换 

 int i=1; 

 Integer d = new Integer(i); 

 Object o = d; 

 2 提供一些工具方法 

 3 Java5 以后提供了自动包装(auto boxing) 

 Integer i = 1;// Integer i = new Integer(1) 

 Object o = 5; 

 Object o1 = 2.5;// new Double(2.5) 

 4 自动拆包(unboxing) 

 Integer i = 5; 

 int x = i+5;// x=i.intValue() + 5 


Java中的时间 

 1 基本的时间表示:long 

 2 java.util.Date 是对long的包装。提供了时间的处理方法 

 getYear() 

 Date 类是Java早期的时间表示,Calendar(日历,历法)是新的 

 时间表示,Java推荐使用。 

 不过Date还是很普遍的在使用! 

 3 long <-> Date <-> Calendar 

 4 默认的日期创建,都是当前时间。 

 5 日期的输出与输入 

 6 Calendar 可以通过工厂方法 Calendar.getInstance() 

 来创建实例。 

 工厂方法:能够创建对象的方法都叫工厂方法。 

 经常用工厂方法创建接口或者抽象类实例。 

 工厂方法好处,可以屏蔽复杂的创建过程。 

 7 日期的计算 

 计算下个月的今天 

 计算这个月的第一天 


 class Person{ 

 Calendar birthday; 

 } 


 大数运算 

 1 java.math.BigInteger 大整数 


内部类 

 1 静态内部类:使用static修饰,声明在类体中,可以使用 

 外部类类名访问,在类内部可以省略类名。静态内部类中 

 可以访问外部类的静态成员。 

 2 成员内部类: 声明在类体中,不使用static,具有类的成员特征 

 也就是,必须有类的实例才能创建内部类实例。内部类实例 

 可以访问共享外部类的成员变量。很常用。 

 如:链表的节点就可以定义为内部类 

 3 局部内部类:把类声明在方法中,就是局部内部类,作用域 

 类似局部变量。很少见。 

 4 匿名内部类,匿名类:非常常见,可以写在任何地方,就行一般的语句。 

 语法更象是创建对象: 

 Date d = new Date(){}; 

 匿名类是对原类的一个继承,同时创建了实例,{} 就是继承 

 以后的类体。类体中可使用机会所有类的语法。 

 被继承的类必须有无参数构造器!匿名类不能写构造器。 

 匿名类可以从抽象类或者接口继承,必须提供抽象方法的实现。 

 5 任何内部类都编译成独立的class文件 

 6 最大的作用:封装! 


List 线性表 

 1 使用集合(List)作为属性时候,一般都直接实例化为空集。 

 2 可以使用泛型约束集合中元素的类型。线性表推荐使用泛型 

 List<Card> cards = new ArrayList<Card>(); 

 3 ArrayList vs Vector 都是用数组实现的线性表 

 Vector 旧(Java 1.1)性能稍差,线程安全,内部数组成倍增长 

 ArrayList 新 (Java 1.2以后)非线性安全,性能好,增长50% 

 4 LinkedList 也是线性表实现, 采用双向循环链表实现。 

 private class Unit{ 

 Object data; 

 Unit next; 

 Unit prev; 

 public Unit(int data) { 

 this.data = data; 

 } 

 } 


HashMap 与 Hashtable 

 1 提供快速的散列查找实现。 

 2 初始化容量与加载因子。 

 初始化容量是散列空间大小,加载因子是指散列空间的充满率 

 如果超过充满率,HashMap会进行扩容并且重新散列。 

 3 HashMap 新的(1.2),非线程安全的,性能稍好, 

 可以保存在一个null的Key 

 Hashtable 旧的(1.1),线程安全,性能稍差,不允许存null。 


Iterator 接口 

 1 是迭代器接口,是一个对集合进行遍历处理的模型。 

 就是,把集合中的元素从头数一遍。 

 2 非常适合与while、for组成模式化的迭代处理代码。 


一定合理覆盖实现hashCode和equals,保证集合API的工作正常 


排序二叉树 

 1 TreeSet TreeMap 


 自然排序: 

 1 类实现了Comparable表示这个类实例是可以比较大小的。 

 可以比较大小的对象List集合,可以利用Collections.sort 

 进行自然顺序排序。 

 2 Comparable 的实现,要实现compareTo方法。 

 这个方法要与equals和hashCode方法的实现一致: 

 compareTo 返回结果为0时候,equals的结果一定是true 

 hashCode值一定一样! 

 3 Java提供的很多类都实现了Comparable, 如:String, 

 包装类,StringBuilder,Date,等。 


@Override 是JDK5以后提供的注释语法,可以告诉Java编译器 

检查随后的方法是否符合方法覆盖的语法。 


在List中交换元素: 

 1 Collections.swap(cards, i, j); 

 2 Card c = cards.get(i); 

 c = cards.set(j, c); 

 cards.set(i, c); 

 3 cards.set(i, cards.set(j, cards.get(i))); 


 Collections 是集合的工具类 

 1 排序 

 2 查找 

 3 填充 

 4 交换 

 5 洗牌 


Java GUI 

1 Swing 图形界面包:javax.swing.* java.awt.* 

2 JFrame 代表图像界面窗口 

3 JPanel 是窗口中的一个矩形区域,一般需要指定布局管理 

4 Layout 是布局, 布局:是指界面中组件元素的相对位置 

 布局的具体实现有:BorderLayout 边框布局 

 FlowLayout: 顺序流式布局 

5 在窗口中显示内容必须放置一个JPanel实例 

6 如果需要复杂的姐妹布局,一般采用Panel中套Panel实现 


关于事件监听 


 事件源对象,是事件发生时候的触发对象。