如何使用 class 中的 List<String> 元素创建不可变 Class
How to Create Immutable Class with List<String> Element in class
不可变 Class 与列表
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;
}
}
测试不可变 Class 以打破不可变性
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]
为什么以及如何将这个新的课程元素从客户端添加到列表中,因为它可以随时添加,所以我们如何解决这个问题,因为这个不可变的 class 应该不允许在创建后进行修改
阅读about immutableLists,您会发现不可变和不可修改是不一样的。
我猜(根据你的问题)你期待一个你根本不创建的不可修改的列表...
请参阅 this answer 以获得正确的解决方案
this.courses = Collections.unmodifiableList(courses);
顾名思义,这会创建一个 不可修改的 列表。但这只是原始列表中的视图。因此,对 原始 列表的更改将在您的 "unmodifiable" 视图中可见。
如有疑问:克隆您的列表,例如:
this.courses = new ArrayList<>(courses);
然后确保您的 getter 确实:
return Collections.unmodifiableList(courses);
使用 Collections.unmodifiableList
,它会在原始列表周围创建一个包装器,并且该包装器对象是不可修改的。原榜单还可以继续更新
因此,为了使 List<String> 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");
在记忆方面不是最好的,但有效:
// 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 中)创建副本。
不可变 Class 与列表
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;
}
}
测试不可变 Class 以打破不可变性
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]
为什么以及如何将这个新的课程元素从客户端添加到列表中,因为它可以随时添加,所以我们如何解决这个问题,因为这个不可变的 class 应该不允许在创建后进行修改
阅读about immutableLists,您会发现不可变和不可修改是不一样的。
我猜(根据你的问题)你期待一个你根本不创建的不可修改的列表...
请参阅 this answer 以获得正确的解决方案
this.courses = Collections.unmodifiableList(courses);
顾名思义,这会创建一个 不可修改的 列表。但这只是原始列表中的视图。因此,对 原始 列表的更改将在您的 "unmodifiable" 视图中可见。
如有疑问:克隆您的列表,例如:
this.courses = new ArrayList<>(courses);
然后确保您的 getter 确实:
return Collections.unmodifiableList(courses);
使用 Collections.unmodifiableList
,它会在原始列表周围创建一个包装器,并且该包装器对象是不可修改的。原榜单还可以继续更新
因此,为了使 List<String> 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");
在记忆方面不是最好的,但有效:
// 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 中)创建副本。