2016-10-10 3 views
2

Я новичок в java 8 и имею условие, в котором есть некоторые проверки, которые необходимо выполнить для создания объекта. Я, конечно, использую потоки для этого, и у меня было трудное время для этого.Обработка вложенных операторов if/else с использованием потоков Java 8

Ввод - это объект HashMap с парами ключ/значение, а вывод должен быть ниже.

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

Вот как следует идентификатор пользователя userid> userrole>.

Каждый объект HashMap будет содержать имя пользователя/имя пользователя/пользователя в качестве ключа и его значения вместе с другими парами ключ/значение. У нас будет куча вложенных операторов 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()); 

Я знаю, что способ, которым я написал функцию отображения в потоке, также неверен. Как это сделать в java 8? Я не знаю, как добавить здесь вложенную часть if/else.

Пожалуйста, помогите мне здесь. Я застрял и не смог продолжить. Благодарю.

Редактировать: Sorry Если бы я не задал проблему точно. Вот код 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; 

    } 

Я обработал здесь только 3 условия согласно таблице. Таким образом, это необходимо для рефакторинга для использования потоков 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 и, наконец, собрать все объекты в список. То, что я не понял, - это то, как он будет расставлять приоритеты ID_пользователя> UserRole> имя пользователя ?? Значение в соответствии с таблицей у меня с условиями, как показано в моем фрагменте кода. Таким образом, это станет вложенным, если/else правильно ... – 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

Смежные вопросы