集合框架
概念
集合:一批数据,和数组类似,这批数据类型相同,但是比数组用起来简单,但是效率低
框架:框架是个半成品工具,类似于模板,目的是提高工作(开发)效率
集合框架:集合类型数据作为工具
有序:每一个数据在集合中都有自己的下标,可以通过下标来操作数据
无序:每一个数据在集合中没有自己的下标,不能通过下标来操作
唯一:一批数据中没有一个值是相同的,那么每个值都是唯一的
集合框架体系语法
Collection接口
Collection是List和Set接口的父接口,Collection存储的数据无序,不唯一。
方法:add(内容),remove(内容),size(),contains(成员)(collection不能操作有下标的)
List接口(子类包含ArrayList、LinkList)
List:可变长度的数组(连续+不定长)
List接口存储有序,不唯一
实现子类:ArrayList,LinkedList,Vector(功能和ArrayList一样)
线程安全:同时操作安全即线程安全,如vector,效率不高
线程不安全:如ArrayList,但是效率高
查询速度快:有下标的查询速度快,如(线性表)arraylist
增加,修改速度快:无下标的增加修改快,如(链表)LinkedList,vector
方法:add(下标,成员数据);add(成员数据);remove(下标);remove(内容);size();
ArrayList类(随机访问快)
创建:
//第一种默认容量是10
ArrayList list=new ArrayList();
//第二种,人为给定容量
ArrayList list1=new ArrayList(20);
//如果内容溢出,每次增加的内容为n+n/2(扩容是逐步扩容,下标不能超出当前最长的长度)
方法:
add(下标,成员数据):按照下标序号插入新数据
list.add(0, “a”);//[a]
list.add(“b”);//[a,b]
list.add(0, “c”);//[c,a,b]
list.add(1, “d”);//[c,d,a,b]
list.add(10,“e”);//数组越界(扩容是逐步扩容,下标不能超出当前集合最长的长度(下标+1))
add(成员):在集合成员最后一维的后面增加成员
remove(下标):按下标删除
list.remove(2);//[c,d,b]按下标删除
remove(内容):按内容删除
list.remove(“b”);//[c,d]按内容删除
获取当前成员个数size()
int length=list.size();//获取当前成员个数
contains(成员):返回Boolean,true表示该成员存在,false表示不存在(通过equals来判断)
boolean bool=list.contains(“b”);
get(下标):按照下标获取对应的成员数据
Object str1=list.get(2);//用下标获取集合中成员
循环:
①用带下标的循环(适用于List)
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(i));
}
②用不带下标的循环输出(List和set都适合)
for(Object o:list) {
System.out.println(o);
}
知识点:
remove(超过size的下标):报错 下标超长
remove的内容也是数组,如remove(2),优先按下标删除
remove(内容),如果内容重复,那么只删除前面的
LinkedList
创建:
LinkedList list=new LinkedList();
方法:
增加首节点 list.addLast(“庚”)
增加尾节点 list.addFirst(“辛”)
删除首节点 list.removeFirst()
删除尾节点 list.removeLast()
Set接口(子类包含HashSet、)
Set接口存储的是无序,唯一的数据
set可以自动排序
HashSet(不安全)
数据成员不能重复
成员默认排序(升序)
Map接口
概念:存储的是键值对(key-value),其中键是唯一的,值可以重复
方法:
put(key,value):增加一对 键值对
map.put(“cn”, “中国”);
map.put(“usa”, “美国”);
map.put(null, “未知国家”);
size():获取成员个数
int a=map.size();
get(key):通过key获取value
Object value1=map.get(“CN”);
keySet():获取所有key
Set set1=map.keySet()
values():获取所有value
Collection co= map.values();
containsKey(key):是否存在这个key
boolean b=map.containsKey(“CN”);
containsValue(value)是否存在value
boolean b1=map.containsValue(“中国”)
HashMap(不安全)
创建:HashMap map=new HashMap();
HashTable(安全)
iterator(迭代器)
泛型
概念:泛型指的是模糊类型,编译时占位置,运行时指定,如果不指定就是object
泛型的使用
class 类型<T1,T2,T3>{//类使用泛型(三种类型不一样)
private T1 a;//变量使用泛型
public void add(T2 b){}//参数使用泛型
public T1 get(int index)//返回值使用泛型
}
注意:
如果未指定具体类型,取值用object
ArrayList list=new ArrayList();
list.add(100);
list.add(“张三”);
Object o=list.get(1);//不能用String接收
如果指定了具体类型,取值必须按照指定类型取值
ArrayList list1=new ArrayList();
list1.add(“100”);
list1.add(“张三”);
String s=list1.get(1);//可以用Object接收
collections工具类
语法和ArrayUtil工具类方法相似(构造方法私有,无法创建实例)
拷贝
Collections.copy(list2, list1)//注意:拷贝的时候,list2是拷贝结果,并且list2,也要有list1等长的值
排序
Collections.sort(list1)
填充
Collections.fill(list2, 5)
判断是否相等
boolean flag=list1.equals(list2);//判断是否相等(判断内容)
实用类
枚举
概念
枚举是一种范围类型,值只能使用已定义范围以内的值
定义枚举
语法:修饰符 enum 枚举名{
枚举值1,枚举值2,枚举值n
属性
构造方法
}
每一个枚举值都是一个实例
每一个枚举值的构成:枚举名(属性),序号
样例:
第一种:
public enum GenderEnum {
female,male}
第二种
female(“女”,“女性”),male(“男”,“男性”);//给枚举值具体赋值,外界访问可以通过枚举值访问属性
private String value;//通过get,set访问某个具体的值
private String value1;
private GenderEnum(String value,String value1) {//枚举的构造函数只能私有
this.value=value;
this.value1=value1;
}
使用枚举
在属性上选择枚举
public class TestClass {
private GenderEnum Gender;}
给枚举类型属性赋值
tc.setGender(GenderEnum.female);//只能通过枚举中的值来传递
可以通过set对枚举的属性改变:
tc.getGender().setValue1(“女的”);//改变枚举中的属性
包装类
概念
每一个基本类型都对应一个复杂类型,这个复杂类型就叫包装类
包装类在:java.lang.*;
基本类型:byte short int long float double char Boolean
包装类型:Byte Short Integer Long Float Double Character Boolean
装箱:怎样创建包装类的复杂类型
基本类型自己动转化为包装类(不是转型)
byte b=1;
Byte b1=b;
int i=10;
Integer i1=i;
char c=‘a’;
Character c1=c;
通过参数为基本类型的构造方法来创建
Character c2=new Character(‘a’);
Integer i2=new Integer(4);
Boolean b2=new Boolean(false);
Short s2=new Short((short)6);//不同类型需要强转
通过参数为字符串的类型构造方法来创建(唯独Character)
Short s3=new Short(“788”);//输出788,输出字符串报错
String s4=new String(“love”);
Boolean b3=new Boolean(“5true”);//显示false
对应包装类提供的valueof(基本类型)
Boolean b5=Boolean.valueOf(false);
Integer i5=Integer.valueOf(9);
Short s5=Short.valueOf((short)8);
对应包装类提供的parseXxx(字符串)(唯独Character没有)
Boolean b6=Boolean.parseBoolean(“true”);
Integer i6=Integer.parseInt(“9”);
Short s6=Short.parseShort(“6”);
开箱:将复杂类型转化为基本类型
自动开箱(开箱即用)
boolean b7=b5;
int i7=i5;
通过包装类的成员方法XXXvalue(),来获取基本类型值
boolean b8=b5.booleanValue();
int i8=i5.intValue();
字符串
创建字符串:
概念:由多个字符构成,用”“表示字符串;字符串是final类型的类,不可继承,内容不可改变
内容不可变的原因
每一个字符串都有对应的hashcode(唯一),为了复用不可变
源码的定义为private final char value
创建字符串:
String str1=“内容”//直接创建
String str3=new String(”内容“)//只要new,就会在堆空间新增加
String Str3=”今天“+”星期六“+”上午“+”上课“//创建了七个字符串对象,分别是:”今天“、”星期六“、”上午“、”上课“和三个叠加的
字符串拆分:(数组接收,循环输出,拆分后被拆分的字符也会消失)
String[] strs=str.split(“六”);
System.out.println(strs);
字符串长度:
int len=str.length();
System.out.println(len);
字符串替换:
String str2=str.replaceAll(“天”, “day”);
System.out.println(str2);
获取字符对应下标:
//获取对应字符的下标(字符串),0开始,没找到返回-1
int i=str.indexOf(“不”);//输出8
int i1=str.indexOf(“不错”);//输出8
截取字符串:substring(截取的位置)->从0开始左闭右开
String str6=str.substring(5);//从第五个开始截取,包含5
System.out.println(str6);
String str7=str.substring(2,7);//从第二个开始截取,不包含7
System.out.println(str7);
字符串比较:
String s1=“牛奶”;
String s2=“牛奶”;
String s3=new String(“牛奶”);
System.out.println(s1s2);//ture
System.out.println(s2s3);//false
System.out.println(s1==s3);//false
StringBuffer
创建字符缓冲对象 StringBuffer
增加内容 append(“内容”)
获取字符串的方法是toString
StringBuffer sb=new StringBuffer(">");//创建一个字符缓冲对象,并给初值<
sb.append(">");
sb.append(">");
sb.append(">");
String s=sb.toString();//用tostring接收字符串
StringBuilder
创建字符缓冲对象 StringBuilder
增加内容 append(“内容”)
获取字符串的方法是toString
StringBuilder sbd=new StringBuilder(">");//创建一个字符缓冲对象,并给初值<
sbd.append(">");
sbd.append(">");
sbd.append(">");
String s=sbd.toString();//用tostring接收字符串
StringBuilder和StringBuffer比较:
效率:StringBuilder>StringBuffer
安全:StringBuilder安全
时间类
Date
创建当前时间对象
Date date=new Date();
字符串转时间(Date)
创建日期格式工具(带格式)
DateFormat df=new SimpleDateFormat(“yy-MM-dd hh:mm:ss”);//转换必须指定转化格式(hh是12小时,HH是24小时)
利用已创建的日期格式转化
String s=df.format(date);
System.out.println(s);
时间转字符串:
创建日期格式工具(带格式)
DateFormat df=new SimpleDateFormat(“yyyy/MM/dd hh时:mm:ss”);
字符串转时间:
Date date=df.parse(strdate);//把字符串转时间
数学工具类
//绝对值
System.out.println(Math.abs(b));
//求整数(四舍五入)
System.out.println(Math.round(a));
//求整数(向上求整)
System.out.println(Math.ceil(a));
//求整数(向下求整)
System.out.println(Math.floor(a));
//随机数
double num=Math.random();//[0,1)
//求400-450的随机数
int m=(int)(Math.random()*50);//50以内的随机数
System.out.println(m);
System.out.println(400+(int)(Math.random()*50));
集合框架
概念
集合:一批数据,和数组类似,这批数据类型相同,但是比数组用起来简单,但是效率低
框架:框架是个半成品工具,类似于模板,目的是提高工作(开发)效率
集合框架:集合类型数据作为工具
有序:每一个数据在集合中都有自己的下标,可以通过下标来操作数据
无序:每一个数据在集合中没有自己的下标,不能通过下标来操作
唯一:一批数据中没有一个值是相同的,那么每个值都是唯一的
集合框架体系语法
Collection接口
Collection是List和Set接口的父接口,Collection存储的数据无序,不唯一。
方法:add(内容),remove(内容),size(),contains(成员)(collection不能操作有下标的)
List接口(子类包含ArrayList、LinkList)
List:可变长度的数组(连续+不定长)
List接口存储有序,不唯一
实现子类:ArrayList,LinkedList,Vector(功能和ArrayList一样)
线程安全:同时操作安全即线程安全,如vector,效率不高
线程不安全:如ArrayList,但是效率高
查询速度快:有下标的查询速度快,如(线性表)arraylist
增加,修改速度快:无下标的增加修改快,如(链表)LinkedList,vector
方法:add(下标,成员数据);add(成员数据);remove(下标);remove(内容);size();
ArrayList类(随机访问快)
创建:
//第一种默认容量是10
ArrayList list=new ArrayList();
//第二种,人为给定容量
ArrayList list1=new ArrayList(20);
//如果内容溢出,每次增加的内容为n+n/2(扩容是逐步扩容,下标不能超出当前最长的长度)
方法:
add(下标,成员数据):按照下标序号插入新数据
list.add(0, “a”);//[a]
list.add(“b”);//[a,b]
list.add(0, “c”);//[c,a,b]
list.add(1, “d”);//[c,d,a,b]
list.add(10,“e”);//数组越界(扩容是逐步扩容,下标不能超出当前集合最长的长度(下标+1))
add(成员):在集合成员最后一维的后面增加成员
remove(下标):按下标删除
list.remove(2);//[c,d,b]按下标删除
remove(内容):按内容删除
list.remove(“b”);//[c,d]按内容删除
获取当前成员个数size()
int length=list.size();//获取当前成员个数
contains(成员):返回Boolean,true表示该成员存在,false表示不存在(通过equals来判断)
boolean bool=list.contains(“b”);
get(下标):按照下标获取对应的成员数据
Object str1=list.get(2);//用下标获取集合中成员
循环:
①用带下标的循环(适用于List)
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(i));
}
②用不带下标的循环输出(List和set都适合)
for(Object o:list) {
System.out.println(o);
}
知识点:
remove(超过size的下标):报错 下标超长
remove的内容也是数组,如remove(2),优先按下标删除
remove(内容),如果内容重复,那么只删除前面的
LinkedList
创建:
LinkedList list=new LinkedList();
方法:
增加首节点 list.addLast(“庚”)
增加尾节点 list.addFirst(“辛”)
删除首节点 list.removeFirst()
删除尾节点 list.removeLast()
Set接口(子类包含HashSet、)
Set接口存储的是无序,唯一的数据
set可以自动排序
HashSet(不安全)
数据成员不能重复
成员默认排序(升序)
Map接口
概念:存储的是键值对(key-value),其中键是唯一的,值可以重复
方法:
put(key,value):增加一对 键值对
map.put(“cn”, “中国”);
map.put(“usa”, “美国”);
map.put(null, “未知国家”);
size():获取成员个数
int a=map.size();
get(key):通过key获取value
Object value1=map.get(“CN”);
keySet():获取所有key
Set set1=map.keySet()
values():获取所有value
Collection co= map.values();
containsKey(key):是否存在这个key
boolean b=map.containsKey(“CN”);
containsValue(value)是否存在value
boolean b1=map.containsValue(“中国”)
HashMap(不安全)
创建:HashMap map=new HashMap();
HashTable(安全)
iterator(迭代器)
泛型
概念:泛型指的是模糊类型,编译时占位置,运行时指定,如果不指定就是object
泛型的使用
class 类型<T1,T2,T3>{//类使用泛型(三种类型不一样)
private T1 a;//变量使用泛型
public void add(T2 b){}//参数使用泛型
public T1 get(int index)//返回值使用泛型
}
注意:
如果未指定具体类型,取值用object
ArrayList list=new ArrayList();
list.add(100);
list.add(“张三”);
Object o=list.get(1);//不能用String接收
如果指定了具体类型,取值必须按照指定类型取值
ArrayList list1=new ArrayList();
list1.add(“100”);
list1.add(“张三”);
String s=list1.get(1);//可以用Object接收
collections工具类
语法和ArrayUtil工具类方法相似(构造方法私有,无法创建实例)
拷贝
Collections.copy(list2, list1)//注意:拷贝的时候,list2是拷贝结果,并且list2,也要有list1等长的值
排序
Collections.sort(list1)
填充
Collections.fill(list2, 5)
判断是否相等
boolean flag=list1.equals(list2);//判断是否相等(判断内容)
输入与输出(IO)
1.文件与目录
1.1概念
文件:文件指的是数据的集合在硬盘的存储,如图片,视频,文本
目录:俗称的文件夹,用于存储文件的结构。
java操作的目录,通过java.io.File类型的对象来操作一个文件或者目录即一个File对象
1.2语法(写代码之前都要判断文件是否存在)
1)创建一个File类型对象和一个文件或者目录一一对应
File file=new File(“文件或者目录的路径”);
2)判断文件或者目录存不存在:file.exists()返回布尔值
boolean bol=file.exists();
样例:
File file1=new File(“F:\d2005\temp\1.txt”);//存在
File file2=new File(“F:\d2005\temp”);//存在
File file3=new File(“F:\d2005\temp\2.txt”);//不存在
if(file2.exists()) {
System.out.println(“文件存在”);
}else
System.out.println(“文件不存在”);
}
3)判断是否是目录类型 file.isDirectory();返回布尔值
boolean bol=file.isDirectoty();
4)判断是否是文件类型 file.ifFile();返回布尔值
boolean bol=file.ifFile();
5)获取文件或者目录名称file.getname();
String filename=file.getname();
6)获取文件大小(字节)file.length();返回的是long表示字节数
b:bit,指的是位 8Bit是一个一个B(Byte);
Long leng=file.length();
long len=(long)(Math.ceil(file.length())/1024);
7)获取文件绝对路径file.getAbsolutePath();返回整个路径(String)
System.out.println(“绝对路径”+file.getAbsolutePath());
8)创建目录midir和mkdirs
file.mkdir();//只创建一级目录
file.mkdirs();//递归创建多级目录
public static void mkdir(File file) {
if(file.exists()&&file.isDirectory())
{
System.out.println(file.getName()+“目录存在”);
}
else
{
file.mkdir();//添加一级目录
System.out.println(“目录创建成功”);
}
}
创建文本文件
String path=“E://D2005//temp//test001.txt”;//文件路径
File file=new File(path);//创建文件对象
if(file.exists()) {//判断文件是否存在
System.out.println(“该文件已存在!”);
}
else {
try {
file.createNewFile();
System.out.println(“文本文件创建成功!”);
9)删除目录或者文件 file.delete()
public static void filedelete(File file) {
if(file.exists()) {
if(file.isFile()) {
file.delete();
System.out.println(file.getName()+“已删除”);
}
else {
file.delete();
System.out.println(file.getName()+“已删除”);
}
}
}
10)获取该目录下面的所有子文件或者目录信息
File[] files=file.listFiles();
public static void deleteFiles(File file) {
//删除目录下面的子内容
if(file.isDirectory()) {
File[] files=file.listFiles();
for(int i=0;i<files.length;i++) {
deleteFiles(files[i]);
}
}
//删除目录
file.delete();
}
11)递归该目录下的所有子文件或者目录信息
2.文件输入输出流
输入:Input 输出:Output
2.1概念
输入流:(inputStream接口)从文件中读取数据的流
输出流:(outputStream接口)从内存往文件写的数据流
字节流:传输单位是一个字节的流
字符流:传输单位是一个字符(两个)的流
输入字节流:FileInputStream以字节为单位的输入流。
输出字符流:FileOutputStream以字节为单位的输出流。
2.2FileInputOutput(字节输入流)
1)创建字节输入流工具
第一种:
try {
FileInputStream input=new FileInputStream(file);
int temp=input.read();
while(temp!=-1) {
System.out.println((char)temp);
temp=input.read();
}
input.close();
FileInputStream input=new FileInputStream(文件路径);
第二种:read(缓冲区数组),一次读取一个数组
try {
FileInputStream input = new FileInputStream(file);
byte[] by=new byte[5];
int temp=input.read(by);
while(temp>0) {
System.out.println(Arrays.toString(by));
System.out.println(“本次读取了”+(char)temp);
temp=input.read();
}
3)关闭输入流工具
input.close();
2.3字节输出流
1)创建字节输出流
FileOutputStream output = new FileOutputStream(file对象)
FileOutputStream output = new FileOutputStream(“路径”);
FileOutputStream output = new FileOutputStream(file对象,append);
FileOutputStream output = new FileOutputStream(“路径”,append);
append:是否追加,true表示不覆盖追加,false是覆盖增加,默认值是false;
2)写 write(int值) output.write(字节的int值)
第一种:一次写一个字节
try {
FileOutputStream output = new FileOutputStream(file);
output.write(‘b’);
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
第二种:一次写入一个数组
try {
FileOutputStream output = new FileOutputStream(file);
String str=“今天是星期日”;
byte[] bytes=str.getBytes();
output.write(bytes);
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
关闭流
output.colse();
文件复制
一次读写
字符输入流(Reader)
特点:单位是一次读一个字符
语法:
创建字符输入流
读字符
第一种:一次读写一个字符
第二种:一次读写一串字符
关闭输入流
字符输出流(Writer)
特点:单位是一次写一个字符
语法:
创建一个字符输出流
Writer fw=new FileWriter(file);
字符写操作
第一种:一次写一个字符
fw.write(‘1’);
fw.write(‘中’);
第二种:一次写一个字符数组
fw.write(char[])
char[] c=new char[10];
c[0]=‘我’;
c[1]=‘爱’;
c[2]=‘中’;
c[3]=‘国’;
fw.write©;
第三种:一次写一个字符数组的一部分
fw.write(char[],起始下标,长度)
fw.write(c,1,2);
字符流拷贝样例:
高阶流
①缓冲字节输入流 与缓冲字节输出流(流自己建立了8k的缓冲区)
利用基本流创建高阶流
//高阶输入流
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
//高阶输出流
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file1));
读写
//自定义缓冲区
byte[] c=new byte[1024];
int len=bis.read©;
//读写操作
while(len>0) {
//写操作
bos.write©;
//读操作
len=bis.read©;
}
bos.write©;
关闭流
bis.close();
bos.close();
②缓冲字节输入流 与缓冲字节输出流
创建缓冲流
BufferedReader br=new BufferedReader(new FileReader(file));
BufferedWriter bw=new BufferedWriter(new FileWriter(file));
读一行或者写一段内容
readLine():返回值即一行内容,如果读取结束返回null
String info=br.readLine();
bw.write(“字符串内容”)//写入一个字符串
bw.newline();//新起一行
bw.flash();//刷新缓存,将之前写的但是没有提交到硬盘的信息提交
关闭流
重定向输入输出
重定向输出流:
系统(console)的输出:默认输出到控制台
我们更改输出位置到其他位置,如文件,即为重定向输出:
try {
PrintStream ps= new PrintStream(“E:/D2005/temp/test05.txt”);//新建打印输出流,更改打印位置
System.setOut(ps);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(“第一句话”);
System.out.println(“第二句话”);
重定向输入流
3.对象流
概念
对象流操作目录:传输单位是对象(标准对象)
标准对象:
必须有无参的构造方法
必须实现序列化接口java.io.Serializable
必须有序列化id(静态常量)
对象输入流(后读)
FileInputStream fis=new FileInputStream(file);//创建一个输入流对象
创建对象输入流
ObjectInputStream ois=new ObjectInputStream(fis);//fis不能是File的对象,要是输入流对象
读一个对象
testclass tc=(testclass)ois.readObject();//将文件的类型转化成testclass
关闭
ois.close();
对象输出流(先写)
创建流
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(file对象或者地址))
写一个对象
oos.writeObject(tc);
关闭
oos.close();
小结:
想要将文件写入对象流,要用输入流(FileInputStream)去实现,
在对象中传入输入流的数据,
再读取对象中的数据,转化为类(强转)的类型,
用类去接收,(如果要输出则要重写类中的tostring)
4.反射
扩展:
nio:既能读也能写
反射注解与junit
1.反射
1.1 概念
在程序运行过程中,能通过全限定名(包名+类名)获取类的所有信息
并且创建该类的实例对象
ClassLoder
1.2 语法
1.2.1 获取类的结构
1)获取类的结构,静态方法forName(“权限定名”)
Class class1=Class.forName(“cn.d2005.java05Reflect.tool.Student”);
2)获取类的结构,用class
Class class2=Student.class;
3)获取类的结构,用成员方法getclass()
Student stu=new Student();
Class class3=stu.getClass();
1.2.2 获取构造方法
1)通过类信息对象获取所有构造方法
getConstructors()
Constructor[] cons= class1.getConstructors();
2)获取单个的构造方法
Constructor cos1=class1.getConstructor(); //无参构造方法
Constructor cos2=class1.getConstructor(String.class,Integer.class);
3)利用获取的构造方法的newInstance(参数列表)去创建对象
Object o1=构造方法对象.newInstance(参数列表);
Object o1=cons[3].newInstance(); //调用Student无参构造方法
Object o2=cons[0].newInstance(“张三”,“男”,25); //调用Student三参构造方法
1.3 获取属性
1)获取所有属性
Field[] field=class1.getDeclaredFields();
2)获取单个属性
Field f=class1.getDeclaredField(“name”);
3)set方法实现利用类结构
//利用获取的构造方法的newInstance(参数列表)去创建对象
Object o=class1.newInstance();
//获取单个属性
Field f=class1.getDeclaredField(“name”);
f.setAccessible(true); //允许直接访问private
f.set(o, “张三”);
System.out.println(o);
1.4 获取方法
1)获取所有方法
Method dm[]=class1.getDeclaredMethods();
2)获取单个方法
Method d=class1.getDeclaredMethod(“setName”,String.class);
3)invoke方法利用类结构中的成员方法更改属性
//利用获取的构造方法的newInstance(参数列表)去创建对象
Object o=class1.newInstance();
//获取单个方法
Method d=class1.getDeclaredMethod(“setName”,String.class);
d.invoke(o, “李四”);
System.out.println(o);
2.注解
2.1 概念
语法: @Xxxx 作用是描述类、方法、属性等
2.2 定义注解
语法:
@Target(ElementType.TYPE)
作用范围 @Target({ElementType.TYPE,ElementType.FIELD })
生命周期 @Retention(RetentionPolicy.RUNTIME) 什么时间段有效
是否可继承 @Inherited 如果父类有该注释,子类可以继承
是否生成文档 @Documented
修饰符 @interface 注解名{
成员 类型 成员名()
例如:String[] value();
}
@Target值:
1)ElementType.TYPE ->类上
2)ElementType.FIELD ->属性
3)ElementType.METHOD ->方法
4)ElementType.CONSTRUCTOR ->构造方法
@Retention值:
1)RetentionPolicy.SOURCE ->文件中有效
2)RetentionPolicy.CLASS ->编译后有效
3)RetentionPolicy.RUNTIME ->运行时有效
抓取注解:
//获取Student类结构
Class class1=Student.class;
//获取Student类的name属性
Field f=class1.getDeclaredField(“name”);
//获取Student类的name属性上的TestNote注解
Annotation a= f.getAnnotation(server.class)
System.out.println(a);
2.3使用注解
语法: @注解名
位置: 受作用范围限制
2.4解释注解(反射获取注解)(反射获取注解)
Method m3=c1.getDeclaredMethod(“testclass1”, Integer.class,String.class);
Annotation an=m3.getAnnotation(server.class);
server s1=(server)an;
System.out.println(s1.value());
2.5常用的注解标签
1)@Override:重写
2)@Overload:重载
3)@SuppressWarnings:警告标签
3.junit
3.1概念:
junit =java unit(单元测试);
junit框架,junit4
3.2项目增加junit jar包
build path ->第三个选项卡->add library->junit 4
3.3使用Junit提供的注解标签
1)@Test->加在哪个方法前,这个方法能独立跑
增加@Test标签的方法规格固定:
public void 方法名(无参数){}
2)@after->在@Test测试方法后都会执行一次
3)@before->在@Test测试方法前都会执行一次
注意:before和after都不能单独运行
多线程
1.1概念
进程(process):程序的一次运行(创建了一个实例),每一个进程计算机都分配内存、cpu、网络、磁盘应用等。
时间片:分配cpu一次运行的最小单位,如10ms(因电脑硬件差异,每个电脑时间片可能不一样)
线程:通过抢夺资源,cpu与资源分配的最小单位,目的是提高资源利用率
主线程:一个进程必须有一个主线程,主线程负责创建、调度、销毁子线程
子线程:子线程是完成真正任务的线程
多线程:一个主线程管理多个子线程即多线程,多线程工作是交替运行,而非真实的并行(同时执行)
1.2线程的创建
主线程:java main方法即主线程入口。
线程的开发:
1)线程类的开发,第一种继承Tread,重写run方法
2)线程的创建,new一个线程(Thread)对象
3)线程启动start(),线程就绪,如果获取了资源就能开始干活
4)线程的销毁,线程run方法(线程体)执行完了或者终止
1.2.1:第一种,通过继承父类(Thread),重写run()方法
1)继承java.lang.Thread
2)重写run()
创建线程对象的方式:
MyThread t1=new MyThread(“张三”);
1.2.2:第二种,通过实现接口,重写run()方法
1)实现Runnable接口
2)重写run()
创建线程对象方式:
MyRunnable mr=new MyRunnable();
Thread t1=new Thread(mr,“张三”);(mr为runnable的参数列表,其中主类有run的抽象方法,重写后调用要使用该构造方法)
Thread t2=new Thread(mr,“李四”);
1.3线程的状态
创建状态:一个线程new出来,即处于创建状态
就绪状态:start()之后处于就绪状态,等抢资源
运行状态:抢到cpu资源,执行run方法
阻塞状态:(只有运行状态才会进入阻塞)当程序处于运行状态,发生了休眠(sleep)、中断等操作处于阻塞状态
死亡状态:正常死亡:run()执行完;非正常死亡(断电)
1.4线程的调度
1)Start():线程启动,线程已就绪,可以参加抢夺资源并执行任务
2)Thread.sleep(时间毫秒):线程休眠;线程会由运行到阻塞,休眠结束进入就绪状态(进行争夺cpu的资源)
3)更改线程优先级
线程对象…setPriority(优先级);优先级1-10:依次增加
t1.setPriority(1);
4)线程对象A.join();//等待线程对象(Thread.currentThread())A执行完后,本线程接着抢资源,本线程进入阻塞
ThreadEextends t1=new ThreadEextends(“甲”);
t1.start();
String name=Thread.currentThread().getName(); //name=main
for(int i=0;i<10;i++) {
System.out.println(
name+“第”+(i+1)+“次打印”);
if(i==2) {
t1.join(); //当i=2时,主线程main进入阻塞,等待t1执行完毕
}
}
5)线程礼让,本线程 本次运行状态 礼让一次(礼让是交出剩余的时间片,重新去线程中争夺资源)
Thread.yield()//线程礼让,本线程本次运行状态,礼让别人一次,线程处于就绪状态,有概率失败(即礼让后还是本线程执行)
6)线程等待:让另一个线程进入等待状态(阻塞状态)
前置条件:线程安全(有互斥锁)的方法内才能实现wait操作
wait操作后:1)锁释放 2)当线程加入等待队列 3)线程阻塞
7)线程唤醒,唤醒队列里的信息
前置条件:线程安全(有互斥锁)的方法内才能实现notify操作
notify操作后:1)等待队列的线程恢复成就绪状态
8)查看线程是否中断(阻塞)
Thead.interrupted()//返回boolean值
1.5线程的同步(线安全)
1.5.1线程数据共享(通信):
使用接口方式创建线程体,多个线程共享一个线程体,如果这个线程体有成员方法,那么多个线程即共享这个变量
public class Tick implements Runnable{
private int total=30; //总数
private int curIndex=0; //当前销售票数
public void run() {
…
}
}
Tick target=new Tick();
Thread t1=new Thread(target,“张三”); //t1,t2共享线程体
Thread t2=new Thread(target,“李四”);
1.5.2线程同步:
概念:线程不安全概念
线程如果实现了数据共享,多个线程同时操作共享数据,那么数据就容易出现线程不安全(操作是一个整体,不能完成一整个操作,就造成不安全)
如:
购票线程 implement Runnable{
int total=30;
int count=0;
public void run(){
while(){
//操作1
//操作2
}
//线程不安全的原因是一个时间片不能将操作1和操作2执行完,就让下一个线程执行(操作1和操作2所有线程共享)
}
线程安全的三种解决方案:
第一种:synchronized 块
//锁对象可以是this也可以是自定义的object对象
synchronized ( 锁对象) {//当有一个线程进入方法后,某个对象也被锁定
//需要作为一个整体运行的代码块
}
第二种:synchronized 方法
public synchronized void tick() {
//需要整体运行的代码块
}
第三种:ReentrantLock互斥锁
锁:加了锁后,没解锁之前,不能进入锁区域操作
互斥锁:加了锁之后,其他线程不能再加锁(进入锁区),除非解锁。(加锁,不解锁会造成死锁)
样例:
ReentrantLock lc=new ReentrantLock();//创建互斥锁
lc.lock();//加锁
…
lc.unlock();//解锁
1.5.3线程之间互相管理(wait+notify):
生产消费模式:producer->consumer
共享数据:
生产者:
消费者:
1.6线程其他操作
1)设置线程名称:
第一套方案:线程类构造方法中super(String name)完成设置;
public MyThread( String name) {
super(name);
}
第二套方案:Thread.currentThread().setName(“xxx”);
public MyThread( String name) {
Thread.currentThread().setName(“xxx”);
}
2)获取线程名字:
第一套:在子线程内通过this.getName()获取线程名字;
第二套:在主线程或子线程Thread.currentThread().getName();
2.线程池
2.1概念
手动创建线程:创建(new) 运行(run) 销毁(自动销毁)
线程缓冲池:预置一部分线程,使用时根据情况考虑是否需要新建线程和
例如:创建10000个线程
普通线程耗时:(创建时间+运行时间+销毁时间)*10000
线程池:创建一个有100个的线程的线程池
线程池耗时:(创建时间+销毁时间)100+运行时间10000
线程池操作步骤:
1)创建线程池
2)创建线程池创建工作
3)关闭线程池
2.2创建线程池的三种方式
1)单线程池:最多只有一个线程池
默认该线程池没有线程,如果创建一个,即有一个
如果有一个,再创建线程,实际上欸有创建,调用之前那个
语法:
//创建单线程池
ExecutorService e1=Executors.newSingleThreadExecutor();
2)固定线程池:最多有n个线程池
先设置线程上限10,默认线程池是五线程的
当我手动创建8个线程,第二次创建5个,实际上是10个
语法:
//创建固定线程池
ExecutorService e2=Executors.newFixedThreadPool(10);
3)缓冲线程池(无线扩展)
默认线程池个数为0,数量是无上限的
什么时候创建线程,当新线程任务来时,已有的线程都没结束,会创建新线程池,上线+1
语法:
//创建缓冲线程池
ExecutorService e3=Executors.newCachedThreadPool();
2.3线程池创建线程
1)Runnable接口方式
e1.execute(new Runnable实现类);
样例:
e1.execute(new ThreadPoolClassq1());
e1.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
String name=Thread.currentThread().getName();
System.out.println(name+":正在运行");
}
});
2)Callable接口方式
Future f=e.submit(new Callable接口实现类)
样例:
Future f=e.submit(new CallThreadClass())
2.4第三种创建线程的方式( Callable接口)
Future f=e.submit(new Callable() {
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
return 5;
}
});
Integer t=f.get();
2.5线程池的应用
数据库缓冲池:DataBase Pool
c3p0,dbpc,druid
1)和固定线程池原理一样。
2)但是多了回收线程的策略。
消息中间件:MessageQueue(消息队列)
RabbitMQ、RocketMQ、ActiveMQ、Kafka
1)和固定线程池原理一样。
2)消息中间件重点是 生产消费模式的共享数据
网络编程
1.概念
网络的作用:交换数据与共享资源
IP地址:用于网络通信的地址,没一台电脑在网络中都有一个地址
IP地址:IpV4,IpV6
IpV4:第一段地址,第二段地址,第三段地址,第四段地址(最大255.255.255.255)
ip地址构成:网络地址+主机地址
网络地址:多台网络设备所在的一个共用网段(区域)
主机地址:网段下的某一个具体的地址(具体)
A类:网络地址(1+3)前8位取值范围:1-126
B类:网络地址(2+1)前8位取值范围:128-191
C类:网络地址(3+1)局域网。前8位取值范围:192-223
D类前8位取值范围:224-239
0,127,255这三段不用
192.168.6.1:1一般代表路由
127.0.0.1代表本机,localhost代表本机域名
0.0.0.0代表所有机器
测试:
1)查看ip:ipconfig
2)ping某一台机子
验证是否可以连通某一台机子
域名:因为ip不好记,所以给ip取一个名称,但是ip需要购买,并且域名与ip一一对应
域名解析器:dns,作用是将域名解析成ip地址
常用的dns:8.8.8.8 114.144.144.144(本机一般会把路由当作dns服务器)
网络通信层协议:高层调用底层,不同的机器(ip)同层交互
应用层:http(浏览器)https(浏览器安全)
传输层:tcp,udp
网络层:ip
2.socket
2.1概念
Socket:套接字,一个设备点
tcp:(Transmission)传出(Control)控制(Protocol)协议
协议:规则
特点:面向连接的传输协议,面向连接指的是先建立连接再通信
如A-B打电话:
1)已知A的地址,B的地址
2)A先拨通B的地址
3)A和B之间沟通消息
4)A和B关闭
udp:(User)用户(Datagrame)数据包(Protocol)协议
特点:非面向连接的传输层协议,直接通信
如A-B发快递:
1)已知A的地址,B的地址
2)将A需要发送的信息打包发送给B
3)中间可能成功也可能失败
扩展知识:
1)Socket:通信的端点,如通信电话的A,B和发包裹的A,B
2)port(端口):是一个数字值 范围0-65535,用于分派通信。端口被占用后不能被另一个服务使用,除非端口被释放了
3)http协议:非面向连接,无状态的应用层协议
4)无状态:每一次访问后无记录任何当时的状态和信息,每次访问都是独立的
2.2基于tcp socket开发
多个客户端(Socket)与一个服务器(ServerSocket)数据交换,客户端与客户端之间不允许直接沟通
Socket服务器开发:
1)创建服务器端
ServerSocket s=new ServerSocket(端口号);//创建服务器
2)等待客户端的请求,如果有则创建一个Socket对象准备通信
Socket ac=s.accept();//等待客户端连接
3)读写
BufferedReader br=new BufferedReader(new InputStreamReader(ac.getInputStream()));//读的是从客户端写入的数据(ac)
4)关闭
s.close();
Socket客户端开发:
1)创建一个客户端(发起一个指向服务器的Socket)
Socket s=new Socket(“127.0.0.1”,8000);
2)读写
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write(“我是客户端”);
bw.flush();//刷新用于输入到缓存
s.shutdownOutput();//关闭写入流,关闭用客户端关闭
//不要用close()去关闭输入输出
3)关闭客户端
s.close();
2.3基于udp socket开发
Socket发送方开发:
1)创建一个Socket
DatagramSocket ds=new DatagramSocket();
2)准备一个包裹数据(内容、接收地址)
String p=“这是你的包裹”;
byte[] buf=p.getBytes();
DatagramPacket dp=new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 8000);
3)发送包裹动作
ds.send(dp);
4)接收包裹
Socket接受方开发:
1)创建一个Socket
DatagramSocket ds=new DatagramSocket(8000);
2)准备一个空包裹
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf, buf.length);
3)接收包裹
ds.receive(dp);
4)处理包裹中的有效信息
String s=new String(dp.getData());
3.集合Iterator
集合(Collection)三大体系:List体系,Set体系,Iterator体系
3.1概念
迭代器:一次取一个值,知道某一次取不到值,即结束,这是一个工具,不是一个结构
3.2语法
1)将一个集合转化成迭代器结构的数据
数据类型->Collection->Iterator
ArrayList list=new ArrayList()
list.add(1);
list.add(2);
list.add(3);
Iterator it1=list.iterator();
2)取一次值
类型 变量=it1.next();
3)循环取值,取到不饿能再取值为止
用增强for循环取值
int a;
while(it1.hasnext()){//判断是否还能取值
a=it1.next();//取一次值
System.out.Println(a)
}
XMl
1.概念
xml:eXtensive(可扩展)Markup(标记)Language(语言)(语言:具有一定格式的语言)
xml文件:.xml后缀,不依赖任何平台
xml节点:node(节点)或者element(元素)
1)节点总结构
<节点名,属性=“值”>
<子节点1 属性=“值”> </子节点1>
<子节点2 属性=“值”> </子节点2>
<子节点3 属性=“值”> </子节点3>
<子节点4 属性=“值”> </子节点4>
</节点名>
2)节点命名规范
①节点名包含数字、字母、符号,但是不能以数字和符号开始
②节点名不能包含空格
③节点必须正确的关闭
④节点大小写敏感(大小写不等)
xml 属性:属性在节点上,一个节点可以有多个不同的属性
<节点 属性1=“值1” 属性2=“值2” … > </节点>
xml文本节点:
<节点>文本节点</节点>
xml结构:
<–声明部分:
1)xml语言的版本1.0
2)encoding:当前所有文本的编码集
ISO-8859-1:国际默认编码集,但不支持中文
UTF-8:统一编码集,支持所有语言
gbk和gb2312:支持中文
–>
如:<?xml version="1.0" encoding="UTF-8"?>
<–
文档结构部分:由一个根(Root)节点和无数个子节点构成
–>
<根节点>
<子节点> </子节点>
<子节点> </子节点>
<子节点> </子节点>
</根节点>
扩展知识点:
1)xml中 属性或者文本节点中不能出现 > < =
> 替换 >
< 替换 <
= 替换 &eq;
>= 替换 %ge;
2.编写xml
<–声明部分:
1)xml语言的版本1.0
2)encoding:当前所有文本的编码集
ISO-8859-1:国际默认编码集,但不支持中文
UTF-8:统一编码集,支持所有语言
gbk和gb2312:支持中文
–>
如:<?xml version="1.0" encoding="UTF-8"?>
<–
文档结构部分:由一个根(Root)节点和无数个子节点构成
–>
<根节点>
<子节点> </子节点>
<子节点> </子节点>
<子节点> </子节点>
</根节点>
3.编写dtd
3.1概念
元数据:描述或定义数据的数据叫元数据
如:java中类于对象的关系,类即元数据,对象即数据
xml中xml文件即数据,dtd文件即元数据
dtd:xml的元数据。
3.2 dtd语法:
<!DCUTYPE 根节点[ <--xml中每一个子节点 属性 的规范-->
<–节点
+ * ? 以及不加任何符号
*:0-n个
+:1-n个
?:0-1个
不加:有且只有一个
–>
<!ELEMENT 节点名 (子节点信息*)>
或者
<!ELEMENT 节点名 (#PCDATA)>//PCDATA表示存在文本信息
<–属性–>
<-- 第二部分 属性定义–>
<!ATTLIST 节点名 #REQUIRED 必选项目 #IMPLIED 非必须 属性名1 类型 是否必须 属性名2 类型 是否必须 >
样例:
<–节点–>
<!ELEMENT Cloths (hight*)>
<!ELEMENT hight (id,discription)> <–存在顺序–>
<!ELEMENT id (#PCDATA)>
<!ELEMENT discription (#PCDATA)>
<!ATTLIST hight size CDATA #IMPLIED name CDATA #REQUIRED >
]>
]>
3.3dtd的使用
3.3.1 xml内定义
dtd如果定义在xml内,只能当前xml使用
语法:
<!DUCTYPE 根节点[ 字节点与属性 信息 ]>
3.3.2 xml外定义
1)将dtd单独的定义成一个文件(文件后缀位.dtd)
2)外部dtd 只出现节点和属性 不出现 DOCPYTE
3)使用外部dtd 需要在xml引用dtd
样例:
3.4 xml解析器
验证解析器:通过dtd 来校验xml是否规范
非验证解析器:简单检查xml是否格式正确(如是否节点正常关闭)
4.java 操作xml
4.1 概念
dom:Document Object Model (文档对象模型),以对象的方式操作整个文档
sax:验证与解析xml文档体系。
jdom:jdk自带的,但是开发了大量的工具类(很少用接口),20%工作完成80%任务,缺点是开发难度高
dom4j:简化了开发,提供了简洁的替换类(替换了原生类)
区别:
1)dom和sax是两种体系
2)dom、sax和jdom都是jdk自带的(类、接口、工具)
dom4j第三方包
4.2 dom4j 读文件
1)将整个xml转化成一个document对象
SAXReader sax=new SAXReader();//创建sax解析工具
Document document = sax.read(new File(“Xml/test.xml”));
2)从document对象中获取根节点
Element root=document.getRootElement();
System.out.println(root.getName());
3)获取根节点的属性或子节点
Iterator it=root.elementIterator();
while(it.hasNext()) {
//获取每一个子节点
Element son=it.next();
System.out.println(son.getName());
4)递归第三步骤
获取节点(Element)属性:
Attribute idAttr=element.attribute(“属性名”);
idAttr.getStringValue();
获取节点中的文本信息:
String Text=element.getStringValue()
4.3 dom4j 写文件
1)创建Document(指向系统文件中的一个xml)
Document document=DocumentHelper.createDocument();
2)创建root根节点
Element root=DocumentHelper.createElement(“Books”);
document.add(root);
3)创建子节点(配置属性以及与父节点的关系)
//创建子节点
Element book1=DocumentHelper.createElement(“book1”);
//给子节点加属性
book1.addAttribute(“bookNO”, “1001”);
//子节点创建节点
Element author=DocumentHelper.createElement(“author”);
author.addText(“张三”);
Element description=DocumentHelper.createElement(“description”);
description.addText(“张三编写javaopp”);
Element book2=DocumentHelper.createElement(“book2”);
book2.addAttribute(“bookNo”, “1002”);
root.add(book1);
root.add(book2);
book1.add(author);
book1.add(description);
4)保存操作
XMLWriter xw=new XMLWriter(new FileOutputStream(“E:/d2005/temp/test.xml”));
xw.write(document);
//关闭流
xw.close();
5.json数据(fastjion)
maven与poi
1.maven
1.1 概念
maven是一个项目构建工具
构建工具:javac->编译java源码
maven->编译java源码+管理jar包+项目结构管理
maven中央仓库:国内或者国外知名jar管理网站
maven本地仓库:本地存储maven管理的jar包的目录,如果本地没有包则去远程下载到本地
maven私有中央仓库:个人或者公司
1.2 maven安装
1)获取安装包
maven主目录:
bin:二进制命令
conf:配置文件(setting.xml)
2)配置环境变量
M2_HOME=maven主目录
PAth 增加maven主目录/bin
3)测试maven版本
$>mvn -version
4)更改maven配置文件(maven主目录/conf/settings)
第一步:本地仓库配置
E:/d2005/repo
第二步:中央仓库地址->阿里云的中央仓库(maven 阿里云仓库)
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
第三步:maven编译项目的版本更改为jdk1.8(maven jdk1.8)
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
5)初始化本地仓库
$>mvn help:system
1.3 eclipse集成maven
eclipse 工作空间每一个都需要重新手动继承maven
1)位置window ->perferences->maven
2)maven installation(maven安装位置):选择一个maven服务器,增加自己的maven主目录(选中)
3)maven user settings->选择使用一个settings.xml文件
用户settings->加入settings.xml文件的路径
1.4 eclipse创建maven项目
1)new->maven project
2)选择maven 模板(不同的模板初始化的目录不一样)选择quickstart
3)配置项目名称与组织机构名
GroupId:组织机构名字
ArtifactId:项目名
version:版本0.0.1-SNAPSHOT(SNAPSSHOT结尾的版本)
finish开始创建项目
2.poi
2.1 概念
poi是java操作office的第三方包
2.2 maven导入poi jarb包
HSSF:excel 07之前后缀.xls结尾
XSSF:excel 10之后后缀.xlsx结尾
workbook:工作台
sheet:页
row:行
cell:单元格
2.3 poi写excel
1)创建工作空间Workbook
Workbook wb=new HSSFWorkbook();
2)创建页sheet
Sheet page1=wb.createSheet(“第一页”);
3)创建行row
Row r1=page1.createRow(0);
4)创建单元格cell
Cell c1=r1.createCell(0);
c1.setCellValue(“姓名”);//设置单元格内容
r1.createCell(1).setCellValue(“年龄”);
r1.createCell(2).setCellValue(“员工号”);
for(int i=1;i<=9;i++) {
Row r=page1.createRow(i);//循环创建行
r.createCell(0).setCellValue(“员工”+i);
r.createCell(1).setCellValue(25);
r.createCell(2).setCellValue(“ds100”+i);
}
5)写入文件并关闭
wb.write(new FileOutputStream(“E:/d2005/temp/test.xls”));
wb.close();
2.4 poi读excel
1)获取现有的工作台Workbook
Workbook wb=new HSSFWorkbook(new FileInputStream(“E:/d2005/temp/test.xls”));
2)获取页sheet
Sheet s=wb.getSheet(“第一页”);
3)获取行(循环获取)
4)获取单元格(循环获取)
5)关闭流
//获取所有行
for(int i=0;i<=s.getLastRowNum();i++) {
Row r=s.getRow(i);//获取单个行
//获取所有单元格
for(int j=0;j<r.getLastCellNum();j++) {
Cell c=r.getCell(j);//获取单元格
System.out.print(c.getStringCellValue()+’\t’);//获取单元格里的数据
}
System.out.println(’\n’);
wb.close();//关闭流