Java – how to find a letter in a string in ArrayList the duplicate string

I have a problem with some tasks. I have to find words that contains letter “r” and duplicate these words. I tried to do this with for loop:

for(int i = 0; i < list.size(); i++){
if(list.get(i).contains("r")){
            list.add(list.get(i));
 }

But it doesnt work at all. When i add new element to array would it make it bigger? Then list.size will change and loop wont manage to get to the last element of array? Also duplicated word should be just after the original one, for example input:

show
ram
cat

output:

show
ram
ram
cat

Really i have no idea how to duplicate it.

This also doesnt work:

for(int i = 0; i < list.size(); i++){
if(list.get(i).contains("r")){
            list.add(i+1, list.get(i));
}

After adding duplicate for element which contains letter r, you would eventually move to that duplicate and since it also contains r you will add duplicate for it, and then after visiting that another copy you will add another duplicate for it, and so on… infinitely so your loop will not end (until you will run of memory).

To avoid it, after duplicating element you need to jump to next element after that duplicate. You can do it by additional incrementing i after

list.add(i+1, list.get(i));
i++;

or

list.add(++i, list.get(i));

You could create a copy of your original List and add elements to it. That way the list you’re iterating over doesn’t change size.

For example:

List<String> list = Arrays.asList("show", "ram", "cat");
List<String> result = new ArrayList<>(list);
list.stream().filter(a -> a.contains("r")).forEach(a -> result.add(a));

Keep it simple and just use another List<String>.

public static void main(String[] args) {
    List<String> input = Arrays.asList("show", "ram", "cat");

    List<String> result = new ArrayList<>();
    for (String s : input) {
        if (s != null && s.contains("r")) {
            result.add(s);
        }
        result.add(s);
    }

    System.out.println(result);
}

Will print that you want. Hope it helps!

Depending on the type of your list, this can easily be achieved with a ListIterator, which has an add method that adds an element exactly after the current element, but does not iterate it.

List<String> list = new ArrayList<>( Arrays.asList( "show", "ram", "cat" ) );

ListIterator<String> iterator = list.listIterator();
while ( iterator.hasNext() ) {
    String value = iterator.next();
    if ( value.contains("r") ) {
        iterator.add(value);
    }
}

System.out.println( list );

The output from this is:

[show, ram, ram, cat]

This will work with ArrayList and LinkedList, but not with the particular List that comes directly from Arrays.asList, because it is unmodifiable.

You need find word which contains letter r and after that add all found words to the list:

    List<String> list = Arrays.asList("black", "red", "blue");
    List<String> result = list.stream()
        .filter(i->i.contains("r"))
        .collect(Collectors.toList());

    list.addAll(result);