我有条件要进行一些检查以创建对象。
我正在使用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
中编写地图功能的方式也不正确。
如何在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
。我希望它现在有意义。
答案 0 :(得分:3)
如果保证至少有一个值,你可以这样重构:
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)));
}
答案 1 :(得分:2)
对于您需要完成的任务并不是很清楚,但总的来说,您需要在if
语句中编写的所有内容都可以使用filter()
方法从{Stream API
1}}。然后,在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的一般信息,了解它们的工作原理。