Рефакторинг два для в Ява 8 потоков - PullRequest
0 голосов
/ 02 ноября 2018

Я столкнулся с небольшой проблемой, чтобы переписать мои два for в потоки Java 8.

// This is a method parameter
Map<String, Collection<String>> preSelectedValues;

List<PersonModel> parameters = parameterSearchService.getParameterNames();

for(Iterator<Map.Entry<String, Collection<String>>> it = preSelectedValues.entrySet().iterator(); it.hasNext();) {
     Map.Entry<String, Collection<String>> entry = it.next();
     for(int i = 0; i < parameters.size(); i++) {
          if (entry.getKey().startsWith(parameters.get(i).getName())) {
               it.remove();
          }
     }
}

Я пробовал следующие потоки, чтобы иметь то же поведение, что и раньше:

Map<String, Collection<String>> filteredParameters = preSelectedValues.keySet().stream()
    .filter(x -> isParameterValid(x, parameters))
    .collect(Collectors.toMap(k -> k, v -> preSelectedValues.get(v)));

isParameterValid метод:

private boolean isParameterValid(String parameterId, List<PersonModel> preSelectedValues) {
     return preSelectedValues.stream()
            .anyMatch(v -> !v.getName().startsWith(parameterId));
}

По сути, я пытаюсь отфильтровать карту «preSelectedValues», которая начинается с «parameterId». Но почему-то, когда я использую потоки, он фильтрует все или ничего.

Ответы [ 2 ]

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

Если вы пытаетесь изменить исходную карту, вы можете использовать removeIf:

preSelectedValues.keySet().removeIf(
    key -> parameters.stream()
            .map(PersonModel::getName)
            .anyMatch(key::startsWith)
);
0 голосов
/ 02 ноября 2018

Ваш isParameterValid метод не имеет той же логики, что и исходные циклы, так как:

  1. Вы переключили экземпляр и аргумент в вызове на startsWith.
  2. Вызов anyMatch с !v.getName().startsWith(parameterId) говорит только о том, что хотя бы один элемент List<PersonModel> не начинается с parameterId. Ваше первоначальное условие для сохранения записи в Map состояло в том, что все элементы List<PersonModel> не начинаются с parameterId (или фактически, наоборот - parameterId не начать с любого из имен элементов List<PersonModel>).

Поэтому я отменил метод возврата условия удаления записи из Map:

private boolean isParameterInvalid(String parameterId, List<PersonModel> preSelectedValues) {
     return preSelectedValues.stream()
            .anyMatch(v -> parameterId.startsWith(v.getName()));
}

И тогда потоковый конвейер может выглядеть так:

Map<String, Collection<String>> filteredParameters = preSelectedValues.entrySet().stream()
    .filter(x -> !isParameterInvalid(x.getKey(), parameters))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Кстати, поскольку ваши оригинальные петли изменяют оригинал Map, вы можете добиться того же с помощью removeIf.

...