2016-10-10 53 views
2

我是java 8的新手,并且有创建对象时需要进行一些检查的情况。 我当然在使用这个流,并且在完成这个过程中经历了艰难的时间。使用Java 8流处理嵌套的if/else语句

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

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

这是如何确定userid> userrole>用户名。

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

我们将有一堆嵌套的if/else语句来完成此前的Java版本中的任务。

这是我到目前为止的代码。

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()); 

我知道我在流中写入map函数的方式也不正确。 如何在java 8中完成此操作?我不知道如何在这里添加嵌套的if/else部分。

请有人帮我在这里我卡住了,无法继续。谢谢。

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

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; 

    } 

我已经在这里按照表格处理了三个条件。所以这必须重构为使用Java 8流。希望现在有意义。

+1

什么是你的实际问题?您发布的代码是否无效?如果不是,为什么不呢?如果它确实有效,你究竟在问什么?也许发布一些带有示例数据的可执行代码以及期望的数据类型应该是什么 – Bohemian

+0

感谢您的回复。我已经添加了片段,希望现在清楚。 – 15R6

+2

它是否保证至少有一个值会在地图中找到? – Bohemian

回答

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))); 
} 
+0

感谢您使用@bohemian。我只是想了解它是如何工作的。因此,首先我们要创建一个必需的键的流,然后我们将从地图对象中获取这个值,过滤掉空/空值,然后限制其中一个值,创建一个UserAction对象并最终收集所有的对象列表..我不明白的是它将如何优先考虑Ie用户ID>的UserRole>用户名?按照我所使用的表格的含义,如我的代码片段所示。所以这将成为嵌套if/else right ... – 15R6

+1

@ 15R6你基本上已经知道了,但注意'.limit(1)'。这意味着流在收集第一个元素后停止。第一次击中后流中的任何物品甚至都没有穿过。例如,如果'map.get'userid“)'返回一个值,那么不会再调用'map.get()'。溪流一次通过一个元素一路燃烧。在进入下一步之前,他们不会通过所有元素的步骤。希望这有助于。 – Bohemian

1

这不是真的清楚你需要完成的任务,但在一般情况下,你需要在你的if语句来写,你可以用filter()方法从Stream API做的一切。然后,在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的一般信息,了解它们的工作原理。

+0

感谢您的回复@ yuriy。是的,我明白你的回答。我也会尝试这种方式。在使用代码片段查看编辑后的问题之后的任何其他建议? – 15R6