Java 将对象流收集到地图中
我有一个用户详细信息的csv文件,我必须通过读取每一行将其加载到HashMap中。这是使用Java8流的一些帮助来完成的Java 将对象流收集到地图中,java,collections,java-stream,Java,Collections,Java Stream,我有一个用户详细信息的csv文件,我必须通过读取每一行将其加载到HashMap中。这是使用Java8流的一些帮助来完成的 Map<String,MockUser> users = new HashMap<>(); try (Stream<String> stream = Files.lines(Paths.get(f.getAbsolutePath()))) { stream.forEach(s -> {
Map<String,MockUser> users = new HashMap<>();
try (Stream<String> stream = Files.lines(Paths.get(f.getAbsolutePath()))) {
stream.forEach(s -> {
String[] fields = s.split(",");
MockUser user = new MockUser(fields[0], fields[1], fields[2]);
users.put(user.getUsername(), user);
});
} catch (IOException e) {
e.printStackTrace();
}
private class MockUser {
String username;
String password;
String role;
MockUser(String username, String password, String role) {
this.username = username;
this.password = password;
this.role = role;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
Map users=newhashmap();
try(Stream=Files.line(path.get(f.getAbsolutePath())){
stream.forEach(s->{
字符串[]字段=s.split(“,”);
MockUser user=新MockUser(字段[0],字段[1],字段[2]);
user.put(user.getUsername(),user);
});
}捕获(IOE异常){
e、 printStackTrace();
}
私有类MockUser{
字符串用户名;
字符串密码;
字符串角色;
MockUser(字符串用户名、字符串密码、字符串角色){
this.username=用户名;
this.password=密码;
this.role=角色;
}
公共字符串getUsername(){
返回用户名;
}
public void setUsername(字符串用户名){
this.username=用户名;
}
公共字符串getPassword(){
返回密码;
}
public void setPassword(字符串密码){
this.password=密码;
}
公共字符串getRole(){
返回角色;
}
公共void setRole(字符串角色){
this.role=角色;
}
}
这很有效。但是,我必须编写一个3行代码来拆分并将流结果添加到地图中。我试过使用Stream.collect,但我完全不能正确地使用它
是否有一种方法可以使用流来简化上述代码。收集?试试这是一种帮助方法,它可以将流转换为地图,这正是您所做的。您可以做到这一点
Map<String, MockUser> users = Files.lines(Paths.get(f.getAbsolutePath()))
.map(line -> line.split(","))
.map(fields -> new MockUser(fields[0], fields[1], fields[2]))
.collect(Collectors.groupingBy(MockUser::getUserName))
Map users=Files.line(path.get(f.getAbsolutePath()))
.map(直线->直线分割(“,”)
.map(字段->新用户(字段[0]、字段[1]、字段[2]))
.collect(收集器.groupingBy(MockUser::getUserName))
最终认识到,收集器.GroupingBy
不应用于将流转换为地图。因为这会将相似的结果分组到一个列表中,并将其作为映射返回。我想要的是一张地图
在浏览了Javadocs之后,我找到了Collectors.toMap
,这正是我想要的解决方案
下面是我最后编写的代码
users = Files.lines(Paths.get(file.getAbsolutePath()))
.map(line -> line.split(","))
.map(fields -> new MockUser(fields[0], fields[1], fields[2]))
.collect(Collectors.toMap(
MockUser::getUsername,
user -> user));
但是,这希望MockUser::getUserName是静态的。。。知道为什么吗?顺便说一句,MockUser是一个POJO,我希望保持这种方式它是一个方法引用,与它是否是静态无关,不知道为什么它会给你错误这个答案不起作用。最后我得到的是一张地图
,这就是我得到的错误<代码>错误:(52,29)java:不兼容的类型:推理变量R具有不兼容的边界相等约束:java.util.Map上界:java.util.Map,java.lang.Object。我必须使用收集器。toMap()。看到我的答案了吧。是的,忘了这一点。很明显,分组将相似的密钥分组到一个列表中,并提供一对。我必须使用收集器。toMap()。请看我的答案。只有当用户名在所有模拟用户中是唯一的时,此代码才起作用,否则它会失败并出现异常。您确定它适合您的用例吗?这就是为什么groupingBy
创建一个Map
,以便在列表中对具有相同键的元素进行分组。适用于我的情况。用户文件无论如何都不应该有任何重复项。。。如果文件包含重复项,则会出现异常。