Java 如何使用List创建不可变类<;字符串>;课堂元素

Java 如何使用List创建不可变类<;字符串>;课堂元素,java,arraylist,immutability,immutable-collections,Java,Arraylist,Immutability,Immutable Collections,具有列表的不可变类 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

具有列表的不可变类

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;
    }
} 
为什么以及如何将这个新的课程元素添加到列表中,作为其来自客户端的元素可以随时添加,因此我们如何解决这个问题,因为这个不可变的类在创建后不允许修改

阅读,您会发现,不可变和不可修改是不同的

我猜(从你的问题中)你期待的是一个不可修改的列表,,而你根本没有创建它

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

this.courses=Collections.unmodifiableList(课程)

正如名字所说,这将创建一个不可修改的列表。但这只是原始列表中的一个视图。因此,对原始列表的更改在“不可修改”视图中可见

怀疑时:克隆您的列表,如:

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

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

因此,为了使
列表课程
列表不可变,您可以使用apachecollection公共库

List不可变列表=
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"); 

在内存环境中不是最好的,但可以:


//不变的学生
公共期末班学生
{ 
最后的字符串名;
最终国际注册号;
最终列表课程;//要使其不可变吗
公立学生(字符串名称、整数注册号、课程列表)
{ 
this.name=名称;
this.regNo=regNo;
this.courses=新数组列表(courses);
} 
公共字符串getName()
{ 
返回名称;
} 
public int getRegNo()
{ 
返回regNo;
} 
公开课程名单{
返回新的ArrayList(课程);
}
} 

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

设置时克隆列表。我总是把它们混在一起-所以你的问题很合理+1是的-它必须是不可修改的-不是不可修改的^ ^ ^+1
this.courses=Collections.unmodifiableList(新的ArrayList(courses))也应该足够了Hanks@GhostCat你的也在工作,但Koziolek也在工作,哪一个是更好和合适的解决方案谢谢@Koziolek你的也在工作,但GhostCat也在工作,哪一个是更好和合适的解决方案
return Collections.unmodifiableList(courses);
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");