1.JAVA开发基础参考书目
《疯狂java联盟》杨恩熊 设计 java设计模式
《java核心技术》、《java编程思想》、《effective java 中文版》、《深入java 虚拟机》、《 数据结构与算法分析》 《java语言描述》、《java与模式》
2.垃圾回收器【Java基础部分只是提及一下】
java7提供G1垃圾回收器来取代原来的并行标记/清楚垃圾回收器(CMS)
垃圾回收器的原则:对于不再使用的对象,不要引用他们,如果保持对象应用,垃圾回收机制展示不会回收该对象,从而导致系统内存越来越少,回收频率会越来越高,导致系统性能的降低
垃圾回收机制的工作目标是回收无用对象的内存空间,这些内存控件都是jvm堆内存里的内存控件,垃圾回收只能回收内存资源,对其他物理资源,如数据库连接、磁盘I/O等资源则无能为力
垃圾回收机制:
一定程度上的垃圾回收机制 System.gc()
调用Runtime对象的gc()实例方法:Runtime.getRuntime().gc();
System.RunFinalize();//强制垃圾回收机制执行可恢复发的Finalize(),在gc()方法后并不一定会立即执行
Runtime.getRuntime.RunFinalize();
3.数据类型和运算符概述
1)强类型语言
2)先声明后使用
指定类型的变量逆光接收与类型与之匹配的数值,强类型语言必须在编译过程中发现源代码的作物,保证健壮性
2)基本数据类型
数据类型
a.基本数据类型{
数值型 -整数型 byte short int long
-浮点数 float double
字符型 char
布尔类型boolean
}
b.引用数据类型{
类class
接口interface
数组
}
数值类型{整形,字符型,浮点型},布尔类型}所有数值类型都可以记性类型转化,包含 [自动类型转换] 和 [强制类型转换]
3)类型转化(CAST)
a.自动类型转化:容量小的自动类型可以自动转化为容量大的自动类型,
注意:容量大为表述的类型
char byte-》short-》int->long
float->double
注意:在int 转为float时,可能损失精度,long转为float损失精度byte short int char这四者只要在范围内就可以自动转换
b.强制转型:由大转小存在有可能丢失信息的情况下完成的,但可能造成精度降低或溢出
注意:当将一种类型强制转化为另一种类型,而又超出目标类型的表示范围,就会截断成为一个完全不同的值 注意:运行时类型提升问题
int a=3;
long b=2;
int c=a+b;//会出现错误,做所有的二元运算符(+-*/)都会有类型提升的问题
注意:注意大数运算的边界问题,溢出问题
20亿*20 超出int范围,必须对20亿强制转型(long) money*year;
4.注释
1)对于一份比较规范的程序源代码而言,注释应该占到源代码的 1/3 以上
2)注释分为 单行注释,多行注释,文档注释
3)注释可以用来缩小错误所在的范围
4)javadoc工具默认只处理public或protected修饰的类、接口、方法、成员变量、构造器和内部类之间的文档注释
5)案例
/**
*@author
*@version
*@param
*@see 参见,用于指定交叉参考的内容
*@exception @throws 抛出异常的类型
*/
javadoc工具不会提取@author和version两个标记的信息,如果需要提取这两个标记信息,应该在使用个javadoc工具是指定-author和-version
5.标识符和关键字
1)分隔符:分号(;)花括号方括号圆括号 空格 原点都具有特殊分隔作用,称谓分隔符
注意分号: java程序允许一行书写多个语句,每个语句之间以分号隔开即可;一个语句也可以跨多行,只要在最后结束的地方使用分号结束即可,但是一个字符串、变量名不能跨越多行
2)java标识符规则:
a.标识符可以由字母、数字、下划线-- 美元符$组成,其中数字不能打头
b.标识符不能是java关键字和保留字,但可以包含关键字和保留字
c.标识符不能包含空格
d.标识符只能包含美元符$ 不能包含@#等其他特殊字符
3)java中所有的关键字都是小写的,TRUE、FALSE、NULL都不是java关键字
4)java还提供了三种特殊的直面量(literal) true、false、null java语言的标识符也不能使用这三种特殊的直接量\
5)编程的本质:就是对内存中数据的访问和修改,每个变量就是某一小块内存,简而言之:变量相当于一个有名称的容器,该容器用于装各种不同类型的数据
6.数据类型
一、整数
1)表现形式 :十进制
八进制 以0开头
十六进制 以0x开头
在java中整数常数默认是int类型,声明long类型,在常量加上l或L,常用大写
不加L的话,会容易出错
byte 1个字节 -128-127
short 2字节 -30000-30000左右
int 4字节 -21亿 -21亿
long 8字节
类 BigDecimal用来标注超过long的数
2)进制转换形式
Interger.toBinaryString();//十转二
Interger.toOctalString();//十转八
Interger.toHexString();//十转十六
特例:
byte b2=100;//如果数据的大小没有超过byte、short的表述范围,则可以自动转型
L问题:避免L作为变量,容易产生误解
3) jdk7新增整数
二进制数的书写
int a= 0b0101010010101010101010;//四个字节
新增数字分隔符 int a=0b0000_0000_1110_000;
int b=1_68787_78787 //整数也是可以这么用的
二、字符型
1)单引号来表示字符常量,采用unicode字符集,通用字符集,通过两个字节标识全世界字符
双引号 表示字符串
也可以使用转义字符 '\n' 换行
char是在0-65535,可以参与整数运算,可直接转化为相应的字符
char c=(char)98; //强制转型
字符串 是定义成String类
String str= "lkjljlkjlkjkj";
2)char代表字符型,实际上字符型也是一种整数类型,相当于无符号整数类型
3)字符的表现形式:
a.直接通过单个字符来指定字符型值 如'A' '9'
b.通过转义字符来表示特殊字符型值 如'\n'
c.直接使用unicode值来表示字符型值如'\uxxxx' ,其中 x为16进制的数
d.char类型可以直接看作整形值使用0-65535,比较大小实际上都是用该字符对应的编码参与运算
三、引用类型
1)引用类型包括类、接口、数组类型实际上还有null类型,所谓引用类型就是对一个对象的引用,对象包括实例和数组两种,引用类型变量就是一个指针,java不使用这种说法
注意:
a. null类型没有名称,所以不能声明一个null类型的变量或者转化为null类型,空引用null是null类型变量唯一的值,空引用null可以转化为任何引用类型,注意不要赋值给基本数据类型
b.如果直接讲一个较小的整数值(在byte或short类型的表数范围内)赋值给一个byte或short变量,系统会自动把这个整数值编程byte或short处理
c.如果把一个巨大的值(超出int的范围),java不会自动把这个整数转化为long类型,应该在数的后面加一个L
d.二进制中最高位为位,当符号位是1时,表示一个负数,负数在计算机中是以补码的形式存在,人在看的时候需要转换为原码
所有整数都是以补码存在的,正数的补码和原码是相同的,负数的补码是其反码加一,反码是对原码按位取反,最高位不变
四、浮点型
1)float 单精度数,可以保留7为有效数字,double是单精度数的两倍
2)浮点数的两种写法是
十进制形式
科学计数法
314e2 314e-2
浮点数默认使用的double,要变成float必须加F/f
float占4位,double占8位
浮点数类型不能精确,如果想要精确,不产生精确误差的计算,可以采用
BigDecimal类
最好在比较中使用浮点数
float f=0.1f;
double d=1.0/10;
System.out.println(f==d);//false
float 和 double 表示范围比int和long大,但是但是产生舍入误差
1.0/1=0.999999999999可能 比long大的话,可以采用biginterger类
3)java浮点数使用二进制数据的科学计数法来表示浮点数,因此可能不能精确表示一个浮点数
注意:
a.java还提供三种特殊的浮点数值 :正无穷大、负无穷大和非数 表示溢出和出错
整数/0=正无穷(POSITIVE_INFINITY)
负数/0=负无穷(NEGATIVE_Infinity)
0.0/0.0=非数(NaN)
b.必须指出 : 所有的正无穷都是相等的,所有的负无穷也是一样的,NaN不与任何人数值相等,只有浮点数除以0才会得到正负无穷大,java会自动把浮点数运算的0变为0.0,如果一个整数除上0,会抛出算数异常 byzero
c.java7中允许在整数或浮点数 自由使用下划线来分隔位数,为了分辨boolean只有true或false,不能用0和非0表示,其基本数据类型的值不能转化为boolean值;强制类型转化的时候要注意:避免数据溢出现象的翻身float a=(float) 5.6
d.字符串转变为基本数据类型8种数据类型都含有对应的包装包,下的parseXXX方法
五、布尔类型
1)Boolean 类型占了1位,不是一个字节,只含有true和false两个值,进行逻辑判断用的
7.表达式
运算符: 一元运算符++ --
二元运算符+-*/ %
算数运算符:
赋值运算符:
关系运算符
逻辑运算符
位运算符:
条件运算符
扩展赋值运算符
二元运算符:
整数运算(类型提升)
小数也可以取余数
如果两个数有一个数为long,double 则最终结果也为long,没有long时,其结果为int ,即时操作数都为short,byte,只有两个数都为float才为float
int a = 3;
int b = a++; //执行完后,b=3。先给b赋值,再自增。
int c = ++a; //执行完后,c=5。先自增,再给b赋值
布尔逻辑表达式
a.与&& 或 || 非 !
逻辑与和逻辑或采用短路方式,从左到右计算,如果确定值不会计算写去 Boolean c= 1>2 && 2>(3/0) ;不会出现异常,
位运算符
a. ~ 位取反 &位与 | 位或 ^位异或 << 左位移 >>右位移
b.用途:笔试可能出现 向右移动一位 相当于除2取商 左移一位相当乘2
权限管理 是通过位运算管理的,游戏中也常用
3<<2 3左移两位 3*2*2
boolean b1=true &false;没有短路情况,和&&的机制也是不同的
扩展运算符 += -=
字符串连接符
只要有一个是字符串类型,就可以自动的将另外一个也变成字符串类型 "4"+5=45
三元运算符
X?y:z x为boolean表达式为真执行y否则执行x
使用总结:
1)表达式类型的自动提升
a.所有的byte类型,short、char类型都会提升到int类型
b.整个算数表达式的算数类型自动提升到与表达式中最高等级操作数同样的类型
2)直接量:是指在程序中通过源代码直接给出的值 int a=5;5就是直接量;只有基本数据类型、字符串、null含有直接
3)由于string类是一个典型的不可变类,因此string对象创建出来就不可能被改变,因此不用担心共享string对象会出现混乱
4)常量池:在编译期间就确定的,被编译到。class文件的一些数据,包含类方法接口中的常量,包含字符串直接量
5)运算符:/除法运算符
a.如果两个整数的运算结果也为整数,会对结果进行截断,且除数不能为0,会出现除0异常
b.如果两个数为浮点数或一个数为浮点数,则计算结果为浮点数,且允许除0,出现无穷大小和nan情况
c. % 求余结果不一定是整数
d. ++ --只能用于操作变量,不能用于操作数值直接量、常量、表达式
e.java中支持连续赋值的情况,但是这种写法会出现可读性差,不推荐
f.位运算符:对于低于int类型byte short char的擦后座数进行位运算先转为int类型,再移位
int a>>b b 先对32取余 a》》33=a》》1
g.扩展赋值运算符还有更好的健壮性
注意点:
byte a=5;
a=a+5;//出错 a为int类型
但是a+=5;不会 ,底层的运行机制不相同
6)比较运算符:基本类型的变量、值不能和引用类型的变量、值使用== ;布尔类型变量和值不能和其他任何类型的变量值使用==。如果两个引用类型没有父子继承关系,也不能用==
7)&&与&的区别:有无短路问题;&总会计算墙后两个操作数,&&先计算左边的操作数
8)优先级:不要以来运算符的先后顺序来控制表达式的执行顺序,可读性太差,尽量使用()来控制
8.逻辑控制
控制语句:
顺序结构
选择结构
循环结构
选择结构: 单选择结构
1)选择结构
a.if建议加上花括号,否则只对第一行起效,双选择结构,多选择结构Math类 Math.random();产生[0,1)的数math
b.switch 语句 用来多选择结构
switch(表达式)//这个表达式 可以为int,或者自动可以转为int的类型(byte,short,char) 枚举;jdk7中的字符串
case 6:
System.out.println();
break;
default:
注意:若无break,会产生case穿透,直到碰到break为止
一般在每个case后面都要加break防止出现case穿透问题
可以利用case穿透来完成相同结果的判断
增强swith,表达式可以用字符串
注意:
1.使用if 。。。else语句时一定要先p排除了包含小范围的情况
2.switch后面的控制表达式的数据类型只能是byte、short、char、int四种整数类型,枚举类型 和 java.lang.String类型,不能是boolean
a.如果省略case后面的代码块break 将会引入一个陷阱
b.写法:case conditon:{ statement(s) break; }
2)循环结构:
while结构:符合条件执行while循环,知道条件不符合为止
可以分为 初始化,条件判断,循环体,迭代(改变循环条件)
dowhile 用的很少,先执行后判断 while后面注意加上分号
循环定义:循环时一定要保证循环条件有编程false的时候,否则这个循环将成为一个死循环,永远无法结束这个循环
a. do while 循环的循环条件
b. for循环中循环条件永远比循环体多执行一次
c.迭代语句在while 和dowhile for中的不同表现形式,在for中continue语句结束本次循环,迭代语句将会被执行,而在while 和dowhile中将不会被执行
d.
public class TestContinue
{
public static void main(String[] args)
{
int i=1;
while(i<10)
{
System.out.println(i);
if(i==5)
continue;
i++;
}
}
}
会出现无限次打印5的现象,因此在使用continue中不要加在while循环中
f.建议不要在循环体内修改循环变量(循环计数器)的值,否子会增加程序出错的可能性
把for循环的初始化语句放在循环之前定义还有一个作用,可以扩大初始化语句中所定义变量的作用域,但通常采用一个额外定义的变量来保存这个循环变量的值
g.break拥有结束循环的作用,break语句不仅可以结束其所在的循环,还可以结束其外层循环,此时需要在break后面紧跟一个标签,这个标签用于表示一个外层循环,:标识符所标记的标签在java中只有放在循环语句之前才有作用, break :outer标签,outer只有在外部才有作用,在内部的话,默认结束当前循环
h.return 语句的使用是用来结束方法的,相应的结束了方法中的循环,在return后面的语句在return被执行后都没有机会被执行了,return语句不管它嵌套了几层循环
9.字符串
字符串就是unicode字符序列
java中没有内置的字符串类型,""是字符串的一个实例
字符串在创建后是字符串引用不可变为final类型,但是字符串
string 中的几个小方法:
eqaulIgnoreCase()//忽略大小写
lastindexof()//
Startwith()//以。。开头
EndWith()//以。。结尾
toLowercase()
toUpperCase()// 字符串中length为方法
Isempty
charAt
equals比较地址 或者 字符串中长度和每个元素相等
indexof() 返回字符对应的索引,没找到返回-1
substring()
replace(oldstr,newstr)
split();
trim();去处首尾空格,中间空格无关
toCharArray()形成char[]数组
String str= new sting("abcd");
sting str1=new string('abcd')// 他们的地址不同但是元素相同
用equals比较时相等,==为不相等
常量"sjkkk" 只开辟一个空间,而通过new 开辟两个不同的空间
new string("abcd") //创建两步走,abcd 和'a''b''c''d'
练习string 的常用方法
查看string中jdk源码
注:string不可以修改字符串;不可变字符序列
二、StringBuffer 和 StringBuilder
1.StringBuilder(线程不安全,效率高) 可变字符序列(stringbuffer 线程安全,效率低)
可修改字符串中某一个字符值,默认创建一个字符数组长度为16 也可穿字符串 new stringbuilder(32);
stringbuilder sb2 =news StingBuilder("abcd");// 将char [] value 中{'a''b''c''d''\u0000'\u0000'\u000''\u0000'}
2.原理
append() 在字符串后面累加,返回当前对象 this,形成字符链串
stringbuilder默认开辟的空间是 "abcd".length()+16;
当字符串长度不够时,进行申请字符串复制,创建大小为 老数组长度大小*2+2,老数组被回收
3.stringbuilder方法:
append()
delete(int start,int end )删除[start,end)r
sb.delete(3,5).delete(3,5)
replace
insert
reverse()反转
stringbuffer 方法中含有sych 同步 线程安全,方法与stringbuilder一样
10.数组(一维)
1)数定义组:java中要求数组中存储相同数据类型(相同父类型也算同一类型),
一旦数组完成初始化工作,相应的数组空间也被分配,则数组长度不变,不管数组中是否存有数据(无数据会有默认)
2)type[] 名称也算是一种数据类型:定义数组只是定义了一个引用变量,并没有分配内存空间,只有在初始化的过程才分配内存空间,因此定义数组时不能指定数组长度
3)初始化可以分为静态初始化和动态初始化
a.静态初始化:通过初始值的个数决定数组长度
b.动态初始化:只指定数组长度,由系统元素分配初始值
注意:
a.使用foreach的注意问题: for(type k:collections) 其中的type必须是collection 的子类,或能够自动转型为该type的类型
b.使用foreach循环,不要对for中的循环变量进行赋值
内存中堆栈的存在,是为了更好的处理和使用资源
4)栈中的局部变量,在没有引用任何数据对象的时候会被回收,堆的使用是为了更好的数据共享
注意:
a.只要类型相互兼容,就可以让一个数组变量指向另外一个实际的数组,这种操作会让人产生数组的长度可变的错觉
b.在java中并不允许无限次扩展数组,如果想实现可以建立一个object[],普通数据类型没有办法做到
c.数组长度是确定的,不变的。如果越界会报ArrayIndexOutofBoundsException
d.每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问他们
举例:
int [] a;//应用
new int[3];//最多三个数,数组元素也含有默认值,跟成员变量的规则是一样的
测量数组的长度 a.length;length属性是final
for(int i=0;i
11.多维数组
多维数组
多维数组不一定是规则矩形
int [][] a=new int[3][];
a[0]=new int[2];
a[1]=new int[4];
int [][] =new int[][3];//非法
数组的拷贝
system类中也包含了 static void arraycopy(src,int dest,int,length)
将数组转成List asList(数组)
升序 sort(数组)
toString(数组)//打印数组
问题 Arrays的toString和Object的toString?
对象怎么排序,需要自定义排序规则实现comparable的comparcTo方法
fill(0)填充内容
冒泡排序
二分法排序,必须是排好顺序的,二分法主要用于查找东西
命令行参数:args的使用
java 类名 参数1 参数2 "参数3"
eclipse中使用运行时 run biological 即可
12.集合-ArrayList 通过数组实现过程
ArrayList :存在java.util的包中,通过数组来实现
object[] elements;
package cn.bjsxt.myCollection;
import java.util.ArrayList;
/**
* 模拟实现JDK中提供的ArrayList类
* @author dell
*
*/
public class MyArrayList {
/*** The value is used for object storage.*/
private Object[] value;
/**The size is the number of objects used.*/
private int size;
public MyArrayList(){
// value = new Object[16];
this(10);
}
public MyArrayList(int size){
if(size<0){
try {
throw new Exception(); //手动抛出一个异常。 讲到异常章节再说,先混个眼熟
} catch (Exception e) {
e.printStackTrace();
}
}
value = new Object[size];
}
public int size(){
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void add(Object obj){
value[size] = obj;
size++;
if(size>=value.length){
//装不下了。扩容吧!
int newCapacity = value.length*2;
Object[] newList = new Object[newCapacity];
// System.arraycopy(src, srcPos, dest, destPos, length);
for(int i=0;i=0;i--){
if(obj==value[i]){
return i;
}
}
return -1;
}
}
public Object set(int index, Object object) {
rangeCheck(index);
Object old = value[index];
value[index] = object;
return old;
}
public void rangeCheck(int index){
if(index<0||index>size-1){ //[0,size-1]
try {
throw new Exception(); //手动抛出一个异常。 讲到异常章节再说,先混个眼熟
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyArrayList list = new MyArrayList(2);
list.add("aaa");
list.add(new Human("高琪"));
list.add("bbbb");
list.add("bbbb");
list.add("bbbb");
list.add("bbbb");
ArrayList list2;
Human h = (Human) list.get(1);
System.out.println(h.getName());
// System.out.println(list.get(3));
System.out.println(list.size());
}
}