[英]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.