Java-通过使用文件中的数据构建不同类型的对象来填充列表



大家好,希望你们身体健康(-:

我正在尝试编写一种方法,从文件中读取并创建不同类型的对象(Academic、Student、Programmer(,然后将其添加到列表(Person(中。我一直在想办法为一种类型的人的每个实例创建不同的对象,并按读取顺序将它们添加到列表中。和中一样,它可能会变成Programmer、Programmer、Student、Programmer,并且应该按顺序将它们添加到列表中。我已经让它为每种类型创建一个对象,但这意味着列表的输出是按类型分组的,而不是按读取顺序分组的。

它读取的数据将以换行符分隔,格式如下:

<type of person>
<name>
<additional data>

当人的类型将决定要创建的人的哪个子类时,name是人的名字,而附加数据是与人的类型相对应的一系列附加信息行。一个学生将有(按顺序(:他们的学位名称,他们在哪一年。一个学者将有他们教的科目。程序员将拥有他们最喜欢的编程语言。

输入文件:

Student
Alice
Computer Science
2
Academic
Bob
Programming
Programmer
Eve
Scala
Student
Jim
Computer Science
1

因此,目前的输出将是

[Hi, I'm Alice. I am studying Computer Science. I am in my 2nd year., Hi, I'm Jim. I am studying Computer Science. I am in my 1st year., Hi, I'm Bob. I teach Programming., Hi, I'm Eve. I like to program in Scala.]

但我希望它是

[Hi, I'm Alice. I am studying Computer Science. I am in my 2nd year., Hi, I'm Bob. I teach Programming., Hi, I'm Eve. I like to program in Scala., Hi, I'm Jim. I am studying Computer Science. I am in my 1st year.]

这是代码-

import java.io.*;
import java.util.*;
public class MiniFB {
public static List<Person> readInData(String filename) {
//this is the method I am talking about
ArrayList<Person> list = new ArrayList<Person>();

try (Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
if (sc.nextLine().equals("Student")) {
String n = sc.nextLine();
String d = sc.nextLine();
int y = sc.nextInt();
Student s = new Student(n, d, y);
list.add(s);
}
}
sc.close();
}
catch (IOException e) {
System.err.println("error");
}
//
try (Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
if (sc.nextLine().equals("Academic")) {
String n = sc.nextLine();
String s = sc.nextLine();
Academic a = new Academic(n, s);
list.add(a);
}
}
sc.close();
}
catch (IOException e) {
System.err.println("error");
}
//
try (Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
if (sc.nextLine().equals("Programmer")) {
String n = sc.nextLine();
String l = sc.nextLine();
Programmer p = new Programmer(n, l);
list.add(p);
}
}
sc.close();
}
catch (IOException e) {
System.err.println("error");
}
//        
return list;
}
public static void main(String[] args) {
List<Person> people = readInData("testFile.txt");
System.out.println(people);
}
}
public abstract class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
@Override
public String toString() {
return "Hi, I'm " + name + ".";
}
@Override
public abstract boolean equals(Object other);
}

public class Student extends Person {
private String degree;
private int year;

public Student(String name, String degree, int year) {
super(name);
this.degree = degree;
this.year = year;
}

private String ordinalEnding(int cardinal) {

if (cardinal % 100 >= 11 && cardinal % 100 <= 13) return "th";

switch (cardinal % 10) {
case 1 : 
return "st";
case 2 : 
return "nd";
case 3 : 
return "rd";
default : 
return "th";
}
}

@Override
public String toString() {
return super.toString() + " I am studying " + this.degree + ". I am in my " + this.year + ordinalEnding(this.year) + " year.";
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Student)) return false;
Student other = (Student)o;
return (this.getName().equals(other.getName()) && this.degree.equals(other.degree) && this.year == other.year);
}
}

public class Academic extends Person {
private String subject;

public Academic(String name, String subject) {
super(name);
this.subject = subject;
}

@Override
public String toString() {
return super.toString() + " I teach " + this.subject + ".";
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Academic)) return false;
Academic other = (Academic)o;
return (this.getName().equals(other.getName()) && this.subject.equals(other.subject));
}
}

public class Programmer extends Person {

private String language;

public Programmer(String name, String language) {
super(name);
this.language = language;
}

@Override
public String toString() {
return super.toString() + " I like to program in " + this.language + ".";
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Programmer)) return false;
Programmer other = (Programmer)o;
return (this.getName().equals(other.getName()) && this.language.equals(other.language));
}
}

好的,所以基本问题是如何解析文件。。。

