t T s
t T s

Reputation: 75

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

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').

Upvotes: 3

Views: 3700

Answers (4)

Sam Orozco
Sam Orozco

Reputation: 1258

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

Upvotes: 1

Ravindra Ranwala
Ravindra Ranwala

Reputation: 21124

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.

Upvotes: 4

lczapski
lczapski

Reputation: 4140

Similar to this, but with external index

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

Upvotes: 1

Mudassir Khan
Mudassir Khan

Reputation: 1782

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/

Upvotes: 1

Related Questions