Search code examples
javacollectionsunmodifiable

How to reverse an unmodifiable List in java


I am trying to reverse an unmodifiable list. However i have tried to achieve it but Is it possible to update or reverse and unmodifiable list? I know we can do it with Google Immutable List

import java.util.*;

public class ImmutableList 
 {

public static void main(String args[])
{
    String[] mylist = {"Apple","Orange","Mango","Kiwi","Banana"};
    List reverselist = new ArrayList();
    List<String> strList = Arrays.asList(mylist);
    List<String> unmodifiableList = Collections.unmodifiableList(strList);
    for(int i=unmodifiableList.size();i>0;i--)
    {
        reverselist.add(unmodifiableList.get(i-1));

    }
    List<String> reverse = Collections.unmodifiableList(reverselist);
    System.out.println(reverse);
  }

 }

In the above program I am just traversing in unmodifable list from back and putting them in an array after that adding that array to new unmodifiable list. Can we do it in better way in terms of optimisation?


Solution

  • When the list is unmodifiable anyhow, you can just create a reversed view on the list.

    This is optimal in terms of performance and storage: It requires O(1) time and O(1) additional space to create this list.

    import java.util.AbstractList;
    import java.util.Arrays;
    import java.util.List;
    
    public class ReversedListViewTest
    {
        public static void main(String[] args)
        {
            String[] array = {"Apple","Orange","Mango","Kiwi","Banana"};
    
            List<String> list = Arrays.asList(array);
            System.out.println("List         : "+list);
    
            List<String> reversedView = reversedView(list);
            System.out.println("Reversed view: "+reversedView);
        }
    
        private static <T> List<T> reversedView(final List<T> list)
        {
            return new AbstractList<T>()
            {
                @Override
                public T get(int index)
                {
                    return list.get(list.size()-1-index);
                }
    
                @Override
                public int size()
                {
                    return list.size();
                }
            };
        }
    
    }