Java 8 потоков / карт / фильтров для изменения или удаления элементов списка на лету - PullRequest
6 голосов
/ 04 апреля 2019

Java 8 здесь. Ищите (возможно, основанный на потоке) способ «Java 8» для замены и / или удаления объекта из List. Вот мой код:

public void applyChanges(List<Fizz> fizzes, Action action, Fizz toModify) {
  int i = 0;
  for (Fizz fizz : fizzes) {
    i++;
    if (fizz.getId() == toModify.getId()) {
      switch(action) {
      case Replace:
        // Here we want to replace 'fizz' in the list
        // with 'toModify' however order/sequence doesn't matter.
        fizzes.remove(i);
        fizzes.add(toModify);
        break;
      case Delete:
      default:
        // Here we just want to remove the Fizz with the matching
        // ID from 'fizzes'.
        fizzes.remove(i);
        break;
      }
    }
  }
}

Я думаю, что это можно написать более эффективно / кратко, а также таким образом, чтобы использовать потоки / карты Java 8, но я не могу понять, как соединить все вместе. Есть идеи?

Ответы [ 2 ]

7 голосов
/ 04 апреля 2019

Поскольку вы используете void в качестве возвращаемого типа и хотите изменить данный список с помощью потока, не будет лучшим решением.Вы можете просто использовать List.replaceAll() и List.removeIf(), чтобы решить это простым оператором if:

public void applyChanges(List<Fizz> fizzes, Action action, Fizz toModify) {
    if (action == Action.Replace) {
        fizzes.replaceAll(fizz -> fizz.getId() == toModify.getId() ? toModify : fizz);
    } else {
        fizzes.removeIf(fizz -> fizz.getId() == toModify.getId());
    }
}

Если у вас больше действий, чем заменитьи удалить вы можете использовать оператор switch вместо if.

Если вы действительно хотите использовать потоки, я бы также разделил различные действия.Вы также должны вернуть новый List в вашем методе и переназначить его переменной, которую вы передаете этому методу:

public List<Fizz> applyChanges(List<Fizz> fizzes, Action action, Fizz toModify) {
    if (action == Action.Replace) {
        return fizzes.stream()
                .map(fizz -> fizz.getId() == toModify.getId() ? toModify : fizz)
                .collect(Collectors.toList());
    }
    return fizzes.stream()
            .filter(fizz -> fizz.getId() != toModify.getId())
            .collect(Collectors.toList());
}
2 голосов
/ 04 апреля 2019

Вы можете использовать map с потоками, например:

List<Fizz> applyChanges(List<Fizz> fizzes, Action action, Fizz toModify) {
    return fizzes.stream()
            .map(fizz -> fizz.getId().equals(toModify.getId()) ?
                    action.equals(Action.Replace) ? toModify : null : fizz)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
}
...