Published 27 Oct, 2022

Java - How to replace only the first element of a List using java streams without making any changes to the rest of the list?

Category Java
Modified : Nov 28, 2022
55

I am getting a List and I want to replace the first value in this list with '$' sign, So that I could use it in some place else. But i don't want the rest of the characters in the list to be misplaced or changed. It's okay to get the result as a new list.

I already tried to just use the list.add(index, value) function but it changes the order of the list. But I don't want any change to the rest of the list.

Is there any good tutorials to to learn java streams. I find it confusing to master. Thanks in advance.

If the input list is ('H','E','L','L','O') the output should be exactly like ('$','E','L','L','O').

Answers

There are 4 suggested solutions here and each one has been listed below with a detailed description. The following topics have been covered briefly such as Java, Lambda, Java 8, Java Stream. These have been categorized in sections for a clear and precise explanation.

3

You can access the list using indices. If the index is zero just map it to a $, otherwise just send it to the next step of the stream processing pipeline. Finally collect it into a List. This approach is better than modifying your source container if you are using Java8. Here's how it looks.

List<Character> updatedList = IntStream.range(0, chars.size())
    .mapToObj(i -> i == 0 ? '$' : chars.get(i))
    .collect(Collectors.toList());

This problem does not lend itself nicely to be solved using Java8 streams. One drawback here is that it runs in linear time and looks we have over engineered it using java8. On the contrary, if you modify your array or list directly chars[0] = '$';, then you can merely do it in constant time. Moreover, the imperative approach is much more compact, readable and obviously has less visual clutter. I just posted the Java8 way of doing it, since you have explicitly asked for that. But for this particular instance, imperative way is far more better in my opinion. Either use an array and set the 0th index or if you need to go ahead with a List for some reason, then consider using List.set instead, as stated in the comments above.


37

hi you can look it the solution

public static void replaceCharacterList(){

        List<String> list =new ArrayList<String>();
        list.add("H");
        list.add("E");
        list.add("L");
        list.add("L");
        list.add("O");
        List<String> newItems = list.stream()
            .map(value-> value.replace(list.get(0),"$") )
            .collect(toList());
      Log.d("replace list","list "+list+" new list "+newItems);
    }

and the output will be like this

output: list [H, E, L, L, O] new list [$, E, L, L, O]

also for another example you can also look it to this example without Streams

https://examples.javacodegeeks.com/core-java/util/collections/replace-specific-element-of-list-example/


32

You could always use the traditional array copy and validation in the replace method for the index:

public class Main {
  private static List<Character> replace(List<Character> chars,int index, char value) {
    Character[] array = characters.toArray(new Character[0]);
    array[index] = value;
    return Arrays.asList(array);
  }
  public static void main(String[] args) {
    List<Character> characters = new ArrayList<>();
    characters.add('H');
    characters.add('E');
    characters.add('L');
    characters.add('L');
    characters.add('O');
    characters = replace(characters, 0, '$');
    for (Character character : characters) {
      System.out.println(character);
    }
  }
}

18

Similar to this, but with external index

AtomicInteger index = new AtomicInteger();
List<Character> newCollect = list.stream()
        .map(ch -> (index.getAndIncrement() == 0) ? '$' : ch)
        .collect(toList());