读取Txt文件并转换成实体类
这里是text文件的样例
//注意这里每一串的分割是tab键 \u0009
1 2003 Spring Soccer League (Spring '03)
2 2003 Summer Summer Soccer Fest 2003
3 2003 Autumn Autumn Soccer League (2003)
4 2004 Spring Soccer League (Spring '04)
5 2005 Summer The Summer of Soccer Love 2005
6 2006 Autumn Autumn Soccer League (2006)
1. 建立实体类
注意这里只能用基本数据类型和String,不然可能会有一点小问题,自己可以试着改别的类型看看,如果能解决那是最好的。
public class FootballStory {
private int id;
private int year;
private String season;
private String title;
public FootballStory(){};
public FootballStory(int id, int year, String season, String title) {
this.id = id;
this.year = year;
this.season = season;
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getSeason() {
return season;
}
public void setSeason(String season) {
this.season = season;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "FootballStory{" +
"id=" + id +
", year=" + year +
", season='" + season + '\'' +
", title='" + title + '\'' +
'}';
}
}
2. 别写转换器,并且我用了单例模式,加了三重检测,防止一般的反射破化他
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class ReadTxt {
private volatile static ReadTxt readTxt = null;
private static boolean shiyijian = false;
private List list;
private String path;
public List getList() {
return list;
}
public String getPath() {
return path;
}
private ReadTxt(){
synchronized (ReadTxt.class){
if (shiyijian == false){
shiyijian=true;
}else{
throw new RuntimeException("不要试图使用反射破坏单例");
}
}
}
//双重检测模式的懒汉式单例,dcl懒汉式
public static ReadTxt getInstance(){
if (readTxt==null){
synchronized (ReadTxt.class){
if (readTxt==null){
readTxt = new ReadTxt();//不是一个原子性操作
/**
* 1.分配内存空间
* 2.执行构造方法,初始化对象
* 3.把这个对象指向这个空间
* 为什么这样写还不安全,是因为有jmm重排序,我们写的程序不一定按照我们写的顺序执行,机器会以更高效的顺序执行(说白了就是机器比较笨,不会遇见不可预知的错误)
* 所以要增加volatile这个东西,(保证所有线程可见,并且原子性)
*/
}
}
}
return readTxt;
}
public List<Object> readTextfile(String path,Class clas) throws Exception {
//相对路径和绝对路径都可以
File file = new File(path);
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String s = new String();
list = new ArrayList();
while ((s = bufferedReader.readLine())!=null){
//以分隔符分割,这里的分隔符不是空格,是tab键,所以要查一下ascii码的
String[] string = s.split("\u0009");
//转换类型
Pattern compile = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
Object[] objects= new Object[string.length];
int len = 0;
for (String s1 : string) {
if (compile.matcher(s1).matches())
objects[len++] = Integer.parseInt(s1);
else
objects[len++] = s1;
}
//获取类中的所有字段
Field[] declaredFields = clas.getDeclaredFields();
//获取字段类型
Class[] classes = new Class[declaredFields.length];
for (int i = 0; i < declaredFields.length; i++) {
classes[i] = declaredFields[i].getType();
}
//装载
Constructor declaredConstructor = clas.getDeclaredConstructor(classes);
Object o = declaredConstructor.newInstance(objects);
list.add(o);
}
return list;
}
}
3. 编写测试类
import java.util.List;
public class Test {
public static void main(String[] args) throws Exception {
ReadTxt readTxt = ReadTxt.getInstance();
//相对路径和绝对路径都可以
List list = readTxt.readTextfile("leagues.txt", FootballStory.class);
for (Object o : list) {
FootballStory footballStory = new FootballStory();
footballStory=(FootballStory) o;
System.out.println(footballStory.toString());
}
}
}
效果如下
FootballStory{id=1, year=2003, season=‘Spring’, title='Soccer League (Spring ‘03)’}
FootballStory{id=2, year=2003, season=‘Summer’, title=‘Summer Soccer Fest 2003’}
FootballStory{id=3, year=2003, season=‘Autumn’, title=‘Autumn Soccer League (2003)’}
FootballStory{id=4, year=2004, season=‘Spring’, title='Soccer League (Spring ‘04)’}
FootballStory{id=5, year=2005, season=‘Summer’, title=‘The Summer of Soccer Love 2005’}
FootballStory{id=6, year=2006, season=‘Autumn’, title=‘Autumn Soccer League (2006)’}
总结
这算是一个小练习,用到了单例模式,反射和文件读取。