—-classOne
package firstExam.second;
import java.io.Serializable;
public class Flower implements Serializable {
private int id;
private String name;
private int age;
public Flower(){
}
public Flower(int id,String name,int age){
this.id=id;
this.name=name;
this.age=age;
}
public int getId(){
return id;
}
public void setId(int id){
this.id=id;
}
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return this.age;
}
public void setAge(int age){
this.age=age;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Flower){
Flower flower=(Flower)obj;
return this.name.equals(flower.name);
}else
return false;
}
@Override
public String toString() {
return "Flower(id="+id+",name="+name+",age="+age+")";
}
}
—-classTwo
package firstExam.second;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class FlowerService {
/*
* List是一个接口,而ListArray是一个类。
* ListArray继承并实现了List。
* 所以List不能被构造,但可以为List创建一个引用,而ListArray就可以被构造。
* List list;—-正确 list=null;
* List list=new List();—-是错误的用法
* List list = new ArrayList();这句创建了一个ArrayList的对象后上溯到了List,
* 此时它是一个List对象了,有些ArrayList有但是List没有的属性和方法,它就不能再用了(多态)。
* 而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性。
*/
private Listlist=new ArrayList();
public void saveFlower(List<Flower> flowerList){
ObjectOutputStream oos=null;
try {
oos=new ObjectOutputStream(new FileOutputStream("flower.txt"));
for(Flower f:flowerList){
//从文件中读或者写对象时,均调用对象的toString()方法进行读写操作
oos.writeObject(f);
}
/*对于字符流 一般写入的时候想要马上看到一般需要flush()
*面试题:close()和flush()的区别?
*A:close()关闭流对象,但是先刷新一次缓冲区,关闭之后,流对象不可以继续再使用了。
*B:flush()仅仅是刷新缓冲区(一般写字符时要用,因为字符是先进入的缓冲区),流对象还可以继续使用
*close会自动flush,什么时候都不用调用。
*/
oos.flush();
oos.close();
//继承在IOException,属于必检异常
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
public void show(List<Flower> list){
/*
* For-Each循环的缺点:丢掉了索引信息。
* 当遍历集合或数组时,如果需要访问集合或数组的下标,
* 那么最好使用旧式的方式来实现循环或遍历,而不要使用增强的for循环,因为它丢失了下标信息。
*/
for(Flower f:list){
System.out.println(f);
}
}
public void distinct(){
//此处id值均不唯一,名字相同的剔除,故不可以用hashSet剔除
List<Flower> newList=new ArrayList<Flower>();
//如果i=this.list.size()-1;不减去1则会发生数组越界的错误
for(int i=this.list.size()-1;i>=0;i--){
for(int j=0;j<i;j++){
/*
* list.contains(obj),系统会对list中的每个元素obj调用obj.equals()方法,
* 假如list中有n个元素,那么会调用n次obj.equals()方法,只要有一次
* obj.equals()返回true,那么 list.contains(obj)就返回true,否则返回false.
*/
if(newList.contains(list.get(i))){
break;
}
newList.add(this.list.get(i));
}
}
System.out.println("---去掉重复花名后的集合---");
show(newList);
sort(newList);
}
public void sort(List<Flower> newList){
Collections.sort(newList,new FlowerComparator());
System.out.println("---按照年龄大小排序后的集合---");
show(newList);
}
public void getFlower(List<Flower> flowers){
ObjectInputStream ois=null;
try{
ois=new ObjectInputStream(new FileInputStream("flower.txt"));
//List的对象中没有length,其size()方法类似于length,表示对象中元素的个数
for(int i=0;i<flowers.size();i++){
Flower flower=(Flower)ois.readObject();
this.list.add(flower);
}
System.out.println("---所有对象的集合---");
show(this.list);
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.getStackTrace();
/*ClassNotFoundException的父类是ReflectiveOperationException,
* 后者的父类是Exception
*/
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
—-classThree
package firstExam.second;
import java.util.Comparator;
public class FlowerComparator implements Comparator {
@Override
//按照花龄进行升序排序
public int compare(Flower o1, Flower o2) {
return o1.getAge()-o2.getAge();
}
}
—-classFour
package firstExam.second;
import java.util.ArrayList;
import java.util.List;
/**
* 先往文件保存10个花类(包括花编号,花名称,花龄)对象,再取出来
* 去掉花名重复的花对象,再按照花龄升序排列
*/
/**
* 使用对象流写入或读入对象时,要保证对象是序列化的。这是为了保证能把对象写入到文件,并把对象读回到程序中的缘故。
* 一个类如果实现了Serializable接口,那么这个类创建的对象就是就是所谓序列化的对象,所谓的“对象序列化”:简单
* 一句话就是使用它可以像存储文本或数字一样简单的存储对象。
*/
/**
* 对象序列化的一个应用是:
* 程序在执行过程中突然遇到断电或者其他故障导致程序非正常终止,那么对象当前的工作状态也就会丢失,
* 这对于有些应用来说是可怕的。用对象序列化就可以解决这个问题,因为它可以将对象的全部内容保存于磁盘文件,这样对象
* 的执行状态也就被存储了,到需要时还可以将其从文件中再读取出来,这样就解决了数据丢失的问题。
*/
/**
* 对象序列化的简单实现:
* 为需要被序列化的对象实现Serializable接口,该接口没有需要被实现的抽象方法,implements Serializable
* 只是为了标注该对象是可被序列化的,然后使用一个输出流(OutputStream及其所有子类)来构造一个
* ObjectOutputStream对象,接着使用ObjectOutputStream对象的writeObject(obj)方法就可以将
* 参数为可被序列化的对象obj写出到文件上。
*/
public class Test {
public static void main(String[] args) {
List<Flower> flowers=new ArrayList<Flower>();
String[]name={"rose1","rose2","rose1","rose2","grass1",
"grass2","flower1","flower2","flower1","flower2"};
int[] age={1,3,6,2,6,3,2,4,2,4};
for(int i=0;i<name.length;i++){
Flower flower=new Flower();
flower.setId(i+1);
flower.setName(name[i]);
flower.setAge(age[i]);
flowers.add(flower);
}
FlowerService flowerService=new FlowerService();
flowerService.saveFlower(flowers);
flowerService.getFlower(flowers);
flowerService.distinct();
}
}