第一章;集合框架
集合框架(多个接口和类)
- 不知道存在的对象的数量或者需要更复杂的方式来存储对象时(一一对应时也可以使用),可以使用集合框架、
- Java集合框架提供一套性能优良、使用方便得接口和类,它们为与java.util包中
a) Collections为工具类
b) 图中实线框为类,虚线框为接口
c) Map与iterator与collection没有父子关系关系,但他们是有关联的(produces关系)
d) Collection是所有集合框架的父接口,collections是操作集合的一个工具类(提供了对集合进行排序、遍历等多种算法实现) - Collection接口存储一组对象,不唯一、无序(即是可以放重复的对象)的对象
- List接口存储一组不唯一,有序(插入顺序)的对象
- Set接口存储一组唯一的,无序的对象
- map接口存储一组键值对象,提供key到value的映射(一对一对的,键为key,值为value,它们又称为kv值)
a) 键(key)必须为唯一的(等同于set)
b) 值(value)可以有多个一样的
- List接口的实现类
a) Arrayslist长度可以变的数组,在内存中分配连续的空间,遍历元素随机访问元素的效率比较高
b) Linkedlist采用链表存储方式(前一个数据末尾存储了下一个数据的地址)。插入、删除元素时效率比较高(可以不是在同一个的空间中存放(即不是一个连续的空间))
c) Arraylist的方法使用
i. ArrayList位于util包中,使用时需要进行导包进入
ii. 集合也有长度,通过集合的名字打点调用size()方法即可获得集合的数量
iii. 在遍历输出集合中的值时也需要通过下标进行输出,(使用集合名.size(下标)获得)
iv. 输出其中的某一个时,通过.get获得
d) 语法书写
demo11 one =new demo11(25, “没有”);
demo11 one2 =new demo11(252, “没有4”);
demo11 one3 =new demo11(253, “没有5”);
demo11 one4 =new demo11(254, “没有6”);
ArrayList list=new ArrayList();
list.add(one);
list.add(one2);
list.add(one3);
list.add(one4);
System.out.println(list.size());
for(int i=0;i<list.size();i++){
demo11 a=(demo11)list.get(i);
System.out.println(a.getTlitle());
}
也可以通过增强型的for来进行输出(但类型是为object类型的进行输出,语法for(object s: lasit){ } )输出集合时必须要通过强制转换才能输出。
标红的为collection的方法,所有的list 和set都有这些方法
clear清空元素 isEmpty判断集合是否为空(返回值为布尔类型) - 泛型(< E >);通过泛型来规定集合中存储的数据类型(使用泛型之后就只能保存规定好的数据类型,其余类型不能保存)
a) 在泛型中(也就是尖括号中需要写数据类型的包装类,直接写数据类型是不可以的)
b) 语法书写(jdk1.7以后的版本可以不写后面的泛型类型)
Listlist2=new ArrayList();
list2.add(“泛型”);
list2.add(“小王八”);
c) remove的使用,通过(集合名).remove进行删除
i. remove可以通过下标进行查找,也可以直接删除对象 - linkedlist(采用链表式存储的,在插入,删除时比较高)
a) linkedlist用法ArrayLsit的用法一样
b) ArrayLsit的方法linkedlist都能使用,且linkedlist具有ArrayLsit没有的方法
c) linkedlist独有的方法
i. 在list集合的方法上加上last或者first进行在首位(末尾)进行操作 - 使用迭代器进行遍历
a) 迭代器类型必须与数据类型一样
b) 迭代器是方便修改的,如果只要遍历,就不建议使用了,要修改就推荐了
c) 语法书写
Iterator IT = list.iterator();
while(IT.hasNext()){//判断是否有下一条数据
demo2 next = IT.next();//获取每一条数据
System.out.println(next);
} - set集合接口(不存在get方法)
a) HashSet
i. HashSet是set接口的常用的实现类
ii. 在set中如果两个值相同,那么只会打印一个
iii. 确保唯一性(就是两个对象值一样,但地址不一样时,我们同过重写equals方法进行确保他的唯一性)
iv. 要获取set集合的值要使用增强型for或者用迭代器 - 使用for增强型时用object类型进行接收,然后进行转换
- 用迭代器进行遍历(代码)
Iterator cat= cats.iterator();
while(cat.hasNext()){
Cat ni=(Cat) cat.next();
System.out.println(ni.getNaem());
}
v. 判断set集合中是否存在同一个元素
b) TreeSet - map接口
a) 以对出现的都使用map接口集合
b) hashmap是map的实现类之一
c) 通过size获得的是对数,不是个数
d) 要获得hasmap的值可以通过get获得,返回的是object类型,必须要转换才能获取(在get(传入键)获得值)
i. containskey是否包含某个键
ii. containsvalue是否包含某个值
iii. remove( 键)移除键值
e) 分别显示map中的键集,值集和键值对集(countries为map名,可以改变)
i. 或去键集countries.keySet( )
ii. 获取值集countries. values();
iii. 获取键值对集countries
f) 清空
i. countries . clear( )
ii. 判断是否为空
iii. countries . isEmpty()
- map里的键一定是唯一的,且没有序,键的返回值是set,值的返回类型是collection,值是可以一样的,且是无序的
a) 获取map集合的方法
b) hasNext判断是否有下一个
i. 方法一
for (Object obj : key) {//方法一
String keys=(String)obj;//将object转换为String类型
String value=(String)map.get(keys);//通过get方法获取值
System.out.println(keys+value);//输出键和值
}
ii. 方法二
Iterator otp=key.iterator();//生成迭代器
while (otp.hasNext()) {//方法二
String keys=(String)otp.next();//获取key
String values=(String)map.get(keys);//通过get方法获取值
System.out.println(keys+"-"+values);
}
iii. 方法三
for (Map.Entry<String, String> object : ms) {//方法三
System.out.println(object.getKey()+object.getValue());
}
方法四
//将key生成set集合
Set keySet=map.keySet();
//map.get(key)获取value值
for (String s : keySet) {
System.out.println(s+";"+map.get(s));
}
iv. 详情 - 每一个map集合都是Map.Entry类型的
- 通过get(key)的方法获取键对应的值
- map使用put方法进行赋值(赋值的内容为一对一对的)key值唯一,不能重复,重写key值会覆盖原来的值,相当于修改
- containsKey判断是否包含某一个键(有返回值,返回值为布尔类型)
- remove ( “ key”)删除对应的键值对
- 分别获得键集,值集和键值对集
a) keySet获得键集
b) value获得值集
c) 直接书写map集合名获得键值对集 - map集合的value值可以是其他的集合,也可以是固定的数据类型
- 生成迭代器关键字Iterator
- 删除的是key值,同时value的值也会被删除(也是用remove方法删除)
a) 在遍历删除数据必须使用迭代器进行删除操作
代码SetkeySet=map.keySet();
Iterator it = keySet.iterator();
while (it.hasNext()) {
String key = it.next();
if(name.equals(key)){
it.remove();//删除指定的键值对
}
} - 通过Entry的方法可以利用.setValue的方法进行统一修改value的值
代码如下
Set<Entry<String, Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
entry.setValue(entry.getValue()+100);
System.out.println(entry.getValue());
}
第二章;枚举
枚举(enum)
- 枚举作用相当于封装,可以对数据进行保护
- 枚举相当于现实生活中的举例,对特有属性值得范围进行枚举,从而达到对数据进行保护的作用
- 枚举指的是有一组固定的常量组成的类型
- 枚举的关键字enum 在enum后的为枚举名 在大括号里的为枚举包含的常量(也可以写属性与方法,但使用情况少,一般声明的都为常量)
- 在枚举中多个常量用逗号隔开,且可以不用声明数据类型
- 在使用枚举的时候可以将原来的数据类型替换成为枚举名(枚举是一种类型)在赋值的时候可以通过打点调用,赋的值为枚举的常量值,(赋值为非枚举的常量时,jdk会报错)
- 使用枚举的好处
a) 类型是安全的
b) 易于输出
c) 代码清晰
d) 枚举可以重复使用,具有通用性 - 利用枚举判断输出时建议使用switch语句进行判断输出
第三章;泛型
泛型
- 从jdk5以后系统提倡使用泛型进行书写集合
- 泛型可以解决强制类型转换时出现的错误或异常
- 泛型是将对象的类型作为参数,指定到其他类或者方法上从而保证类型转换的安全性和稳定性(本质是参数化类型)
- 泛型集合可以约束集合内的元素类型
迭代器也可以书写泛型 - 在map中使用泛型需要通过给键值进行定义类型,也就是要赋值两个数据类型,用逗号隔开
书写语法
//所有的键值是map.entry类型的,而里面的键值类型是可以自己定义的类型Set<Map.Entry<String,String>>ms=map.entrySet();//获取所有的键值对
for (Map.Entry<String, String> object : ms) {
System.out.println(object.getKey()+object.getValue());
} - 在ArrayList中直接在集合类型后面加泛型即可
a) 书写语法
ArrayList list=new ArrayList();
第四章;包装类
包装类
- java.lang包也是jdk的系统自带的包之一,但jdk自动导入了该包,无需手动导入
- java.lang包中包含着enum,包装类,math,string,stringBuffer,system,等
- java常见的包有,java . lang java . util java . io java . sql等
- 包装类
a) 包装类把基本类型数据转换为对象
b) 每一个基本类型在java.lang包中都有一个相应的包装类 - 包装类的作用
a) 包装类提供了一系列实用的方法
b) 集合不允许存放基本数据类型数据,存放数字是,要用包装类
- 包装类
a) 在基本数据类型的基础上将首字母大写就是对应的包装类(除char和int类型外,char的包装类是character,int的包装类是integer) - 包装类的构造方法
a) 所有包装类都有的构造方法(将与之对应的基本数据类型做参数)
i. public Type(type value)
如Integer i=new Integer()
b) 除Character类之外的构造方法(将字符串做参数)
i. public Type(String value)
如 Integer i =new Integer( “123” )
c) 代码
i. 第一种构造方法书写代码
//所有的包装类都有的构造方法,将与之对应的基本数据类型做参数
int i=9;
Integer il=new Integer(i);
其中也可以直接赋值,不需要定义int i;
ii. 第二中构造方法书写代码
//所有的包装类都有的构造方法,除character外,将字符串做参数
int i=9;
Integer il=new Integer(“i”);
其中也可以直接赋值,不需要定义int i;
iii. 在用第二种构造方法时,字符串类型必须能转换为对应的包装类类型,(比如;integer包装类不能接受integer(“我”) ),否则会出现运行时报错,但编译时不会报错
iv. 当用字符串构造方法构造布尔类型的包装类时,不区分turn或flash的大小写(当赋值不为turn时,返回值都为false)
- 包装类常用方法
a) 包装类常用方法一value
将包装类转换为基本数据类型
i. 语法代码;(需要用新的变量进行接收,也可以直接写成int j= il ; )
Integer il=new Integer(10);
int j =il.intValue();
b) 包装类常用方法二
i. 将基本类型转换为字符串tostring - 方法一,利用tostring方法(每一个包装类都有tostring方法)
代码 ;int num=23;
String StrNam=Integer.toString(num); - 方法二,在后面加双引号(常用为这种方法)
代码;int num=23;
String nams=num+"";
c) 包装类常用方法三parse
i. 将字符串转换为对应的基本数据类型数据(character除外)
代码;String s=“49”;
int na=Integer.parseInt(s);
其中parse后面的可以改变,改变为对应的数据类型
d) 包装类常用方法四valueOf
i. 把基本类型转为包装类 - public Static Type valueOf( Type value)
如Integer Intvalue=Integer.valueOf( 21);
(使用方法与前面的通过构造进行转变的一样
)
书写语法
Integer ins=Integer.valueOf(89);
ii. 把字符串类型转为包装类(除character外) - public Static Type valueOf( Type value)
如Integer Intvalue=Integer.valueOf( “21”);
(使用方法与前面的通过构造进行转变的一样
)
书写语法(它和构造方法一样,都有相同的规定)
Integer ins=Integer.valueOf(“89”);
时间类 - 时间类关键字date,通过date类进行生成
- 代码详情(SimpleDateFormat位于text关于包中年月日在jdk帮助文档中有说明)
- 通过format方法进行输出时间(一般有接受的对象,也称为时间格式转换器)
Date date=new Date();
//获取当前时间
System.out.println(date);
//更改时间的格式 yyy年 mm月 dd日 hh 12小时进制的时 HH 24小时进制的时 mm 分ss秒
SimpleDateFormat sdf=new SimpleDateFormat(“yyy年 mm月 dd日 hh时 :mm分:ss秒”);
String time=sdf.format(date);
System.out.println(time); - 获取的当前的时间(calender类,不常用获得的都是西方的时间日期)
a) calendar类是个抽象类,不能直接new对象
b) 通过getInsance方法进行new对象(calender t =calendar.getInstance)
c) 通过调用get方法进行获取(t.get(YEAR)获取年,t.get(MONTH)获取月(从0开始),t.get(DAT_OF_MONTH)获取日, t.get(DAT_OF_WEEK)获取星期(从星期天开始))
装箱和拆箱
18. 生成随机数,(利用Randim类(随机数类))
a) 随机数类是从0开始的
代码
Random r=new Random();
int n=r.nextInt(10);//获取0-10的整数
19. math数学类,提供了一系列的数学运算方法和自然底数E和π的取值IP
20. 向上取整(math.ceil)
21. 向下取整(math.floor)
22. 四舍五入(math.round)
23. 去绝对值(math.abs)
24. 求最大值,最小值(math.max/math.min)
25. 求随机数(math.randim)(不常用,一般用random类进行获取)
a) 语法
b) int rand=(int)Math.random()*10;
26. string类可以通过new赋值,也可以直接赋值
a) toLowerCase小写
b) toUpperCase()大写
c) concat拼接字符串(也可以用+号连接),有返回值,需要接受
d) 其余的方法书写代码(部分方法)
String s1=“1234567890”;
//在字符串中首次出现的索引,没有为-1
System.out.println(s1.indexOf(“526”));
//截取下标位置开始到末尾的字符串
System.out.println(s1.substring(5));
//截取两个下标之间的,不包含后一个
System.out.println(s1.substring(2, 7));
String s2=" q 13 “;
//去除首尾的空格
System.out.println(s2.trim());
//判断是否是某个字符串结尾
String s3=“woork.java”;
System.out.println(s3.endsWith(”.java"));
//判断是否是某个字符开头
System.out.println(s3.startsWith(“w”));
//将字符串以“-”进行拆分(\为转移字符)
String s6=“s-f-g-g-s”;
String []strs=s6.split("-");
27. 装箱;将基本的数据转换为包装类的对象;
28. 拆箱;将包装类转换为基本数据类型的数据;
29. 装箱和拆箱在jdk5之后才自动回生成,jdk5之前没有
第五章;stringbuffer类
StringBuffer类
(操作的是本身,不是副本)
- StringBuffer:对字符串频繁的修改时使用;(修改的是字符串本身)
- StringBuffer的声明;(StringBuffer不能直接赋值给string类型的变量)
a) StringBuffer strb=new StringBuffer( );
b) StringBuffer strb=new StringBuffer( “aaa”);
c) 用法与string一样(String Buffer的数据是String Buffer类型的,不能直接赋值给string类型) - StringBuffer转换为字符串使用tostring方法(strb.toString)
- string转换成StringBuffer直接建立对象就可以了(参数为要的string类型值就行)
- StringBuffer方法追加(增加字符,修改的是本身)
a) append()方法进行追加,在括号中填入要增加的字符 - StringBuffer方法插入(在某一个位置插入某一个内容)
a) insert(位置,“要插入的内容”)(StringBuffer的位置与数组一样,下标也是从0开始)
b) 在stringBuffer中也可以插入变量名(可变时使用stringBuffer,stringBuffer与stringbuilder是一样的)
random类(随机数生成器)
通过随机数生成器调用它的方法获得随机数 - random类是获得随机数的类(取值从0开始)
- 使用方法是通过new来获得(创建对象来获得)
- 生成整数;对象名.nextInt( )生成随机整数
- 生成随机指定的整数;对象名.nextInt(指定范围)(指定的范围不能超过int的范围)
- 种子的使用
a) 同一个种子值来初始化两个random对象,然后用每个对象调用相同的方法,得到的随机数也是相同的
b) 不同的种子来初始化的random获得的随机数是一样的 - 种子;指的就是new的random类后面()括号里的参数,没有参数,种子不一样,设置参数相同时,种子一样
- 代码书写
a) Random random=new Random( )(没有种子)
random.nextInt( 需要的随机数的大小范围 )
b) Random random=new Random((使用最多的种子是时间(种子变化的范围越大,生成的随机数越随机)) )(有种子)
random.nextInt( 需要的随机数的大小范围 )
第六章;ccollections算法类
Collections算法类
- java集合框架将针对不同数据结构算法的实现都保存在工具类中
- collections类提供了一系列的用于操作集合的静态方法
- collections是集合的操作类,而collection是集合接口
- collections中常用的静态方法
a) sort();排序
i. 书写语法
//排序
Collections.sort(list);
//默认为升序排序
for (String string : list) {
System.out.println(string);
}
//反转也就是降序排序
Collections.reverse(list);
for (String string : list) {
System.out.println(string);
}
b) binarySearch( );查找
i. 书写语法
//查找//返回值是集合的下标 System.out.println(Collections.binarySearch(list, “c”));
其中list为集合名 c为查找的元素名
c) max()\min();查找最大值\最小值
i. 默认返回的类型是object类型的,可以通过强制转换进行转换
ii. 书写语法
//最大值 有转换的
Stringstr=(String)Collections.max(list);
System.out.println(str);
//最小值没有转换的
System.out.println(Collections.min(list); - 要对自己定义的类的对象进行排序的话,必须重写compareTo()方法且要实现comparable接口
a) 重写compareTo()方法需要自己进行书写比较规则
b) 重写compareTo()方法有返回值,返回值是int类型的,return 为0时是一样大,return为1时当前的对象大,return为-1时当前的对象小
c) 书写语法
public int compareTo(Demo2 arg) {
if(this.monery>arg.monery){
return 1;
}else if (this.monery<arg.monery){
return -1;
}else{
return 0;
}
}
第七章;IO流
javaIO(输入输出流)
-
持久化存储,(数据不会丢失)
a) 数据源;操作数据来源称为数据源
b) 数据汇;通过程序进行对数据进行操作,保存到新的目的地称为数据汇
c) 文件来源(数据源)有两种(暂时的和永久的)
i. 永久保存;文件(称为文件,数据运行后不会丢失)
ii. 暂时保存;键盘、控制台、内存(数据运行后会丢失,不能重复使用) -
IO(输入输出流,一般指在数据是文件(永久保存)的作用上进行数据的交互)
a) 站在程序的角度上看,分为读与写两种
b) 读为input(也就是输入,简写为I)
c) 写为output(也就是输出,简写为O) -
文件(一些数据的集合)
a) 文件保存在java.io包中(java .io.file)
b) 使用时用new来获得( File file=new File(String pathname) )是一个构造方法, String pathname 代表的是文件的路径名,是string类型(书写方法一般为;c:\text.txt或c:/text.txt,与在计算机中的书写有区别)
c) file可以是指文件,也可是指文件目录 -
路径
a) 相对路径;不是从盘符进行寻找的
b) 绝对路径;从盘符进行寻找的 -
获取file的长度返回的是字节(0L)(L是强制转换)(一个字符是两个字节)
-
使用的代码情况
//创建文件对象
File file=new File(“E:\JAVA文件输入输出案例实用\a.txt”);
//判断文件是否存在 System.out.println(file.exists());
//判读是否是文件夹
System.out.println(file.isDirectory());
//判断是否是文件
System.out.println(file.isFile());
//删除一个文件
file.delete();//删除之后再盘符中也会对应的删除,无法通过java进行恢复 -
使用创建文件时,会产生编译时的异常,必须通过捕获,否则无法通过编译(在使用数据库时也会常常出现编译时的异常)
//创建文件
if(!file.exists()){//判断文件是否存在,不存在进行新建
try {
//创建文件时会产生异常,必须进行捕获,它是编译时异常,不捕获无法通过编译
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} -
创建文件过后进行删除,文件的路径还是存在的,相当于在创建文件时,先建立的文件路径,在建立的文件,删除的是文件,路径不会删除(就是,先建立房子,有没有人住是另一回事,新建文件就是建立人,删除文件就是删除人)
-
流(相当于水管流水一般,读写文件一般用流来进行读写)
a) 流是一组有序的数据序列
b) 以先进先出方式发送信息的通道(先读到什么就先写什么) -
流区分(他们的父类是抽象类)
a) 输入流;inputStream(输入字节流)和reader(输入字符流,一般用于处理文本内容)作为基类(也就是父类)
b) 输出流;outputstream(输入字节流)和writer(输入字符流,一般用于处理文本内容)作为基类(也就是父类)
c) 字节流是8位通用字节流,字符流是16位Unicode字符流
字节流
处理音频视频图片等内容必须使用字节流 -
使用io流进行获取内容
a) 先判断是输出还是输入,在根据实况进行使用字符或字节进行输入输出
b) 代码书写
//使用io时要判断是输入还是输出
try {
//创建输入流对象 可以传入文件名,也可是文件路径名
FileInputStream fis=new FileInputStream(“E:\JAVA文件输入输出案例实用\a.txt”);
byte[] b=new byte[1000];
//将读取到内容存放到数组中,他是有返回值的,返回的是内容的长度
int len=fis.read(b);
//关流fis.close();
//将数组内容转换成字符串
String s =new String(b, 0, len);
//输出获得的内容
System.out.println(s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
c) 使用将数组中的内容转换为字符串时要注意string对象的构造方的参数数量(用三个参数的构造方法) -
使用输入输出流后,需要进行关流,以便减少内存的占用
a) 代码书写
//关流
fis.close(); -
逐个输出字符(这只是另一种方法,输出只有一遍)
a) 代码
//逐个输入
int ads=0;
int i=0;
while ((ads=fis.read())!=-1) {
b[i++]=(byte)ads;
System.out.print(new String(b));
}
//关流
fis.close(); -
输出流
a) 输出流是将java文件写入到计算机中
b) 通过.getBytes( )方法将字符串转换为字节
c) 在输入输出流中要实现换行加\r\n
d) 要实现不覆盖原来得数据,在参数列表中加人true(默认是false,也就覆盖原来的数据)
e) 输出流的代码书写
try {
//创建输出对象 在参数中加上true为保存原来的数据,要实现换行加\r\n
FileOutputStream fis=new FileOutputStream(“E:\JAVA文件输入输出案例实用\a.txt”,true);
String s ="\r\nabcdefghijkmlnopqrstuvwsxyz";
//将字符串转换为字节
fis.write(s.getBytes());
//刷新,将内存中的数据刷新到文件中
fis.flush();
//关闭流
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} -
在输出流中必须要加上close,否则无法输出,但在输入流中可以不写,能输入(推荐读写)
a) 刷新,flush()与close的目的不一样,flush是刷新内容,将内存中的数据传输到计算机中
b) close()关流;关流是将输入输出流进行关闭,使数据无法再进行传输修改,从而减少内存的占用,同时也可以将内存中的数据传输到计算机中(调用close方法时也会掉用flush方法,当调用flush方法不会调用close方法,这也是他们的区别) -
利用io流进行复制
a) 通过输入输出流的方法进行对换
b) 代码
try {
FileInputStream fos=new FileInputStream(“E:\JAVA文件输入输出案例实用\1.jpg”);
FileOutputStream foss=new FileOutputStream(“E:\JAVA文件输入输出案例实用\2.jpg”);
int i=0;
while ((i=fos.read())!=-1) {
foss.write(i);
}
System.out.println(“复制完成”);
fos.close();
foss.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
字符流
处理用户能看得懂的数据内容一般都使用字符流(文本内容)
输入流(reader类) -
便于读取各种带编码的文件,比字节流获取数据效率更高
-
字符流
a) 字符输入流(reader读取数据方法)
i. read方法与字节流的read方法一样,但存放参数类型的是char类型,不再是byte类型的参数
ii. read方法的构造方法依旧存在
b) 字符输出流(writer)
i. 在利用writer进行遍历输出时通过 . readerline( )方法进行输出不会出现空方格,如果用 . reader()方法进行输出的话会出现空方格
c) 输出字符流代码
try {
//创建文件对象
FileReader fis=new FileReader(“E:/JAVA文件输入输出案例实用/d.txt”);
//建立字符流保存数组
char []ch=new char[100];
//将字符流保存到数组中,并返回长度
int len =fis.read(ch);
//关闭流
fis.close();
//将数组转换为字符串
String s =new String(ch, 0, len);
//输出字符流内容
System.out.println(s);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} -
inputStreamReader(字符输入流,是Reeder的子类,是fileReader的父类)
a) fileReader类是inputStreamReader类的子类
i. FileReader( File file )(可以传入文件)
ii. FileReader( String name)(可以传入文件地址)
iii. fileReader无法指定编码格式,读取文件时会按照文件默认的编码格式进行读取 -
fileReader方法
-
获取程序编码格式;
System. out. printIn ( System. getProperty (“ file. encding ”) ) -
中文乱码的原因;文件编码格式与程序的编码格式不一样(推荐编码格式是UTF-8国际通用格式,)
-
解决中文乱码的方法;字符流读取数据的时候进行指定编码格式,或者通过改变文件的编码格式进行解决(必须在可以改变文件的编码格式的情况下才可用,不推荐使用)
-
利用InputStreamReader字符输入流解决中文乱码方法(推荐使用)
a) InputStreamReader在new对象时可以指定编码格式也可以传入字节流(是字节流与字符流的过渡,是一个适配器)
i. 在使用InputStreamReader的时候要new一个字节流,然后将字节流传入到InputStreamReader中,才能进行指定编码格式的读取(字节流为需要转换成字符流的数据)
ii. InputStreamReader也可以将一个字节流的数据转换成字符流
iii. 代码
try {
FileInputStream fss=new FileInputStream(“E:/JAVA文件输入输出案例实用/d.txt”);
//将字节流转换为字符流,并指定编码格式
InputStreamReader fis=new InputStreamReader(fss,“gbk”);
char []ch=new char[100];
int i=fis.read(ch);
System.out.println(new String(ch, 0, i));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
b) 传入的编码格式与文件的编码格式一样才能进行指定的编码格式读取数据 -
为了更加快速的读取字符流的数据,出现了缓冲流(缓冲流也是字符流的一种)
a) BufferedReader类(缓冲流)
b) 缓冲流就是将字符流在包装异常
c) 缓冲区是有大小的
d) 缓冲流的readLind()方法(一次读取多个数据)
i. readLind()需要传入一个reader数据流()
e) readLind()在没有读出来的情况可能是;流没用关闭(后开的流先关) -
缓冲区的代码
a) (一行读取)
//创建文件对象
FileReader fis=new FileReader(“E:/JAVA文件输入输出案例实用/d.txt”);
//创建缓冲区
BufferedReader buf=new BufferedReader(fis);
String sx ="";
//按行读取
while ((sx=buf.readLine())!=null) {
System.out.println(sx);
}
b) (整个读取)
//创建文件对象
FileReader fis=new FileReader(“E:/JAVA文件输入输出案例实用/d.txt”);
//创建缓冲区
BufferedReader buf=new BufferedReader(fis);
String sx ="";
//整个读取
StringBuilder str=new StringBuilder();
while ((sx=buf.readLine())!=null) {
str.append(sx+"\n");
}
fis.close();
buf.close();
System.out.println(str);
输出流(white类)
- white类
- writer类也是抽象类
a) 代码书写
try {
//定义输出流对象
FileWriter fw=new FileWriter(“E:/JAVA文件输入输出案例实用/d.txt”);
//写的文件中的内容
fw.write(“我是盖世英雄!”);
//刷新,关流
fw.flush();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}(要换行加入\r\n就行) - 常用方法
a) writer(String)(在写的时候可以直接写字符串,不必需要写数组)
b) close()(关闭流)
c) flush();清空缓存(在流没有使用完毕的时候使用flush) - FliesWriter
a) 构造方式也和其余的流一样,有两种
b) FliesWriter ( Flie file)(文件)
c) FliesWriter( String name ) (文件地址) - OutputStramWriter(指定输出的编码格式)
a) 代码书写
i. new OutputStreamWriter( OutputStream)(将一个字节输出流进行转换为)
ii. new OutputstreamWriter(OutputStream,String charSetname )(将以一个字节输出流的数据按照指定的编码格式进行输出) - BufferedWriter带缓存区的输出流(使用时与输入流的缓冲区一样使用)
- new line( )创建新的一行(在BufferedWriter中的一个方法)
序列化(serializable) - 将对象进行转换为二进制进行传输到客户端,客户端通过进行反序列化进行编译出对象
- 通过类实现serializable接口进行序列化和反序列化
a) 发送数据为序列化
b) 接受数据为反序列化 - 序列化关键字(是个接口)serializable,必须实现才能进行序列化
- 序列化的流有两个objectOutputStream(输出流,序列化流)ObjectInputStream(输入流,反序列化流)
a) objectOutputStream(序列化)
i. 代码书写
try {
//创建序列化的流对象(对象转成二进制的字节序列码)
ObjectOutputStream sso=new ObjectOutputStream(new FileOutputStream(“E:/JAVA文件输入输出案例实用/g.txt”));
//写入文件(序列化)
sso.writeObject(Stu);
sso.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
ii. 在使用序列化是必须在对象类中实现serializable接口
b) ObjectInputStream(反序列化)
i. 代码书写
//创建反序列化的流对象(二进制的字节序列码转换为对象)
ObjectInputStream sis=new ObjectInputStream(new FileInputStream(“E:/JAVA文件输入输出案例实用/g.txt”));
//读取二进制序列码进行转换为对象
Demo08Student stud=(Demo08Student) sis.readObject();
System.out.println(stud);
其他io流的类
date类
a) dateoutputstream(写入二进制的数据)
b) dateintputstream(读出二进制的数据)
printWriter打印类(写数据时推荐使用)
c) printWriter打印流,单个存在的,有自动换行的功能,在加上true后有自动刷新的功能
d) 代码书写
try {
//true自动刷新
PrintWriter pw=new PrintWriter(new FileWriter(“E:/JAVA文件输入输出案例实用/f.txt”),true);
pw.println(“我是中国人”);
pw.println(“我是中国人”);
pw.println(“我是中国人”);
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
第八章;多线程
多线程
多线程的概念
-
进程(正在运行的程序)
a) 应用程序的执行实例
b) 拥有独立的内存空间和系统资源 -
线程(一个进程中不同的执行路径)
a) 进程中执行元素的最小单位,可完成一个独立的顺序控制流程(独立的执行路径)
b) CPU调度和分派的基本单位 -
多线程
a) 如果在一个进程中同时运行啦多个线程,用来完成不同的工作,则称为“多线程”
b) 多个线程是交替占用cup资源的,并非真正的同时执行(只是运行速度快) -
多线程的好处(单线程就只有一条执行路径(main方法),多线程有多条)
a) 充分的利用了cup的资源
b) 简化编程模型
c) 带来良好的用户体验
多线程的实现 -
thread类是线程的关键类,通过thread类进行线程的相关操作
-
主线程
a) main()方法时主线程的入口
b) 产生其他子线程的线程
c) 必须最好完成执行,因为它执行各种关闭动作 -
获取线程对象 . currentThread( )(通过该方法进行获取,是一个静态的方法)
a) 获取到的对象是Thread类型的,通过接收后调用. getname( )获取线程的名称
b) 在线程类中可以直接调用. currentThread( )方法 -
创建线程(必须重写run方法)
a) 创建线程继承Thread类,且一定要重写run方法(不去重写run方法不会出现编译时报错)
b) 启动线程;通过start方法进行启动(要实现启动多个线程就要new多个线程对象然后通过对象调用start方法)
c) 直接调用run方法存在的问题(相当于单线程)
i. 只有主线程的执行数据
ii. 依次调用了两次run方法
d) 创建新的线程必须重写run方法且在run方法中书写线程要执行的操作
e) 线程每次执行的时长是由cup进行分配的时长进行决定的
f) 线程类在测试类中要实例化对象才能进行启动线程
g) 获取当前线程名;
Thread.currentThread().getName()
h) 代码书写(继承thread类创建线程)
//建立线程对象
MyThread th=new MyThread();
th.start();//开启线程
//主线程的逻辑体
for (int i = 0; i <10; i++) {
System.out.println(Thread.currentThread().getName()+i);
} -
实现Runnable接口创建线程(推荐使用)
a) 通过Runnable接口创建线程也要重写run方法(不去重写会出现编译时报错)
b) 通过Runnable接口创建线程时new线程对象时要传入一个Runnable接口实现类的对象(也可以传入两参数,一起修改线程名)
c) 代码详情
i. 主线程(代码)
MyThread2 t=new MyThread2();//实现接口类型
Thread Th2=new Thread(t);//转换接口类型
Th2.start();
for (int i = 0; i < 10; i++) {
try {
Th2.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+i);
}
d) 子线程代码与继承的代码一样书写(实现接口runnable) -
thread与runnable创建线程的区别
a) thread类
i. 编写简单,可直接操作线程
ii. 适用于单继承
b) runnable接口(推荐使用)
i. 避免单继承的局限性
ii. 便于共享资源 -
创建线程的方法
-
线程状态与调度
a) 线程没有调用start方法时可以进行修改线程的名称
b) 线程的调度
c) sleep方法可以使线程处于休眠状态(也就是堵塞状态)
i. 在使用sleep时会出现异常需要捕捉
ii. 传入的参数为休眠的时间长度(单位为毫秒)
iii. 在主线程中要使线程休眠必须通过thread调用sleep才能进行休眠
d) 线程调度指的是特定机制为多个线程分配cup的使用权
e) 线程休眠代码书写
i. 主线程(代码)
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
ii. 子线程(代码)
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
} -
线程的优先级(用数字1-10表示)
a) 线程的默认优先级是5,最低为1,最高为10
b) 线程的优先级高的线程获取的CPU资源的概率较大
i. . setPriorityThread_MAX_PRIORITY最高级
ii. . setPriorityThread_MIN_PRIORITY最低级
iii. . setPriority( (线程的优先级的数字))(通过线程的优先级数字的大小进行改变线程的优先级)
-
线程的强制执行(join)
a) 暂停当前线程,等待其他线程结束后再继续执行该线程
b) 代码书写
if (i==5) {
try {
//当前线程停止执行,加入的子线程执行完之后当前线程再执行
Th2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
i. }
c) 使用方法
-
线程的死亡有两种
a) 自然死亡(线程运行结束)
b) 强制死亡(强制停止线程,无法手动进行强制进行死亡) -
线程的不安全
a) 当多个线程在同时操作同一个数据时就会出现线程不安全
b) 解决线程不安全的方法
i. 同步方法;在方法上加上synchroized(进行上锁) -
方法上锁后,cup就进行锁定方法,只有当前线程执行完成后其余线程才能进行使用方法
ii. 同步代码块;在代码块上加上synchroized -
代码块上锁后,cup就进行锁定代码块,只有当前线程执行完成后其余线程才能进行使用代码块
-
在使用该方法时要传入一个对象(该对象为无用的对象,没有用,只做参数进行使用),该对象一般为this或者object(this推荐使用)
-
线程的礼让(停止当前的线程,让其他线程先去执行)
a) 线程的礼让是概率性的事件,让当前线程处于就绪状态(不一定执行,也不一定不执行)
b) 礼让的几个方面
i. 当前线程处于阻塞状态
c) 代码书写(关键字yield)
if (i==6) {
Th2.yield();
} -
线程的中断(中断休眠)
a) 代码书写
if (i==6) {
Th2.interrupt();
}第九章;网络编程
网络编程
-
网络概述
a) 网络就是连接在一起的计算机(两台以上的计算机) -
IP地址
a) 计算机在网络中地址的表示(每一台计算机的IP都不同)
b) IP地址有32位二进制表示的,由4个8位二进制数组成 -
IP地址的组成
a) IP=网络地址+主机地址
i. 网路地址;标识计算机或网路设备所在的网段
ii. 主机地址;标识特点主机或网络设备
iii. 一般的IP地址都为ABC三类中一类 -
查看自己的IP;使用ipconfig命令查看IP(在Dem命令管理中使用)
-
测试网络是否通畅;使用ping进行测试ping IP(IP为网络的地址,在Dem命令管理中使用)
DNS域名解析和网络服务器 -
访问网站时通过网址进行访问的原因;方便记忆
a) 通过DNS域名解析器将网址进行编译返回为IP地址(相当于将IP地址进行包装,然后通过) -
网路服务器(通常指在网络环境下,具有较高计算能力,能够提供用户服务功能的计算机)
a) 邮件服务器
i. 邮件服务器一般进行邮件的传输
ii. 邮件服务器是对邮件进行收发管理的一个服务器
b) web服务器(对应的是java程序)
i. 网站的服务器
ii. 专门用来分析用户的请求,然后进行相对应的操作
iii. 常见的web服务器 -
B/S和C/S程序模式
a) B/S是服务器端应用程序(访问网站的,特点是方便进行升级)
b) C/S是客户端应用程序(需要下载的,特点是升级程序后用户是要重新进行下载的)
网络通信协议 -
网络通信协议是为了在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合
-
网络分层
a) 物理层;网络传输的东西
b) 数据链路层;将数据的传输,
c) 网络层;路由选择(选择传输的方式)
d) 传输层;点到点,可见的数据传输
Socket简介及分类 -
Socket(套接字,网路编程的关键字)
a) socket是提供给应用程序的接口
b) socket是通信的关键,相当于接口,双方通过socket才能准确的找到相应的服务器进行通信
(相当于快递点)
c) socket分类
i. 流式套接字;SOCK_STREAM,他是面向连接、可靠的数据传输服务(不会存在文件的丢失,遵守TCP协议)
ii. 报式套接字;SOCK_DGRAM,他是无连接服务,将数据分段的传输(会有数据的丢失,但效率更高遵守UDP协议)
iii. 原始式套接字;SOCK_RAM(不常使用) -
socket通信原理
a) 使用流进行通信
b) 通信原理相当于打电话
c) 在使用socket后需要将其进行关闭
d) 要使用端口才能进行通信 -
端口;计算机上用一些整形的数字来表示端口(1024以下的都是系统的端口,一般使用1024以上的端口进行调用)
基于TCP协议的Socket编程(流式套接字) -
网络编程使用java.net包
a) Socket客户端
i. 在客户端中建立socket时传入的端口名必须与服务器端的端口名一样,在传入id的时候要是服务器的id(本机用localhost(或者127.0.0.1)进行获取,他是一个字符串),否则无法进行通信
ii. 在客户端发送请求是用输出流 -
当请求是一个字符串就传字符串
-
当请求是对象时,方法如下
a) 确保对象可以序列化
b) 然后将对象进行序列化
iii. 要给服务器发送数据要将发送请求的输出流关闭,通过调用shutdownOutput()方法进行关闭(也称为socket半关闭)
iv. 通过输入流接受服务器的响应
b) ServerSocket服务器端
i. 在服务器端需要一个侦听客户端请求的一个方法,通过accept方法可以进行侦听请求(有返回值,返回值是socket类型) -
如果传入的是一个对象的话,必须将对象进行反序列化之后才能进行准确的接受用户的请求
ii. accept方法在没有接受到用户端的数据请求是处于堵塞状态的,一旦数据请求发送过来就会到就绪状态
iii. 在服务器端响应客户端使用输出流 -
多线程网络编写
a) 通过线程类进行创建线程
i. 线程类中必须声明一个变量为socket类型的
ii. 用socket类型的变量值进行相对应客服端的线程开启
iii. 在线程类中只书写socket处理的代码(也就是逻辑处理输入输出等语句)
b) 建立服务端
i. 在服务端中书写服务端的监听方法(监听方法必须写在循环中,才能确保能重复监听客户端的请求)
ii. 在服务端中必须建立线程对象,否则无法进行线程的对应输出输入
c) 建立客户端
i. 客户端与单线程的客户端书写相同
ii. 客户端中也需要实现线程的类并将socket对象传入到线程类中 -
单线程的CTP协议代码编写
a) 服务器端
try {
//建立端口
ServerSocket serverSocket=new ServerSocket(5000);
//等待响应
Socket socket= serverSocket.accept();
//建立端口套接字的输入流
InputStream ins=socket.getInputStream();
//建立端口套接字输入流的缓冲区
BufferedReader is=new BufferedReader(new InputStreamReader(ins));
//定义空字符串
String info;
//循环输出
while((info=is.readLine())!=null){
System.out.println(info);
}
//定义新的字符串,给客户端回应
String hello=“服务器响应回;hello Dell!”;
//建立端口套接字的输出流
OutputStream si=socket.getOutputStream();
//将字符串进行字节化,并进行输出
si.write(hello.getBytes());
//关闭流和套接字
si.close();
is.close();
ins.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
b) 客户端
try {
//建立对应IP地址和端口的套接字
Socket socket=new Socket(“localhost”, 5000);
//定义字符串
String info=“客户端说:holle word!”;
//建立套接字的输出流
OutputStream out=socket.getOutputStream();
//将字符串进行转换为字节流并进行输出
out.write(info.getBytes());
//关闭套接字的输出流
socket.shutdownOutput();
//建立套接字的输入流,用于读取服务器端的回复
InputStream showInFo= socket.getInputStream();
//建立套接字的缓冲区
BufferedReader sho=new BufferedReader(new InputStreamReader(showInFo));
//定义新的字符串
String in;
//利用while循环进行输出服务器端的回复
while ((in=sho.readLine())!=null) {
System.out.println(in);
}
//关闭流和套接字
showInFo.close();
sho.close();
out.close();
socket.close();} catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
-
CTP协议多线程的代码书写
a) 线程类
//定义套接字的变量
private Socket socket;
public SocketDemo02(Socket socket) {
super();
this.socket = socket;
}
public void run() {
//书写服务器的逻辑处理编码 与多线程的run方法同样进行数据的输出输入
try {
InputStream inp = socket.getInputStream();//接受数据
//定义空数组
byte[]b=new byte[1000];
int leb=inp.read(b);
System.out.println(new String(b, 0, leb));
inp.close();
} catch (IOException e) {
e.printStackTrace();
}
b) 客户端
try {
//建立套接字对象 参数是;IP地址、端口
Socket socket=new Socket(“localhost”,6666);
//建立输出流,将数据输出到服务器端
OutputStream out=socket.getOutputStream();
//输出的内容是字节流,通过getbyte进行转换
out.write(“你好”.getBytes());//输出数据内容
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
c) 服务器端
try {
//建立端口
ServerSocket sever=new ServerSocket(6666);
//通过while循环使accept能够重复使用
while(true){
Socket acc = sever.accept();
//响应成功输出提示
System.out.println(acc.getInetAddress()+“链接成功!”);
//建立线程对象
SocketDemo02 soc=new SocketDemo02(acc);
//将线程进行转换,并启动线程
Thread t=new Thread(soc);
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
UDP协议网络编程(报式编程) -
udp 是将数据进行打包,然后通过数据包的形式进行发送到对方
-
udp协议的没有服务器端与客户端的说法,都是客户端之间的数据交互
-
udp的数据发送与接收
a) udp协议通过send方法进行数据的发送(有参数,参数是一个有内容数据的包)
b) udp通过received进行数据的接受(有参数,参数是一个接受内容的空包) -
udp协议的运行是先运行接受端,在运行发送端
-
udp协议代码的书写
a) 发送端
try {
//发消息的一端
DatagramSocket socket=new DatagramSocket();
//发送数据的内容
String s=“你好”;
//将数据类型进行转换
byte[]b=s.getBytes();
//将数据保存到数据包中,参数是;数组、数组长度、IP地址、端口
DatagramPacket packet=new DatagramPacket(b, b.length, InetAddress.getLocalHost(), 8888);
//发送数据
socket.send(packet);
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
b) 接受端
try {
//接受消息的一端
DatagramSocket socket=new DatagramSocket(8888);
//定义空包
byte b[]=new byte[100];
DatagramPacket packet=new DatagramPacket(b, b.length);
//接受到的数据保存进空包里
socket.receive(packet);
//将接受到的数据转换为字符串
String s=new String(packet.getData(),0,packet.getLength());
//输出数据内容
System.out.println(s);
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}第十章;XML
XML
-
XML(extensible markup language),可扩展标记语言
a) 标记;用< >包裹的称为标记(也叫元素)
b) 特点
i. XML与操作系统,编程语言的开发平台无关
ii. 实现不同系统之间的数据交换(数据交换的格式)
iii. 可以跨平台,跨语言
c) 作用
i. 数据交互
ii. 配置应用程序和网站
iii. Ajax基石
iv. 统一信息的结构,实现不同的系统之间的通信 -
XML文档结构
a) 与HTML的书写类似
c) XML的声明(写在第一行)
i. <?xml version=”1.0” encoding=”UTF-8”?> -
version 文档符合的规范
-
encoding 文档的编码格式(不写也是UTF-8)
d) 文档元素描述信息(文档结构)
i. 每一个XML文档是以树形结构进行存储的
ii. 每一个XML只有一个根元素(相当于HTML中的HTML标签) -
建立XML文档
a) 元素的书写(HTML中的标签书写一样),元素也能增加属性(与HTML中的id、class一样的书写)
b) 属性值不能包含(< ” &)(不推荐包含(‘ >))
c) 标签中可以随意定义标签(标签中可以在写标签)
d) XML的注释;
e) 书写代码<?xml version="1.0" encoding="UTF-8"?>
-
XML的属性注意事项
XML的标签命名一般与数据库中的标签名一样(方便进行映射) -
转义符(关键字的转换)
a) 当出现多个特殊字符的时候通过cdata书就进行输出则不会将特殊字符当成标签使用 -
命名空间
a) 指定标签的特殊含义
b) 命名空间作用是解决在复杂,大型XML文件中出现名称相同,但含义不同的元素
c) xmlns是命名空间的关键字(例:xmlns:Nikon=“http//www.nikon.com”) -
XML解析
a) 非验证解析器
i. 检查文档格式是否良好
b) 验证解析器
c) 使用DTD检查文档的有效性 -
解析方法(XML文件必须为与工程的目录下)
a) DOM解析(文档对象模型)
i. 基于XML文档树解析结构
b) 解析方法
i. 创建解析器工厂对象(关键字documentBuilderFactory . newInstance( ))
//解析器工厂对象
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
ii. 解析器工厂对象创建解析器对象( .newDocumentBuillder)
//解析对象
DocumentBuilder builder=factory.newDocumentBuilder();
iii. 解析器对象指定XML文件进行解析获得文档对象document . parse( )(要传入文件路径)
//解析文件获取文档对象
Document document=builder.parse(“XMLDemo02.xml”);
iv. 文档对象解析(未完成…)
c) 判断节点关键字(. getNodeType( )==Element. ELEMENT_NODE)(只解析节点)
i. 代码书写
for (int j = 0; j < node.getLength(); j++) {
//获取子元素
Node item2 = node.item(j);
//判断节点,让程序只解析节点
if (item2.getNodeType()==Element.ELEMENT_NODE) {
//数据类型转换
Element ele=(Element) item2;
//获取文本内容并进行输出
System.out.println(ele.getTextContent());
}
}
d) 代码书写
i. 内容保存的是元素,在同一个标签中(包要导w3c的)
//解析器工厂对象
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
try {
//解析对象
DocumentBuilder builder=factory.newDocumentBuilder();
//解析文件获取文档对象
Document document=builder.parse(“XMLDemo01.xml”);
//获得name元素集合
NodeList nodelist=document.getElementsByTagName(“name”);
//遍历每一个name集合
for (int i = 0; i <nodelist.getLength(); i++) {
//获取单个的name元素
Node phone= nodelist.item(i);
//转换为element类型
Element ele=(Element) phone;
//解析属性
String type=ele.getAttribute(“name”);
String pricet=ele.getAttribute(“money”);
String color=ele.getAttribute(“color”);
System.out.println(“品牌:”+type+“价格:”+pricet+“颜色:”+color);
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
ii. 内容保存的是多个元素保存在多个标签中(包要导w3c的)
//解析器工厂对象
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
try {
//解析对象
DocumentBuilder builder=factory.newDocumentBuilder();
//解析文件获取文档对象
Document document=builder.parse(“XMLDemo02.xml”);
//获得student元素集合
NodeList nodelist=document.getElementsByTagName(“student”);
//遍历每一个student集合
for (int i = 0; i < nodelist.getLength(); i++) {
//进行数据类型进行转换
Element item = (Element) nodelist.item(i);
//输出name的属性值
System.out.println(item.getAttribute(“name”));
//获得子元素的集合
NodeList node=item.getChildNodes();
//遍历输出每一个值元素
for (int j = 0; j < node.getLength(); j++) {
//获取子元素
Node item2 = node.item(j);
//判断节点,让程序只解析节点
if (item2.getNodeType()==Element.ELEMENT_NODE) {
//数据类型转换
Element ele=(Element) item2;
//获取文本内容并进行输出
System.out.println(ele.getTextContent());
}
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} -
为XML添加元素
a) 要创立转换器工厂,通过转换器工厂建立转换器对象,对象创建XML文件,通过文件进行建立属性
i. 创建子元素
ii. 为子元素创建子子元素并添加
iii. 为根元素添加子元素
b) 转换完成后要进行保存到文件(要获取数据源和输出流)
XML方法使用二(XML4J) -
使用DOM4J进行解析(DOM4J提供的是一些接口和类)
a) document;定义XML文档
b) element;定义XML元素
c) text;定义XML文本节点
d) attribute;定义XML的属性 -
导入jar包
a) 在工程中新建一个空的文件夹
b) 在文件夹中访日jar包(文件夹命名为lib(资源的缩写))
c) 在工程中加入相应的文件包 -
DOM4J的使用
a) 关键字document(是导入jar包中的,非w3c中的)
b) 获取对象
i. 解析器的对象通过SAXReader进行new获取对象
ii. 转换工厂的对象通过OutputFormat . createPrettyPrint( )进行获取一个对象(默认格式,不需要添加格式)
iii. 转换工厂通过XMLWrite write=newXMLWrite(参数)进行获取
iv. 代码 -
解析器获取代码
//建立解析器工厂
SAXReader reaorder=new SAXReader();
try {
//读取XML的信息
document=reaorder.read(new File(“XML4JDemo01.xml”));
} catch (DocumentException e) {
e.printStackTrace();
} -
转换工厂代码
//获取转换工厂对象
OutputFormat format=OutputFormat.createPrettyPrint();//以一个格式输出
//指定代码格式 format.setEncoding(“gbk”);
try {
//创建输出流,指定以format格式输出
XMLWriter writer=new XMLWriter(new OutputStreamWriter(new FileOutputStream(src)),format);
//输出document
writer.write(document);
//关闭流
writer.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
c) 获取节点
i. 获取根节点通过 . getRooElement ( )的方法进行获取
ii. 获取子节点通过 . emelentIterator( )的方法进行获取所有的字节点(根节点的下一级节点,可以通过反复循环调用获取子子节点)
iii. 获取节点代码 -
获取根节点
//获取根节点
Element element=document.getRootElement(); -
获取子节点(子子节点)
//获取所有的子节点
Iterator<?> sel= element.elementIterator();
d) 添加节点
i. 添加子节点 . addElement( “ “ )(括号中添加子节点的标签名)
ii. 添加子子节点也是用 . addElment( “ “ )进行添加
iii. 曾加后的内容要通过转换器进行保存到XML文档中
iv. 添加节点代码
//获取XML的根节点
Element root=document.getRootElement();
//创建student
Element add= root.addElement(“student”);
add.addAttribute(“name”, “战神”);
//创建student子节点
Element foot=add.addElement(“score”);
//添加子节点的内容
foot.addAttribute(“score”, “1000”);
//将子节点的数据保存到XML文件中
seavxml(“XML4JDemo02.xml”);
e) 删除节点
i. 删除节点通过 . getParent( ) . remove( “ 要删除对象 ”)(删除后的内容要保存到XML文件中,通过转换器进行保存)
ii. 代码
//获取根节点
Element root=document.getRootElement();
//获取student子节点
Iterator<?> iterator = root.elementIterator();
//遍历子节点
while (iterator.hasNext()) {
//数据类型转换
Element next = (Element) iterator.next();
//判断是否是指定的节点
if(next.attributeValue(“name”).equals(“张三”)){
//获取根节点删除子节点
next.getParent().remove(next);
}
}
f) 修改节点
i. 修改节点通过 . addAttribute( “元素名 ” , “ 元素值”)进行修改(修改过后的XML内容要保存到XML文件中,通过转换工厂进行保存. addAttribute方法为有对应属性的修改,没有为添加,getName为对没有属性的标签进行修改 . setText是修改内容不是修改属性)
ii. 代码
//获取根节点
Element root=document.getRootElement();
//获取所有的student子节点
Iterator<?> iterator = root.elementIterator();
int id=0;
//遍历子节点
while (iterator.hasNext()) {
id++;
//数据类型转换
Element next = (Element) iterator.next();
//添加内容和属性
next.addAttribute(“id”, id+"");
}
//将数据保存到XML文件中
seavxml(“XML4JDemo02.xml”);
g) 输出XML文件内容
i. 通过迭代器进行遍历输出
ii. 代码书写
//获取根节点
Element element=document.getRootElement();
//或取所有的子节点
Iterator<?> sel= element.elementIterator();
//遍历子节点
while (sel.hasNext()) {
Element si=(Element) sel.next();
//输出字节的name属性
System.out.println(si.attributeValue(“name”));
//获取子子节点
Iterator<?> eles=si.elementIterator();
//循环子子节点
while (eles.hasNext()) {
Element sis=(Element) eles.next();
//输出子子节点的yuScore属性
System.out.println(sis.attributeValue(“yuScore”));
}
}
iii. 代码