2015-05-20 2 views
6

Мне нужно преобразовать измененный объект списка в неизменный список, каков возможный путь в java.Как создать неизменяемый список в java?

public void action() { 

    List<MutableClass> mutableList=Arrays.asList(new MutableClass("san","UK",21),new MutableClass("peter","US",34)); 
    List<MutableClass> immutableList=immutateList(mutableList); 
} 

public List<MutableClass> immutateList(List<MutableClass> mutableList){ 
    //some code here to make this beanList immutable 
    //ie. objects and size of beanList should not be change. 
    //ie. we cant add new object here. 
    //ie. we cant remove or change existing one. 
} 

Ниже мой MutableClass -

final class MutableClass{ 
final String name;  
final String address; 
final int age; 
MutableClass(String name, String address ,int age){ 
    this.name=name; 
    this.address=address; 
    this.age=age; 
} 
} 
+0

Что там у вас не неизменны, потому что вы можете легко вызвать метод .add (Object o). Создайте подкласс ArrayList, переопределите метод .add (..) и попросите его либо выполнить пустую реализацию, либо выбросить неконтролируемое исключение. И сделайте этот класс окончательным, так что вы не можете подклассифицировать его и изменить реализацию. – Stultuske

+0

Вы можете обернуть список другим объектом и реализовать только интерфейс Iterable. –

+3

. Ответьте на свой вопрос: http://stackoverflow.com/questions/10750791/what-is-the-sense-of-final-arraylist –

ответ

23

Вы можете сделать

beanList = Collections.unmodifiableList(beanList); 

когда вы инициализирован beanList, чтобы сделать его неизменны.

Если у вас есть как внутренние методы, которые должны быть в состоянии изменить список, и общественные методы, которые не должны допускать изменения, я предлагаю вам сделать

// public facing method where clients should not be able to modify list  
public List<Bean> getImmutableList(int size) { 
    return Collections.unmodifiableList(getMutableList(size)); 
} 

// private internal method (to be used from main in your case) 
private List<Bean> getMutableList(int size) { 
    List<Bean> beanList = new ArrayList<Bean>(); 
    int i=0; 

    while(i<size) { 
     Bean bean = new Bean("name"+i,"address"+i,i+18); 
     beanList.add(bean); 
     i++; 
    } 
    return beanList; 
} 

(Ваши Bean объекты уже кажутся незыблемыми.)


в качестве побочного примечание: Если вам случится быть с помощью Java 8+, ваш getMutableList может быть выражена следующим образом:

return IntStream.range(0, size) 
       .mapToObj(i -> new Bean("name" + i, "address" + i, i + 18)) 
       .collect(Collectors.toCollection(ArrayList::new)); 
5

Использование Collections.unmodifiableList(). Вы передаете исходный код ArrayList и он возвращает список, который генерирует исключение, если вы пытаетесь добавить, удалить или сменить элементы. Например, используйте return Collections.unmodifiableList(beanList); вместо return beanList; в конце getImmutableList(). main() выдает исключение. Класс Collections имеет методы для всех других общих типов коллекций, кроме списка.

0

Ниже приведено решение для того, чтобы сделать список неизменным без использования каких-либо API.

Неизменный объект с переменной-члена ArrayList

public final class Demo { 

private final List<String> list = new ArrayList<String>(); 

public Demo() { 
    list.add("A"); 
    list.add("B"); 
} 

public List<String> getImmutableList() { 
    List<String> finalList = new ArrayList<String>(); 
    list.forEach(s -> finalList.add(s)); 
    return finalList; 
} 

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    Demo obj = new Demo(); 
    System.out.println(obj.getImmutableList()); 
    obj.getImmutableList().add("C"); 
    System.out.println(obj.getImmutableList()); 
} 

}

Так фактический список не изменится, всегда на выходе будет [A, B]

Смежные вопросы