Search code examples
javaarraylistcollections

Move element backward in a List using Collections.rotate() in Java


I have an ArrayList as mentioned below (My Code Snippet).

My List elements are in this order initially - ("Periodic", "Multiple", "Single", "Subsequent", "Consecutive").

After applying Collections.rotate() on my List elements the modified List should look like -

("Periodic", "Subsequent", "Multiple", "Single", "Consecutive").

Element "Subsequent" needs to be moved backward to the 1st index element in the List which is "Multiple", so that the element at 1st index will be pushed down to the 2nd index after rotating.

When I tried using Collections.rotate(), it throws an Exception.

IllegalArgumentException "fromIndex > toIndex".

I researched and understood the error, toIndex should always be greater than or equal to fromIndex, but I could not quite figure out how to modify my code snippet in order to achieve what I need.

Any suggestions would greatly be appreciated.

Isn't it possible to move an element backward in a List using rotate() method?

List<String> list = new ArrayList<String>(Arrays.asList("Periodic", "Multiple", "Single", "Subsequent", "Consecutive"));
       for (int i = 0; i < list.size(); i++) {
            int indexOfSubName = 0;
            int indexOfMultipleName = 0;

            String name = list.get(i);

            if (name.equalsIgnoreCase("Subsequent")) {
                indexOfSubName = list.indexOf(name);

            }

            if (name.equalsIgnoreCase("Multiple")) {
                int indexOfMultipleName = list.indexOf(name);
            }
           Collections.rotate(list.subList(indexOfSubName , indexOfMultipleName ), 1);
        }

Solution

  • Two issues:

    • You are trying to get sublist from 3 to 1 which should be vice versa. So you could check min and max and then try to get sublist.
    • Your sublist call will bring you element say from index 1 to n-1 i.e. if you pass 3, you will get just two elements i.e. index 1 and 2 and not the third one. See this javadoc for details. You could do something like:

      List<String> list = new ArrayList<String>(Arrays.asList("Periodic", "Multiple", "Single", "Subsequent", "Consecutive"));
      int indexOfSubName = 0;
      int indexOfMultipleName = 0;
      for (int i = 0; i < list.size(); i++) {
          String name = list.get(i);
          if (name.equalsIgnoreCase("Subsequent")) {
              indexOfSubName = list.indexOf(name);
          }
          if (name.equalsIgnoreCase("Multiple")) {
              indexOfMultipleName = list.indexOf(name);
          }
      }
      int min = Math.min(indexOfMultipleName, indexOfSubName);
      int max = Math.max(indexOfMultipleName, indexOfSubName);
      Collections.rotate(list.subList(min, max+1), 1);
      System.out.println(list);
      

    if you run this, you will get output as what you need:

    [Periodic, Subsequent, Multiple, Single, Consecutive]