Also eine Stream-basierte Lösung ist hier unnötig. Auf Zwang würde ich das auch nicht nutzen.
Du musst auch kein Schleife oder so bauen um das Element zu finden. Du hast beim Ersetzen zwei Aufrufe:
a) Finden des index mittels
indexOf Aufruf
b) setzen des neuen Eintrages mittels
set Aufruf.
Eine Stream Lösung selbst wäre aus meiner Sicht unleserlich und unnötig komplex. Das würde dann vermutlich darauf hinaus laufen, dass man alle Elemente streams, dann in einer map Methode schaut: Ist es das gesuchte Element, dann mapt man es zu dem neuen, ansonsten bleibt es das bestehende und dann sammelt man es in einer neuen ObervableList die man dann zuweist.
Aber neue ObservableList bedeutet, dass man auch die Observer wieder neu eintragen muss und so ... Und daran merkt man dann doch recht schnell, dass das nicht wirklich Sinn machen kann ...