Coded9
Coded9

Reputation: 159

How to create a read-only list in java without using unmodifiablelist method from collections API?

An interviewer asked me this question to create a read-only list in java without using collections API method.Any thoughts on how we can achieve this ?

Upvotes: 1

Views: 5306

Answers (4)

Ramanlfc
Ramanlfc

Reputation: 8354

Just extend AbstractList. As the docs mention:

To implement an unmodifiable list, the programmer needs only to extend this class and provide implementations for the get(int) and size() methods.

Upvotes: 6

user2742080
user2742080

Reputation: 43

I have overridden get(int) and size(), but addPerson is still able to add new Strings to the ArrayList.

import java.util.AbstractList;
import java.util.ArrayList;

public class UnmodifyableList extends AbstractList
{
    public UnmodifyableList()
    {
        arrayList = new ArrayList<>();
        arrayList .add("Artyom");
        arrayList .add("Natasha");
        arrayList .add("Anton");
        arrayList .add("Dasha");
    }

    @Override
    public String get(int i)
    {
        return arrayList.get(i);
    }

    @Override
    public int size()
    {
        return arrayList.size();
    }

    public void addPerson()
    {
        arrayList.add("testname");
    }
}

but when I delete addPerson() and use methods inherited from AbstractList, yes, it turns out that the ArrayList cannot be modified.

Upvotes: 0

Mohd Faizan Khan
Mohd Faizan Khan

Reputation: 435

I have been asked the same question in an interview, and I came up with some code which works fine in my case and interviewer got convinced.

Employee Class

public final class Employee {
 private int age;
 private String name;
 private double salary;
 public Employee(int age, String name, double salary){
    this.name=name;
    this.age=age;
    this.salary=salary;
 }

 public int getAge() {
    return age;
 }
 public String getName() {
    return name;
 }
 public double getSalary() {
    return salary;
 }
}

EmployeeList Class

public class EmployeeList extends AbstractList<Employee>{

private ArrayList<Employee> list;

 public EmployeeList(ArrayList<Employee> list){
    this.list=list;
 }

 @Override
 public Employee get(int i) {
    return this.list.get(i);
 }

 @Override
 public int size() {
    return this.list.size();
 }

}

EmployeeListUtility Class

public class EmployeeListUtility {
 private EmployeeList employeeList;
 public EmployeeList getImmutableEmployeeList(ArrayList<Employee> employeeList) {
    this.employeeList = new EmployeeList(employeeList);
    return this.employeeList;
 }

}

Runner Class

public class RunnerClass {
public static void main(String[] args) {
    ArrayList<Employee> listOfEmployees=new ArrayList<>();
    listOfEmployees.add(new Employee(1, "Faizan", 1000));
    listOfEmployees.add(new Employee(2, "Arun", 1000));
    listOfEmployees.add(new Employee(3, "Amit", 1000));
    listOfEmployees.add(new Employee(4, "Noman", 1000));
    listOfEmployees.add(new Employee(5, "John", 1000));

    //till now listOfEmployee is mutable

    EmployeeListUtility employeeListUtility=new EmployeeListUtility();
    EmployeeList employeeList=employeeListUtility.getImmutableEmployeeList(listOfEmployees);
    //now employeeList object is immutable. 
    System.out.println(employeeList.size()); //print 5
    employeeList.clear();  //will throw java.lang.UnsupportedOperationException 
}

}

Now with employeeList object in runner class, if you try to access any other method of AbstractList which you have not implemented in EmployeeList Class, then it will throw java.lang.UnsupportedOperationException.

which means your employeeList is immutable now.

Upvotes: 2

Simmant
Simmant

Reputation: 1513

I try some thing like below, hope it will help:

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ImutableList {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        List<Integer> lsd = new ArrayList<Integer>();
        lsd.add(1);
        lsd.add(2);
        lsd.add(3);
        lsd.add(4);

        ImList imList = new ImList(lsd);
        imList.getLis().add(5);
        imList.getLis().add(6);
        imList.getLis().add(7);
        imList.getLis().add(8);

        for (int k : imList.getLis()) {
            System.out.println(k);
        }
// output will: 1 2 3 4 only    

        }

    static class ImList extends AbstractList<Integer> {

        private final List<Integer> list;

        public ImList(List list) {
            this.list = list;
        }

        @Override
        public Integer get(int index) {
            // TODO Auto-generated method stub
            return this.list.get(index);
        }

        @Override
        public int size() {
            // TODO Auto-generated method stub
            return this.list.size();
        }

        public List<Integer> getLis() {
            return new ArrayList<>(list);
        }

    }

}

Upvotes: 0

Related Questions