【问题标题】:How to Create Immutable Class with List<String> Element in class如何在类中使用 List<String> 元素创建不可变类
【发布时间】:2019-10-21 07:58:54
【问题描述】:

带列表的不可变类

package com.text.immutable;

import java.util.Collections;
import java.util.List;

// An immutable class Student
public final class Student 
{ 
    final String name; 
    final int regNo; 
    final List<String> courses;  // want to make Immutable 

    public Student(String name, int regNo, List<String> courses) 
    { 
        this.name = name; 
        this.regNo = regNo; 
        this.courses = Collections.unmodifiableList(courses);
    } 
    public String getName() 
    { 
        return name; 
    } 
    public int getRegNo() 
    { 
        return regNo; 
    } 

    public List<String> getCourses() {
        return courses;
    }
} 

测试不可变类以打破不变性

package com.text.immutable;

import java.util.ArrayList;
import java.util.List;

class ImmutablityTest 
{ 
    public static void main(String args[]) 
    { 
        List<String> courses = new ArrayList<String>();
        courses.add("java");
        courses.add("spring");
        courses.add("hibernate");
        courses.add("rest");

        Student s = new Student("ABC", 101, courses); 

        System.out.println("Before Update List");
        System.out.println(s.getName()); 
        System.out.println(s.getRegNo()); 
        System.out.println(s.getCourses());
        courses.add("Hibernate"); // Able to Change which affect final OutCome
        //s.getCourses().add("SpringBoot"); // giving Exception in thread "main" java.lang.UnsupportedOperationException

        System.out.println("After Update List");
        System.out.println(s.getName()); 
        System.out.println(s.getRegNo()); 
        System.out.println(s.getCourses());

    } 
} 

输出是

Before Update List
ABC
101
[java, spring, hibernate, rest]
After Update List
ABC
101
[java, spring, hibernate, rest, Hibernate]

为什么以及如何将这个从客户端添加到列表中的新课程元素随时添加,所以我们如何解决这个问题,因为这个不可变类在创建后不允许修改

【问题讨论】:

  • 设置时克隆列表。
  • 我总是把它们混在一起——所以你的问题很合理+1

标签: java arraylist immutability immutable-collections


【解决方案1】:

this.courses = Collections.unmodifiableList(courses);

顾名思义,这将创建一个不可修改列表。但这只是原始列表中的一个视图。因此,对该原始列表的更改在您的“不可修改”视图中变得可见。

如有疑问:复制您的列表,例如:

this.courses = new ArrayList<>(courses);

然后确保您的 getter 这样做:

return Collections.unmodifiableList(courses);

【讨论】:

  • 是的 - 它必须是不可修改的 - 不是一成不变的 ^_^ +1
  • this.courses = Collections.unmodifiableList(new ArrayList&lt;&gt;(courses)); 也应该足够了
  • 感谢@GhostCat 你的也可以工作,但 Koziolek 也可以工作,哪个更好,更合适的解决方案
【解决方案2】:

在记忆方面不是最好的,但很有效:


// An immutable class Student
public final class Student 
{ 
    final String name; 
    final int regNo; 
    final List<String> courses;  // want to make Immutable 

    public Student(String name, int regNo, List<String> courses) 
    { 
        this.name = name; 
        this.regNo = regNo; 
        this.courses = new ArrayList(courses);
    } 
    public String getName() 
    { 
        return name; 
    } 
    public int getRegNo() 
    { 
        return regNo; 
    } 

    public List<String> getCourses() {
        return new ArrayList(courses);
    }
} 

在输入时(在构造函数中)创建列表的副本,在输出时(在 getter 中)创建副本。

【讨论】:

  • 感谢@Koziolek,你的也可以工作,但 GhostCat 也可以工作,哪个更好,更合适的解决方案
【解决方案3】:

阅读about immutableLists,您会发现不可变和不可修改的不一样

我猜(根据您的问题)您期待一个您根本不会创建的不可修改列表...

请参阅this answer 以获得适当的解决方案

【讨论】:

    【解决方案4】:

    使用Collections.unmodifiableList,它会围绕原始列表创建一个包装器,并且该包装器对象是不可修改的。原始列表仍然可以更新。

    因此,为了使List&lt;String&gt; courses 列表不可变,您可以使用 Apache 集合公共库。

    List<String> immutableList = com.google.common.collect.ImmutableList.of("Geeks", "For","Geeks");

    ImmutableList 已重写 List.add 方法以始终抛出异常java.lang.UnsupportedOperationException


    第二种选择是在构造函数本身内创建列表。

    public Student(String name, int regNo,  String... args) 
    { 
        this.name = name; 
        this.regNo = regNo; 
        courses = (List)Arrays.asList(args);
    
    }
    

    然后这样称呼它:

     Student s = new Student("ABC", 101, "a","a","a","a"); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      • 2023-02-06
      • 1970-01-01
      • 2012-10-19
      相关资源
      最近更新 更多