我找到了将手写数据解析为对象的最佳方法。
假设我有一个名为IEvent
的界面。
假设我有两个类EventNewPlayer
和EventUpdateTime
,它们都实现了接口IEvent
类EventNewPlayer
需要2个整数和一个字符串。让我们说位置X
和Y
以及播放器的名称
班级EventUpdateTime
只需要一个参数:时间。
我想从手写文件中创建尽可能多的事件
该文件如下所示:
NEWPLAYER, 4, 2, joe
NEWPLAYER, 8, 9, bob
UPDATETIME, 1
NEWPLAYER, 8, 9, carl
UPDATETIME, 3
我想从此文件生成事件列表。 此外,我希望将来添加尽可能多的事件。
这样做的最佳/适当/可维护方式是什么?
对于任何英语错误感到抱歉,英语不是我的第一句话。
答案 0 :(得分:2)
一种OOP式的方式:
1)创建一个名为StringEventFactory
的基本接口和一个名为parseFromArray
的非静态函数,将一个字符串数组作为参数并返回IEvent
;还创建一个名为className
的静态函数,它返回每个事件类的文件名。
2)为每个事件创建一个继承自...Factory
的相应StringEventFactory
类,并实现parseFromArray
函数,从字符串数组数据中创建该类型的事件。
3)创建一个哈希表,其中包含:
..Factory
对象 4)对于每一行,将其拆分为一个字符串数组,并使用第一个元素从哈希表中获取StringEventFactory
对象。将数组的其余部分传递给其parseFromArray
函数以创建所需的事件对象
这样就可以很容易地添加新的类规范,而不使用丑陋的switch
语句。
编辑:代码+规范略有变化
interface StringEventFactory {
public static string className();
public IEvent parseFromArray(string[]);
};
class EventNewPlayerFactory implements StringEventFactory
{
public static string className() { return "NEWPLAYER"; }
public IEvent parseFromArray(string[] info)
{
if (info.length != 4) // includes the class name
return null;
// sanity check
if (!info[0].equals(className()) || info[3].isEmpty())
return null;
int x, y;
try {
x = Integer.parseInt(info[1]);
y = Integer.parseInt(info[2]);
}
catch (NumberFormatException ex) {
// notify?
return null;
}
return new EventNewPlayer(x, y, info[3]);
}
};
// similarly for EventUpdateTime ...
// main body
public static void main(string[] args)
{
Hashtable<string, StringEventFactory> factories = new Hashtable<string, StringEventFactory>();
factories.put(EventNewPlayerFactory.className(), new EventNewPlayerFactory());
// similarly for other classes
List<IEvent> eventList = new ArrayList();
// file parsing
FileReader input = new FileReader(fileName);
BufferedReader read = new BufferedReader(input);
String line = null;
while ((line = read.readLine()) != null)
{
String[] array = line.split(",");
for (int i = 0; i < array.length; i++)
array[i] = array[i].trim();
// fetch the factory class
StringEventFactory fact = factories.get(array[0]);
if (fact == null) {
// class name does not exist
continue;
}
StringEvent out = fact.parseFromArray(array);
if (out == null) {
// parameters were incorrect!
continue;
}
// success! add to list
eventList.add(out);
}
}
很抱歉,如果它不能直接使用并且语法错误,我的Java稍微生锈了,但希望是你想要的。
答案 1 :(得分:0)
给定数据数组
String[] data = { "ObjA,0,0,Bob", "ObjB,0" };
Enum定义为
public enum MyEnum {
ObjA, ObjB;
}
我会使用类似的东西:
for ( String line : data ) {
Object obj;
String[] parts = line.split(",");
switch(MyEnum.valueOf(parts[0])) {
case ObjA:
obj = new ObjectOfTypeA(parts);
break;
case ObjB:
obj = new ObjectOfTypeB(parts);
break;
}
然后每个对象都可以处理自己的参数:
public ObjectOfTypeA(String[] params) {
x = params[1];
y = params[2];
name = params[3];
}
和
public ObjectOfTypeB(String[] params) {
ticks = params[1];
}
对于您创建的每个新对象,您将需要将其添加到Enum列表,switch case,然后显然是创建类本身。
答案 2 :(得分:0)
我建议你使用有限状态机。它维护简单灵活。您将来可以添加不同的处理程序。
以下是我的XML解析示例 - https://github.com/kurkov/XMLParser 但是你可以为文本文件解析做类似的事情。
答案 3 :(得分:-1)
你按顺序:
Files.readAllLines(//path)
可能很有用split
over&#34;,&#34;并检查第一个文本是否为NEW ...或UPD ...(检查lentgh以确定)object
(并将其存储在List
中,以便在文件讲座后检索所有这些都将具有以下外观:
public static void main(String args[]) {
List<EventNewPlayer> listPlayer = new ArrayList<>();
List<EventUpdateTime> listTime = new ArrayList<>();
for (String line : Files.readAllLines("myfile.txt")) {
String[] array = line.split(",");
if (array[0].equals("NEWPLAYER") && array.length == 4) {
listPlayer.add(new EventNewPlayer(array[1], array[2], array[3]));
} else if (array[0].equals("UPDATETIME") && array.length == 2) {
listPlayer.add(new EventUpdateTime(array[1]));
}
}
}
如果您的文件中存在错误,则array.length
的checl只是一个安全措施,以避免IndexOutOfBoundsException