try (Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
if (sc.nextLine().equals("Student")) {
System.out.println("Student");
String n = sc.nextLine();
String d = sc.nextLine();
int y = sc.nextInt();
Student s = new Student(n, d, y);
list.add(s);
}
}
sc.close();
}
catch (IOException e) {
System.err.println("error");
}
try (Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
if (sc.nextLine().equals("Academic")) {
System.out.println("Academic");
String n = sc.nextLine();
String s = sc.nextLine();
Academic a = new Academic(n, s);
list.add(a);
}
}
sc.close();
}
catch (IOException e) {
System.err.println("error");
}
try (Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
if (sc.nextLine().equals("Programmer")) {
System.out.println("Programmer");
String n = sc.nextLine();
String l = sc.nextLine();
Programmer p = new Programmer(n, l);
list.add(p);
}
}
sc.close();
}
catch (IOException e) {
System.err.println("error");
}        

第一次扫描会同时检测到两名学生,然后第二次扫描会检测到学者和最后一名程序员,如果你想这样对他们进行排序,那就太好了。

像这样打开和关闭文件效率很低,更好的解决方案是阅读每一行,并评估你需要做什么,比如。。。

try ( Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
if (line.equals("Student")) {
String n = sc.nextLine();
String d = sc.nextLine();
int y = sc.nextInt();
Student s = new Student(n, d, y);
list.add(s);
} else if (line.equals("Academic")) {
String n = sc.nextLine();
String s = sc.nextLine();
Academic a = new Academic(n, s);
list.add(a);
} else if (line.equals("Programmer")) {
String n = sc.nextLine();
String l = sc.nextLine();
Programmer p = new Programmer(n, l);
list.add(p);
}
}
} catch (IOException e) {
e.printStackTrace();
}

这将按照文件中出现的顺序加载每个条目,并打印

[Hi, I'm Alice. I am studying Computer Science. I am in my 2nd year., Hi, I'm Jim. I am studying Computer Science. I am in my 1st year., Hi, I'm Bob. I teach Programming., Hi, I'm Eve. I like to program in Scala.]

您可能需要考虑的另一件事是,允许每个类从Scanner本身解析文本,因为每个类都会更好地了解自己的需求,并且有助于解耦一些逻辑,作为一种建议。

因此,我们可以通过构造函数修改Person和子类以接受Scanner,这意味着每个类都要负责自己的解析。。。

public static abstract class Person {
private String name;
public Person(Scanner scanner) {
this.name = scanner.nextLine();
}
public String getName() {
return this.name;
}
@Override
public String toString() {
return "Hi, I'm " + name + ".";
}
@Override
public abstract boolean equals(Object other);
}
public static class Student extends Person {
private String degree;
private int year;
public Student(Scanner scanner) {
super(scanner);
this.degree = scanner.nextLine();
this.year = scanner.nextInt();
}
private String ordinalEnding(int cardinal) {
if (cardinal % 100 >= 11 && cardinal % 100 <= 13) return "th";
switch (cardinal % 10) {
case 1 : 
return "st";
case 2 : 
return "nd";
case 3 : 
return "rd";
default : 
return "th";
}
}
@Override
public String toString() {
return super.toString() + " I am studying " + this.degree + ". I am in my " + this.year + ordinalEnding(this.year) + " year.";
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Student)) return false;
Student other = (Student)o;
return (this.getName().equals(other.getName()) && this.degree.equals(other.degree) && this.year == other.year);
}
}
public static class Academic extends Person {
private String subject;
public Academic(Scanner scanner) {
super(scanner);
this.subject = scanner.nextLine();
}
@Override
public String toString() {
return super.toString() + " I teach " + this.subject + ".";
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Academic)) return false;
Academic other = (Academic)o;
return (this.getName().equals(other.getName()) && this.subject.equals(other.subject));
}
}
public static class Programmer extends Person {
private String language;
public Programmer(Scanner scanner) {
super(scanner);
this.language = scanner.nextLine();
}
@Override
public String toString() {
return super.toString() + " I like to program in " + this.language + ".";
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof Programmer)) return false;
Programmer other = (Programmer)o;
return (this.getName().equals(other.getName()) && this.language.equals(other.language));
}
}

然后读取文件变得像…一样简单

try ( Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
if (line.equals("Student")) {
Student s = new Student(sc);
list.add(s);
} else if (line.equals("Academic")) {
Academic a = new Academic(sc);
list.add(a);
} else if (line.equals("Programmer")) {
Programmer p = new Programmer(sc);
list.add(p);
}
}
} catch (IOException e) {
e.printStackTrace();
}

我们可以谈论很多关于";工厂模式";等等,但这传达了基本思想;(

不,你不需要这样做,这只是解决问题的另一种方法;(

ArrayList<Person> list = new ArrayList<Person>();
try (Scanner sc = new Scanner(new File(filename))) {
while (sc.hasNextLine()) {
String line = sc.nextLine();
if (line.equals("Student")) {
String n = sc.nextLine();
String d = sc.nextLine();
int y = sc.nextInt();
Student s = new Student(n, d, y);
list.add(s);
} else if (line.equals("Academic")) {
String n = sc.nextLine();
String s = sc.nextLine();
Academic a = new Academic(n, s);
list.add(a);
} else if (line.equals(...)) {
..
}
}
sc.close();
}

最新更新