1

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));
}
2
  • Why don't you create a duplicate ArrayList? Commented Jul 27, 2017 at 10:22
  • Well, i didnt know i could :D Thought i had to change existing one. Thanks. Commented Jul 27, 2017 at 10:24

5 Answers 5

5

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));
Sign up to request clarification or add additional context in comments.

1 Comment

Jeez, it was so easy :D Thanks a lot!
1

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

Comments

1

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.

Comments

0

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!

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.