繁体   English   中英

使用 Java 8 流处理嵌套的 if/else 语句

[英]Handling nested if/else statements using Java 8 streams

我有一个条件,为了创建一个对象,需要进行一些检查。 我为此使用了Stream ,但我很难完成这项工作。

输入是一个带有键/值对的HashMap对象,输出应该在下面。

| userrole   | userid | username | output   |
|------------|--------|----------|----------|
| "" (blank) | 111    | amathews | 111      |
| ""         |        | amathews | amathews |
| Admin      | 111    | amathews | 111      |
| Admin      | 111    | ""       | 111      |
| Admin      |        | amathews | Admin    |

优先级是这样的:userid>userrole>username。

每个HashMap对象将包含 userrole/username/userid 作为键及其值以及其他键/值对。 在以前的 Java 版本中,我们将有一堆嵌套的 if/else 语句来完成此任务。

这是我的代码:

map.entrySet().stream()
        .filter(e -> e.getValue() instanceof String || e.getValue() instanceof Integer)
        .filter(e -> e.getKey().contains("userrole") || e.getKey().contains("userid") || e.getKey().contains("username") )
        .map(e -> e.getValue())
        .collect(Collectors.toList());

我知道我在Stream编写 map 函数的方式也不正确。 如何在 Java 8 中实现这一点? 我不知道如何在此处添加嵌套的 if/else 部分。

编辑:对不起,如果我没有准确说明问题。 这是代码片段:

public List<UserAction> getUserActionList(Map<String, String> map)
    {
        String userRole = map.get("userrole");
        String userName = map.get("username");
        String userId = map.get("userid");

        String output = null;
        // if userrole, userid and username are not null/empty, then output is userid 
        if(!checkForNullEmpty(userRole) && !checkForNullEmpty(userId) && !checkForNullEmpty(userName))
            output = userId;
        // if userrole and userid are null/empty and username is not empty/null, then output is username
        else if(checkForNullEmpty(userRole) && checkForNullEmpty(userId) && !checkForNullEmpty(userName))
            output = userName;
        // if userid and username are null/empty and userrole is not empty/null, then output is userrole
        else if(!checkForNullEmpty(userRole) && checkForNullEmpty(userId) && checkForNullEmpty(userName))
            output = userRole;

        List<UserAction> udList = new ArrayList<>();
        // Add the map and output into a UserAction object
        udList.add(new UserAction(map, output));

        return udList;

    }

根据表格,我在这里只处理了 3 个条件。 所以这必须重构以使用 java 8 Stream s。 我希望它现在有意义。

如果保证至少有一个值,您可以像这样重构它:

public List<UserAction> getUserActionList(Map<String, String> map) {
    return Stream.of("userid", "username", "userrole")
        .map(map::get)
        .filter(s -> !checkForNullEmpty(s))
        .limit(1)
        .map(output -> new UserAction(map, output))
        .collect(Collectors.toList());
}

如果不能保证至少有一个值是非空的,那就有点难看,但还不错:

public List<UserAction> getUserActionList(Map<String, String> map) {
    return Stream.of("userid", "username", "userrole")
        .map(map::get)
        .filter(s -> !checkForNullEmpty(s))
        .limit(1)
        .map(output -> new UserAction(map, output))
        .map(Collections::singletonList)
        .findFirst()
        .orElseGet(() -> Arrays.asList(new UserAction(map, null)));
}

您需要完成的任务并不是很清楚,但总的来说,您需要在if语句中编写的所有内容都可以使用Stream API filter()方法完成。 然后,在map()方法中,您将拥有处理数据所需的确切逻辑(例如,将其转换为其他类型或获取所需的值)。 collect()方法用于从Stream创建结果,例如列表、集合、映射、单个对象或其他任何东西。 例如:

map.entrySet().stream()
                .filter(e -> {
                    // filter the data here, so if isStrOrInt or containsUserData is false - we will not have it in map() method
                    boolean isStrOrInt = e.getValue() instanceof String || e.getValue() instanceof Integer;
                    boolean containsUserData = e.getKey().contains("userrole") || e.getKey().contains("userid") || e.getKey().contains("username");
                    return isStrOrInt && containsUserData;
                })
                .map(e -> {
                    if (e.getKey().contains("userrole")) {
                        // do something
                    }
                    // some more logic here
                    return e.getValue();
                })
                .collect(Collectors.toList());
                // or e.g. .reduce((value1, value2) -> value1 + value2);

如果您最终需要创建单个对象,则可能需要reduce()方法。 我建议您检查reduction operations ,有关Stream API 的一般信息以了解它们是如何工作的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM