You can use filter on the streamed list, then simply update the count

public void updateCount(String bookName, int updateBy) {
  books.stream().filter(book -> book.getName().equals(bookName)).forEach(
      book -> book.setCount(book.getCount() + updateBy)
  );
}
Answer from baao on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › java › update-the-list-items-in-java
Java Program to Update the List Items - GeeksforGeeks
July 23, 2025 - In Java, Lists are dynamic collections that allow modifications, such as updating elements. We can use the set method to update the elements in the List. This method replaces the element at the given index with a new value, allowing modification ...
Top answer
1 of 2
2

I would use streams for that job.

Assuming your class MyObject has getters and setters methods defined (getKey(), getValue(), setKey(), setValue()), you can do:

l1.forEach(myObject1 -> l2.stream()
            .filter(myObject2 -> myObject1.getKey().equals(myObject2.getKey()))
            .findAny().ifPresent(myObject2 -> myObject1.setValue(myObject2.getValue())));

If you can have duplicate keys then you should modify ifPresent() to forEach():

l1.forEach(myObject1 -> l2.stream()
            .filter(myObject2 -> myObject1.getKey().equals(myObject2.getKey()))
            .forEach(myObject2 -> myObject1.setValue(myObject2.getValue())));
2 of 2
1

Not many elegant one line streaming I can think of. My suggestion is split two steps:

  1. convert l2 to map.
  2. stream map change items in l1. This is more flexible and easy to debug solution.
static class myObject {
    String key;
    int val;

    public myObject(String key, int val) {
      this.key = key;
      this.val = val;
    }

    @Override
    public String toString() {
      return "myObject{" +
          "key='" + key + '\'' +
          ", val=" + val +
          '}';
    }
  }
  public static void main(String[] args) {
    myObject a = new myObject("k1", 30);
    myObject b = new myObject("k2", 40);
    Map<String, myObject> list2map = List.of(a,b).stream().collect(Collectors.toMap(m -> m.key, m -> m));

    myObject c = new myObject("k1", 10);
    myObject d = new myObject("k2", 20);
    List<myObject> l1 = List.of(c, d);
    l1 = l1.stream().map(m -> {
      m.val = list2map.getOrDefault(m.key, m).val;
      return m;
    }).collect(Collectors.toList());
    System.out.println(l1);
  }
Top answer
1 of 10
119

Yes, you can modify state of objects inside your stream, but most often you should avoid modifying state of source of stream. From non-interference section of stream package documentation we can read that:

For most data sources, preventing interference means ensuring that the data source is not modified at all during the execution of the stream pipeline. The notable exception to this are streams whose sources are concurrent collections, which are specifically designed to handle concurrent modification. Concurrent stream sources are those whose Spliterator reports the CONCURRENT characteristic.

So this is OK

  List<User> users = getUsers();
  users.stream().forEach(u -> u.setProperty(value));
//                       ^    ^^^^^^^^^^^^^
//                        \__/

but this in most cases is not

  users.stream().forEach(u -> users.remove(u));
//^^^^^                       ^^^^^^^^^^^^
//     \_____________________/

and may throw ConcurrentModificationException or even other unexpected exceptions like NPE:

List<Integer> list = IntStream.range(0, 10).boxed().collect(Collectors.toList());

list.stream()
    .filter(i -> i > 5)
    .forEach(i -> list.remove(i));  //throws NullPointerException
2 of 10
5

The functional way would imho be:

import static java.util.stream.Collectors.toList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class PredicateTestRun {

    public static void main(String[] args) {

        List<String> lines = Arrays.asList("a", "b", "c");
        System.out.println(lines); // [a, b, c]
        Predicate<? super String> predicate = value -> "b".equals(value);
        lines = lines.stream().filter(predicate.negate()).collect(toList());

        System.out.println(lines); // [a, c]
    }
}

In this solution the original list is not modified, but should contain your expected result in a new list that is accessible under the same variable as the old one

Top answer
1 of 5
20

When you create a Stream from the List, you are not allowed to modify the source List from the Stream as specified in the “Non-interference” section of the package documentation. Not obeying this constraint can result in a ConcurrentModificationException or, even worse, a corrupted data structure without getting an exception.

The only solution to directly manipulate the list using a Java Stream, is to create a Stream not iterating over the list itself, i.e. a stream iterating over the indices like

IntStream.range(0, list1.size()).forEach(ix -> list1.set(ix, list1.get(ix)+1));

like in Eran’s answer

But it’s not necessary to use a Stream here. The goal can be achieved as simple as

list1.replaceAll(i -> i + 1);

This is a new List method introduced in Java 8, also allowing to smoothly use a lambda expression. Besides that, there are also the probably well-known Iterable.forEach, the nice Collection.removeIf, and the in-place List.sort method, to name other new Collection operations not involving the Stream API. Also, the Map interface got several new methods worth knowing.

See also “New and Enhanced APIs That Take Advantage of Lambda Expressions and Streams in Java SE 8” from the official documentation.

2 of 5
3

Holger's answer is just about perfect. However, if you're concerned with integer overflow, then you can use another utility method that was released in Java 8: Math#incrementExact. This will throw an ArithmeticException if the result overflows an int. A method reference can be used for this as well, as seen below:

list1.replaceAll(Math::incrementExact);
🌐
Medium
medium.com › @AlexanderObregon › javas-list-replaceall-method-explained-cf88a8cda6bd
Java's List.replaceAll() Method Explained
February 13, 2025 - The replaceAll() method from the java.util.List interface makes this easier by applying a function to each element and updating the list with the new values. This article breaks down how replaceAll() works, shows real examples of data ...
🌐
How to do in Java
howtodoinjava.com › home › collections framework › java arraylist › replace an existing item in arraylist
Replace an Existing Item in ArrayList
January 12, 2023 - Use set(index, object) to update with the new item. Note that the IndexOutOfBoundsException will occur if the provided index is out of bounds. The following Java program contains four strings.
🌐
TutorialKart
tutorialkart.com › java › how-to-update-an-element-of-arraylist-in-java
How to Update an Element of ArrayList in Java?
December 21, 2020 - import java.util.ArrayList; public class ArrayListExample { public static void main(String[] args) { ArrayList<String> names = new ArrayList<String>(); names.add("Google"); names.add("Apple"); names.add("Samsung"); //update element of arraylist names.set(1, "Asus"); for(String name: names) { System.out.println(name); } } } ... In the following example, we will create an ArrayList of Car objects, and update Car object of the list at index 2.
Find elsewhere
🌐
Java Code Geeks
javacodegeeks.com › home › core java
Java ArrayList Insert/Replace At Index - Java Code Geeks
January 2, 2022 - We can use the set() for any type of object such as wrapper classes, String or any user-defined custom objects. It is allowed to update the values of the array list based on the condition while iterating it with the help of set() method.
🌐
Medium
medium.com › @javabydhruvkumar › how-to-update-newly-objects-in-list-from-another-list-based-on-condition-using-streams-7d9241d2c0a0
How to update newly Objects in List from another List based on condition Using Streams | by Dhruv kumar | Medium
December 8, 2022 - package org.dt; import java.util.Arrays; import java.util.List; public class Test { public static void main(String[] args) throws Exception{ List<User> users= Arrays.asList(new User("dhruv","agra"),new User("Ankit","agra")); List<User> users1= Arrays.asList(new User("dhruv","hyd"),new User("Ankit","hyd")); //User user=new User("dhruv","agra"); users.forEach(user -> users1.stream() .filter(u-> u.getName().equals(user.getName())) .findFirst().ifPresent(u-> user.setAdd(u.getAdd()))); System.out.println(users); } }
Top answer
1 of 3
1

Feature Envy

The LoanAccountService needs to know all fields from LoanAccount that gets updated:

account.get().setCreationDate(loanAccount.getCreationDate());
account.get().setLoanAmount(loanAccount.getLoanAmount());
account.get().setNumberOfInstallments(loanAccount.getNumberOfInstallments());
account.get().setType(loanAccount.getType());

Now imagine LoanAccount would get a few more fields and they are updateable too but you forgot to change LoanAccountService.. This means LoanAccountService depends on LoanAccount..

A solution would be to add a new method to LoanAccount:

public LoanAccount updateBy(LoanAccount other) {
  this.creationDate = other.creationDate();
  this.loanAmount = other.loanAmount();
  this.numberOfInstallments = other.numberOfInstallments();
  this.type = other.type();
  return this;
}

Optional#map

The if-statement

if (account.isPresent()) {

can be replaced by the method map on Optional. With adding the new updateBy method:

public LoanAccount updateBy(LoanAccount other) {
  bank.getLoanAccounts()
      .stream()
      .filter(la -> la.getId().equals(other.getId()))
      .findAny()
      .map(loanAccount -> loanAccount.updateBy(other))
      .orElseThrow(() -> new IllegalArgumentException("The object does not exist."));
  return other;
}

Further Improvement

A second Feature Envy is in the following snipped:

bank.getLoanAccounts()
   .stream()
   .filter(la -> la.getId().equals(loanAccount.getId()))

Not the LoanAccountService should filter the data but the Bank itself should filter it:

// in Bank.java

public Optinal<List<LoanAccount> findBy(int id) {
   return loanAccounts.stream()
                      .filter(la -> la.getId().equals(id))
                      .collect(Collectors.toList())
}

All together

// LoanAccountService.java

public LoanAccount updateBy(LoanAccount other) {
  bank.findBy(other.getId())
      .findAny()
      .map(loanAccount -> loanAccount.updateBy(other))
      .orElseThrow(() -> new IllegalArgumentException("The object does not exist."));
  return other;
}
2 of 3
1

I would suggest following:

  1. Place operations to the objects that contain data for this operation. It will improve encapsulation and allow more flexible code reuse. Also it will be easy to test such implementation because of small methods.
  2. Use more convenient structure. In this case Map<String, LoanAccount> (map id to loanAccount) instead of List<LoanAccount>

As you can see in this case service contains only required logic (how to react on loan absence). It is easy to read, test and understand.

LoanAccountService.java

public class LoanAccountService{

    private Bank bank;

    public LoanAccountService(Bank bank) {
        this.bank = bank;
    }

    public LoanAccount update(LoanAccount loanAccount) {
        if (!bank.updateLoanAccount(loanAccount)) {
            throw new IllegalArgumentException("The object does not exist.");
        }
        return loanAccount;
    }
}

Bank.java

@Getter
@Setter
public class Bank {
    private Map<String, LoanAccount> loanAccounts;

    public boolean updateLoanAccount(LoanAccount loanAccount) {
        LoanAccount loan = loanAccounts.get(loanAccount.getId());
        if (loan != null) {
            loan.update(loanAccount);
            return true;
        }
        return false;
    }
}

LoanAccount.java

@Getter
@Setter
public class LoanAccount {
    private String id;
    private Integer numberOfInstallments;
    private LoanAccountType type;
    private Date creationDate;
    private BigDecimal loanAmount;

    public void update(LoanAccount loanAccount) {
        this.setCreationDate(loanAccount.getCreationDate());
        this.setLoanAmount(loanAccount.getLoanAmount());
        this.setNumberOfInstallments(loanAccount.getNumberOfInstallments());
        this.setType(loanAccount.getType());
    }
}

If you can't use this approach, you could made a small refactoring of the service (less code and "if conditions" are good things):

public LoanAccount update(LoanAccount loanAccount) {
    LoanAccount account = bank.getLoanAccounts()
            .stream()
            .filter(la -> la.getId().equals(loanAccount.getId()))
            .findAny()
            .orElseThrow(() ->  new IllegalArgumentException("The object does not exist."));
    account.setCreationDate(loanAccount.getCreationDate());
    account.setLoanAmount(loanAccount.getLoanAmount());
    account.setNumberOfInstallments(loanAccount.getNumberOfInstallments());
    account.setType(loanAccount.getType());
    return account;
}

Also I think you should return updated loan account.

🌐
Stack Exchange
cs.stackexchange.com › questions › 154419 › update-a-property-of-all-objects-in-a-list-collection-array-when-at-least-one-ob
algorithms - Update a property of all objects in a List/Collection/Array when at least one object satisfies a criteria using a single loop - Computer Science Stack Exchange
Solution: Have a reference which dictates the hikeEligibility which can be false by default. Iterate and assign the same reference to all the objects in the collection. If at least one item in the collection meets the criteria, set the value of hikeEligibility to true
🌐
w3resource
w3resource.com › java-exercises › collection › java-collection-exercise-5.php
Java - Update specific array element by given element
May 21, 2025 - import java.util.*; public class Exercise5 { public static void main(String[] args) { // Creae a list and add some colors to the list List<String> list_Strings = new ArrayList<String>(); list_Strings.add("Red"); list_Strings.add("Green"); list_Strings.add("Orange"); list_Strings.add("White"); list_Strings.add("Black"); // Print the list System.out.println(list_Strings); // Update the third element with "Yellow" list_Strings.set(2, "Yellow"); // Print the list again System.out.println(list_Strings); } }
🌐
Java2s
java2s.com › example › java › collection-framework › update-objects-stored-in-list-by-reference.html
Update objects stored in List by reference - Java Collection Framework
Array lists contain references to objects, not the objects themselves, any changes you make to an object in an array list are automatically reflected in the list. import java.util.ArrayList; public class Main { public static void main(String[] args) { ArrayList<Employee> emps = new ArrayList<Employee>(); // add employees to array list emps.add(new Employee("A")); emps.add(new Employee("T")); emps.add(new Employee("K")); // print array list System.out.println(emps);/* w ww. j av a2s. c om*/ // change one of the employee's names Employee e = emps.get(1); e.setName("new name"); // print the array