Java convert list of string with comma separated values to list of objects

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Java convert list of string with comma separated values to list of objects



I'd like to convert a json array of person


persons: [
"1, Franck, 1980-01-01T00:00:00",
"2, Marc, 1981-01-01T00:00:00"
]



To a list of Person object using this class:


class Person
private Integer id;
private String name;
private Date dateOfBirth;

// getter and setter



Would it be possible to use a converter and Java 8 to do it?


public Person convert(String from)
String data = from.split(",");
return new Person(Integer.parseInt(data[0]), data[1], new Date(data[2]));





You should have a look at json parsers like jacksonxml for such tasks.
– NielsNet
Aug 11 at 0:17





The json array is not correct. What is that object inside json array - a string or an json object?
– Pankaj Singhal
Aug 11 at 14:09



string


json




2 Answers
2



You can do it like so,


Pattern idNumber = Pattern.compile("\d+");
List<Person> persons = Arrays.stream(from.split("}")).filter(s -> idNumber.matcher(s).find())
.map(s -> s.substring(s.indexOf("") + 1)).map(s -> s.split(","))
.map(a -> new Person(Integer.parseInt(a[0].replaceAll(""", "")), a[1],
LocalDateTime.parse(a[2].trim().replaceAll(""", ""))))
.collect(Collectors.toList());



First split each string using "" character, and then filter out invalid tokens, which does not contain a digit. Notice that each valid payload should contain Id number which is a digit. Finally remove any spurious trailing characters occur before the Id digit and map each resulting String to a Person object. At last collect the Person instances into a List.


split


String


Person


collect


Person


List



Notice that I have used LocalDateTime for the dateOfBirth field in the Person class. So the Person class looks like this.


LocalDateTime


dateOfBirth


Person


Person


public class Person
private final Integer id;
private final String name;
private final LocalDateTime dateOfBirth;
// remainder omitted for the sake of brevity.



However as you can see it is always intuitive to use some framework such as Jackson ObjectMapper to get the work done than writing all this. But in this case your Json is malformed so you won't be able to use such a framework unless you fix the json payload structure.


ObjectMapper



Update



Here's much more elegant Java9 solution.


String regexString = Pattern.quote(""") + "(.*?)" + Pattern.quote(""");
Pattern pattern = Pattern.compile(regexString);

List<Person> persons = pattern.matcher(from)
.results()
.map(mr -> mr.group(1)).map(s -> s.split(", "))
.map(a -> new Person(Integer.parseInt(a[0]), a[1], LocalDateTime.parse(a[2])))
.collect(Collectors.toList());



In Java 9, you can now use Matcher#results() to get a Stream<MatchResult>. Here's an excerpt from the documentation.


Matcher#results()


Stream<MatchResult>



Returns a stream of match results for each subsequence of the input
sequence that matches the pattern. The match results occur in the same
order as the matching subsequences in the input sequence.



I would rather recommend you to use Java9 to solve this.



If you need to do it just for a List of String representation of a Person, you may do it like so.


List


String


Person


List<String> personStr = Arrays.asList("1, Franck, 1980-01-01T00:00:00", "2, Marc, 1981-01-01T00:00:00");
List<Person> persons = personStr.stream()
.map(s -> s.replaceAll(" ", "").split(","))
.map(a -> new Person(Integer.parseInt(a[0]), a[1], LocalDateTime.parse(a[2])))
.collect(Collectors.toList());



Notice the latter is far more easier than the prior and contains just a subset of the original solution.





Thanks Ravindra, it makes total sense! However would you have any idea how to do it if you had a List<String> as a parameter to convert to a List<Person> ?
– Andrew
Aug 12 at 0:21





@Andrew Show me your input list, and then I can update the answer.
– Ravindra Ranwala
Aug 12 at 2:09





Given I am using SpringBoot, I was thinking of using a wrapper so I could map the RequestBody to this wrapper automatically and then convert it to a List<Person>: public class PersonsWrapper private List<String> persons; So each String in this list would look like this: "2, Marc, 1981-01-01T00:00:00"
– Andrew
Aug 12 at 2:22






Mate you're awesome! I haven't used java for a while, it's so nice to be able to convert it this way!
– Andrew
Aug 12 at 5:02



An Extention of your solution itself & with a bit of abstraction:


List<String> personStr = Arrays.asList("1, Franck, 1980-01-01T00:00:00", "2, Marc, 1981-01-01T00:00:00");

List<Person> persons = personStr.stream()
.map(Person::new)
.collect(Collectors.toList());



Where, Person class has a constructor which accepts a string arg to convert it to a Person object, as follows:


Person


string


Person


public Person(String from)
String data = from.split(",");
Arrays.parallelSetAll(data, i -> data[i].trim());
this.id = Integer.parseInt(data[0]);
this.name = data[1];
this.dateOfBirth = new Date(data[2]);






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

make 2 or more post in bootsrap

Store custom data using WC_Cart add_to_cart() method in Woocommerce 3

React Native Navigation and navigating to another Screen problem