Поток Java находит значение по ключу, если существует - PullRequest
0 голосов
/ 30 ноября 2018

У меня простая DataStructure

public class DataStructure {
    private String key;
    private String value;
    //get, set
}

И мне нужно вернуть значение из `List 'на основе ключа, и я хочу сделать это Java8 способом, с потоками.Я думаю, что код говорит сам за себя:

public class Main {
    public static void main(String args[]) {
      List<DataStructure> dataList = new ArrayList<>();
      dataList.add(new DataStructure("first", "123"));
      dataList.add(new DataStructure("second", "456"));

        System.out.println(findValueOldSchool(dataList, "third")); //works ok
        System.out.println(findValueStream(dataList, "third")); //throws NoSuchElementException
    }

    static String findValueOldSchool(List<DataStructure> list, String key) {
        for (DataStructure ds : list) {
            if (key.equals(ds.getKey())) {
                return ds.getValue();
            }
        }
        return null;
    }

    static String findValueStream(List<DataStructure> list, String key) {
        return list.stream()
                .filter(ds -> key.equals(ds.getKey()))
                .findFirst()
                .get().getValue();
    }
}

Как я могу изменить findValueStream(), чтобы не выбрасывать исключение NoSuchValueException при поиске несуществующего ключа?Я не хочу возвращать Optional<String>, потому что этот метод уже используется во многих местах проекта.И, конечно же, я пробовал map, ifPresent, anyMatch, просто не могу найти правильный способ сделать это.

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Вы должны использовать Stream.findFirst с Optional.orElse, например:

static String findValueStream(List<DataStructure> list, String key) {
    return list.stream() // initial Stream<DataStructure>
            .filter(ds -> key.equals(ds.getKey())) // filtered Stream<DataStructure>
            .map(DataStructure::getValue) // mapped Stream<String>
            .findFirst() // first Optional<String>
            .orElse(null); // or else return 'null'
}

Примечание : Приведенное выше использует Stream.map для сопоставления потока DataStructure с соответствующим потоком value.

0 голосов
/ 30 ноября 2018

используйте orElse, чтобы вернуть значение по умолчанию, если у Optional есть пустое состояние:

Это также означает, что вам сначала нужно отобразить на DataStructure::getValue следующим образом:

return list.stream()
           .filter(ds -> key.equals(ds.getKey()))
           .findFirst()
           .map(DataStructure::getValue)
           .orElse(null);

просто замена get на orElse будет не достаточным:

 return list.stream()
            .filter(ds -> key.equals(ds.getKey()))
            .findFirst()
            .orElse(null)
            .getValue();

Поскольку на этот раз вы получите NullPointerException вместо NoSuchElementException в случаепустого необязательного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...