Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 streams/maps/filters to modify or delete list elements on the fly

Java 8 here. Looking for a (possibly stream-based) "Java 8" way of replacing and/or deleting an object off of a List. Here's my code:

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;
      }
    }
  }
}

I think this can be written more efficiently/concisely and also in such a way as to leverage Java 8 streams/maps but I can't seem to figure out how to wire everything together. Any ideas?

like image 230
hotmeatballsoup Avatar asked Apr 04 '19 16:04

hotmeatballsoup


1 Answers

Because you are using void as return type and want to modify the given List using a Stream would not be the best solution. You can just use List.replaceAll() and List.removeIf() to solve this with a simple if statement:

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

If you have more actions than replace and delete you can use a switch statement instead of if.

If you really want to use Streams I also would separate the different actions. You also have to return the new List in your method and reassign it to the variable you pass to that method:

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());
}
like image 99
Samuel Philipp Avatar answered Nov 14 '22 23:11

Samuel Philipp