将带有分隔符的字符串映射为字符串列表或新对象

3

我有一个文件,其中一些数据是由分号分隔的。我正在尝试构建一个流,以逐行读取文件,将每个数据列分离并映射到新的对象。

data.txt:

John;Smith;42;shopassistant
Clara;Lefleur;24;programmer

Person.class:

public class Person{
   String name;
   String lastName;
   int age;
   String job;
}

我开始的时候是这样的:
List<Person> people = Files.lines(Paths.get("src/data.txt"))....

有什么想法吗?

2个回答

5
您可以像这样使用地图:
List<Person> people = Files.lines(Paths.get("src/data.txt"))
        .map(p -> p.split(";"))//split each line with ';'
        .map(p -> new Person(p[0], p[1], Integer.valueOf(p[2]), p[3]))//create a new Person
        .collect(Collectors.toList());//then collect the result

请确保您拥有一个包含该信息的构造函数:

public Person(String name, String lastName, int age, String job) {

1
很棒的解决方案。我不知道在.map方法之后流会如何表现,也没有发现我可以使用两次。谢谢。 - steve1337
@YCF_L [FYI,使用Java 9和Scanner可以更好地完成此操作](https://dev59.com/Ia3la4cB1Zd3GeqPT-fT#52017044) - Eugene
@YCF_L 顺便提一下,你在这里使用单字符正则表达式走了运气,否则那个'Pattern'应该被放在流外面... - Eugene
@Eugene 我测试了我的代码和你的代码,发现我的代码更快,你可以在自己的环境中检查一下。 - Youcef LAIDANI
@YCF_L 我测试了我们两个人的代码,发现我的代码更快。抱歉,但这就像是在说什么都没有说一样。适当的测试和解释比我和你想象的要困难得多。 - Eugene
显示剩余2条评论

2

对于这个任务,使用Scanner会更有用。自从Java-9以来,这种方法的使用变得更加简单:

Pattern p = Pattern.compile("^(\\w+);(\\w+);(\\w+);(\\w+)$", Pattern.MULTILINE);
List<Person> persons = new Scanner(Paths.get("src/data.txt"))
            .findAll(p)
            .map(mr -> new Person(mr.group(1), mr.group(2), Integer.valueOf(mr.group(3)), mr.group(4)))
            .collect(Collectors.toList());

它是否更符合标准? - steve1337
@steve1337 你是什么意思? - Eugene
在代码审查期间,您希望看到哪种解决方案? - steve1337
1
@steve1337 显然,这个问题需要使用Scanner工具来解决。 - Eugene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接