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