Java 将对象流收集到地图中

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 -> {

我有一个用户详细信息的csv文件,我必须通过读取每一行将其加载到HashMap中。这是使用Java8流的一些帮助来完成的

 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
,以便在列表中对具有相同键的元素进行分组。适用于我的情况。用户文件无论如何都不应该有任何重复项。。。如果文件包含重复项,则会出现异常。