2017-08-02 105 views
1

我找到了解析手写数据到对象的最佳方法。Java正确解析

可以说我有一个叫做IEvent的接口。

比方说,我有两个类EventNewPlayerEventUpdateTime这既实现了接口IEvent

EventNewPlayer需要2个整数和一个字符串。可以说位置XY和玩家的名字

EventUpdateTime只需要一个参数:时间。

我想提出的创造尽可能多的事件,我想,从手写文件

的文件应该是这样的:

NEWPLAYER, 4, 2, joe 
NEWPLAYER, 8, 9, bob 
UPDATETIME, 1 
NEWPLAYER, 8, 9, carl 
UPDATETIME, 3 

我想生成的事件列表从这个文件。 另外我想在未来添加尽可能多的事件,我想要的。

什么是最好的/适当的/可维护的方式来做到这一点?

对不起有任何英文错误,英文不是我的第一个语言。

+1

SO不是解决资源的作业。来这里与你的代码尝试有一些特殊的问题 –

+0

@IvanPronin我没有要求代码。我不需要编写代码来知道它不是这样做的好方法(拆分“,”,条件将会非常简单但很脏) – mouuff

回答

2

的OOP式的方式还会创建一个名为className的静态函数,该函数返回每个事件类的文件内名称。

2)对于每个事件,创建相应的...Factory类,它继承自StringEventFactory,并实现parseFromArray函数以从字符串数组中创建该类型的事件。

3)创建哈希表,其:

  • 密钥存储在文本文件中的类名,例如“NEWPLAYER”等
  • 值是对应的类..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

您依次是:

  • 一行读了你的文件行:Files.readAllLines(//path)可以是有用
  • split过“”并检查第一文本新建...或... 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])); 
      } 
     } 
    } 

的checl array.length只是一个安全性,如果在您的文件中有一个错误,以避免IndexOutOfBoundsException

+0

如果downvoter^s可以说出来而不仅仅是voteedown ^^ – azro

0

给定的数据数组

String[] data = { "ObjA,0,0,Bob", "ObjB,0" }; 

而且一个枚举定义为

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]; 
} 

对于您创建的每个新对象,您都需要将它添加到枚举列表,切换案例中,然后显然是创建类本身。

0

我可以建议你使用有限状态机。维护简单灵活。将来可以添加不同的处理程序。

这是我的XML解析示例 - https://github.com/kurkov/XMLParser 但是,您可以为文本文件解析做类似的事情。 )

1创建一个基本接口称为StringEventFactory,和称为parseFromArray非静态函数,取一个字符串数组作为参数并返回一个IEvent;:这样做的