2017-08-02 110 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;:這樣做的