2017-07-12 32 views
2

我有一個數組定義如下:地圖陣列反對

String [] source = {"26", "Tom", "foo", ...}; 

並有Person類:

public class Person{ 
    private String age; 
    private String name; 
    private String print; 
    private String ......;//the same type and order and number of source 
    public Person() { 

    } 
    //full construtors 
    public Person(String age, String name, String print,String ....) { 
     this.age = age; 
     this.name = name; 
     this.print = print; 
     //.... 
    } 

    /* setters & getters */ 

} 

我怎樣才能將這些值映射到Person實例?

這是我真正的編碼

public static List<BasicalVo> readObject(String path) throws IOException, NoSuchMethodException { 
     InputStreamReader fReader = new InputStreamReader(new FileInputStream(path),"gb2312"); 
     BufferedReader bufferedReader = new BufferedReader(fReader); 
     String currentLine; 
     String[] temp; 
     List<BasicalVo> basicalVoList= new ArrayList<BasicalVo>(); 
     while ((currentLine = bufferedReader.readLine()) != null) { 
      temp = currentLine.split(",");//I get the Array 
      for (int i = 0; i < temp.length; i++) { 
       //I don't know hot to translate to BasicalVo . 
       BasicalVo vo = new BasicalVo(); 
       basicalVoList.add(vo); 
      } 
     } 
     return basicalVoList; 
    } 
+1

如果順序是決定的(例如'age'是第一個),那麼只需傳入'Str ing []'然後遍歷其元素 –

+0

你知道編譯時的參數個數嗎?或者他們可能有所不同 – gmanjon

+0

數組的參數與對象的字段的順序和類型相同 – kevin

回答

3

如果陣列中只包含一個Person你只需要創建這樣的實例:

String[] source = new String[]{"26", "tom", "xx", "....."}; 
Person p = new Person(source[0], source[1], source[2], source[3],...); 

因爲你知道有在構造函數中的參數個數和所以你將不會有一個ArrayIndexOutOfBoundsException如果陣列構建得很好


二,

假設你只有3個屬性,你就能夠做到這樣,如果數組是這樣的:

String[] source = new String[]{"26", "tom", "xx", "22", "john", "yy"}; 
ArrayList<Person> list = new ArrayList<>() 
for (int i = 0; i < source.length; i += 3) { 
    list.add(new Person(source[i], source[i + 1], source[i + 2])); 
} 

III。

如果你有多個字段,你最好這樣做:

public Person(String[]source) { 
     this.age = source[0]; 
     this.name = source[1]; 
     this.print = source[2]; 
     //.... 
} 

因爲它不會不加收你在你的循環從數據讀取有代碼,使其更容易做你的東西,其實這並不難,因爲如果你有一個像20場每一種情況下,你必須assignate這20個attributs


IV。

或最後一個命題有一個工廠方法:

public static Person createPersoneFromArray(String[] array) { 
    Person p = new Person(); 
    p.setAge(array[0]); 
    p.setName(array[1]); 
    //... 
    return p; 
} 

,並在主方法:

Person p = Person.createPersoneFromArray(source); 
+0

但是,如果source.length是20或更多,我不能這樣做 – kevin

+0

如果你在類中有20個字段,那麼就沒有辦法循環在他們之上,你可以遍歷數組,但不能覆蓋屬性或使用Map,我將添加一個示例 – azro

+0

我建議使用靜態工廠方法而不是構造函數,因爲內部邏輯的構造函數通常會被忽略。 –

3

如果source只包含一個人的數據,那麼你可以這樣做:

Person p = new Person(source[0], source[1], source[2] ...); 

如果數組太短了ArrayIndexOutOfBoundsException會被拋出。

1

在我認爲你最好的選擇是使用反射這種特定的情況下。反射是一組類和接口,允許您在執行時調用不同的方法。例如:

String [] source = { "26", "tom", "xx", ... }; 
Constructor constructor = Person.class.getConstructors()[0] 
constructor.newInstance(source) 

要考慮到這個例子只能因爲你只有一個構造函數,所以Person.class.getConstructors()[0]返回你想要的構造函數。 YOu可以嘗試使用Person.class.getConstructors(Class<?>...)獲得特定的構造函數,在這種情況下,您需要將參數類型作爲參數傳遞給數組。

+0

反射增加了相當有些開銷,爲了方便起見刪除了任何種類的安全類型,雖然它有其用途,但我認爲在這種情況下它不是必需的。 –

+0

完全同意(開銷和類型安全),但是是唯一的選項,你不知道編譯時參數的數量,這是我在第一個問題中失敗的地方(現在被修改) – gmanjon

+0

由於沒有類可以創建在編譯時一個*總是*知道構造函數有多少個參數。 –

2

你也可以添加另一個構造你的BasicalVo類以一個String []輸入:

public BasicalVo(String [] input) { 
    this.age = input[0]; 
    this.name = input[1]; 
    this.print = input[2]; 
    //.... 
} 

,你那麼可以在主稱因爲沒有額外的for循環如下

.... 
temp = currentLine.split(","); 
BasicalVo vo = new BasicalVo(temp); 
basicalVoList.add(vo); 
.... 
1

你可以使用OpenCSV

CSVReader csvReader = new CSVReader(new FileReader("people.csv"),','); 
ColumnPositionMappingStrategy mappingStrategy = new ColumnPositionMappingStrategy(); 
mappingStrategy.setType(Person.class); 
String[] columns = new String[]{"age","name","print"}; 
mappingStrategy.setColumnMapping(columns); 
CsvToBean ctb = new CsvToBean(); 
List personList = ctb.parse(mappingStrategy, csvReader);