2

I have an array defined as follows:

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

And a Person class:

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 */

}

How can I map these values to a Personinstance?

this is my real coding

  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;
    }
5
  • 1
    If the order is decided (e.g. age is first) then just pass in the String [] and then loop through its elements Commented Jul 12, 2017 at 7:30
  • Do you know the number of arguments at compilation time? or they could vary Commented Jul 12, 2017 at 7:38
  • the argument of the array is the same order and type with the object's field Commented Jul 12, 2017 at 7:45
  • @kevin In this cases is a good practice no implement the Builder pattern. It would give more readability and flexibility. Take a look at this post jlordiales.me/2012/12/13/the-builder-pattern-in-practice Commented Jul 12, 2017 at 8:06
  • ok, thanks, my code is a simple example project to read from .txt file and translate to object, then save into the database.anyway ,thank you Commented Jul 12, 2017 at 8:22

5 Answers 5

3

If the source just contains one person's data then you can do this:

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

If the array is too short an ArrayIndexOutOfBoundsException will be thrown.

Sign up to request clarification or add additional context in comments.

Comments

2

I.

If the array contains only one Person you only need to create the instance like this :

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

Because you'll know how many parameters there is in the constructor and so you won't have an ArrayIndexOutOfBoundsException if the array is well-build


II.

Assuming you have only 3 attributes, you'll be able to do like this if the array is like this :

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.

If you have multiple fields, you would better do like this :

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

Because it wouldn't not surcharge the code you have in your loop which read from the data, and make it easier to do your stuff, and in fact this is not hard, because in every case if you have like 20 fields, you'll have to assignate these 20 attributs


IV.

Or last proposition with a factory method :

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

And in the main method :

Person p = Person.createPersoneFromArray(source);

5 Comments

but , if the source.length is 20 or more,I could not do like that
if you have 20 fields in the class too so, there is no way to loop over them, you can loop over the array, but not over attributes OR use a Map, i'll add an example
I would suggest using a static factory method instead of a constructor as constructors with logic inside are generally frowned upon.
although it looks stupid, but It works.Thanks anyway
@kevin Thanks kevin ... you ask, we answer and you told us that is stupid, good I've add a factory method as proposed by philip
2

you can also add another constructor to your BasicalVo class which takes a String[] as input :

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

which you then can call in your main as follows without additional for loop

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

Comments

1

You can use 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);

Comments

1

In this specific case I think that your best option is to use reflection. Reflection are a set of classes and interfaces that allow you to call different methods at execution time. For instance:

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

Take into account that this example only works because you have only one constructor, and so Person.class.getConstructors()[0] returns the constructor you want. YOu can try to get the specific constructor with Person.class.getConstructors(Class<?>...), in that case you would need to pass as a parameter an array with the type of the arguments.

6 Comments

Reflection adds quite a bit of overhead and removes any sort of type safety for the sake of convenience and while it has its usages I think it is not necessary in this case.
Totally agree (overhead and type safety), but is the only option of you don't know the number of parameters at compile time, which is what I underestood in the first question (now is modified)
As no classes can be created at compile-time one always knows how many parameters a constructor has.
I already know the number and type of this class which includes 23 parameters.so the array contains 23 value.
@Phillipp You can have many constructors with many parameters. I just wanted to give the solution some flexibilty that could extend its usage, if you don't like it that's ok, not trying to begin a suitability discussion here.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.