Reputation: 159
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
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
Reputation: 43
I have overridden get(int)
and size()
, but addPerson
is still able to add new String
s 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
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
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