如何设计一个包含java.lang.String的不可变值类? 客观的
创建一个类,用作对象的不可变列表 方法 我决定利用的集合,而不是用包装一个简单的,因为我知道这样可以避免对后台进行不必要的并发检查,而后台不知道被包装(来源:) 要求如何设计一个包含java.lang.String的不可变值类? 客观的,java,guava,immutability,Java,Guava,Immutability,创建一个类,用作对象的不可变列表 方法 我决定利用的集合,而不是用包装一个简单的,因为我知道这样可以避免对后台进行不必要的并发检查,而后台不知道被包装(来源:) 要求 类可以是跨线程使用的“值持有者” 创建后不允许任何代码更改内部值 很高兴拥有 类应该实现,以便按照创建顺序对值进行迭代 一组给定的应该只有一个类 尝试 这里有一些尝试,尽管可能有更多的组合。原谅这个幽默的表演 尝试#1(包括用法示例) import java.util.List; 导入com.google.common.c
- 类可以是跨线程使用的“值持有者”
- 创建后不允许任何代码更改内部值
- 类应该实现,以便按照创建顺序对值进行迭代
- 一组给定的应该只有一个类
import java.util.List;
导入com.google.common.collect.ImmutableList;
类BritnetPearsPellings实现了Iterable{
公共静态拼写(字符串…拼写){
BritnetsPearsPellings BritneyPears=新的BritnetsPearsPellings();
britneySpears.spellings=不可变列表.copyOf(拼写);
返回英国梨;
}
私人名单拼写;
英国私人会计师事务所{
}
公共列表getSpellings(){
返回拼写;
}
}
@凌驾
公共迭代器迭代器(){
返回拼写。迭代器();
}
公共类用法{
公共静态void main(字符串[]args){
例如(String sepllin:BritnetSpearsSpellings.of(“布列塔尼·斯皮尔斯”、“布列特尼·斯皮尔斯”、“布列塔尼·斯皮尔斯”))
System.out.printf(“您喜欢这样说:%s%n”,sepllin);
}
}
}
尝试#2
类BritnetSpearsPellings实现了Iterable{
公共静态拼写(字符串…拼写){
BritnetsPearsPellings BritneyPears=新的BritnetsPearsPellings();
britneySpears.spellings=不可变列表.copyOf(拼写);
返回英国梨;
}
私有不可变列表拼写;
英国私人会计师事务所{
}
公共不可变列表getSpellings(){
返回拼写;
}
@凌驾
公共迭代器迭代器(){
返回拼写。迭代器();
}
}
尝试#3
类BritnetSpearsPellings实现了Iterable{
公共静态拼写(字符串…拼写){
BritnetsPearsPellings britneySpears=新的BritnetsPearsPellings(ImmutableList.copyOf(拼写));
返回英国梨;
}
私有最终不可变列表拼写;
私有BritnetSpearsSpellings(不可变列表拼写){
this.spellings=拼写;
}
公共不可变列表getSpellings(){
返回拼写;
}
@凌驾
公共迭代器迭代器(){
返回拼写。迭代器();
}
}
差异摘要
- 1将保存在公共接口中,在JavaDoc中记录不变性。
- 2将所有内容存储和公开为
- 3以创建专门构造函数为代价,将内部引用保持为最终引用,在没有其他初始化选项的情况下,可能会使静态工厂方法初始化看起来很愚蠢(在实际类中实际存在)
尝试#2
而不是尝试#1
,因为它记录了您总是返回不可变列表实例。通常,选择尽可能具体的返回类型和尽可能一般的参数类型是很有用的。但对于这两种情况,我们更喜欢接口而不是具体的类
嗯,ImmutableList
是一个抽象类,而不是一个接口。但由于它的性质,它的行为非常像一个接口
当类成员引用拼写在对象的生命周期内无法更改,并且/或者您希望使整个类本身不可变时,trunt#3
是有意义的。否则,当拼写
可以在对象生存期内分配给另一个不可变列表时,它就没有意义了
考虑到您示例中的用例,我倾向于说#3是最佳选择。显然,我认为#3是最佳选择final
强制并记录类(该字段)的不可变性,而不仅仅是列表本身是不可变的
无论是在getter中使用一些javadoc公开一个列表
,还是实际的不可变列表
,都是另一回事。我看到过这样的观点,返回一个不可变列表
清楚地记录了意图,但是,您仍然将自己绑定到一个实现上,而不是一个接口,用于一些低级别的东西,并且将来可能需要更改(即使不可变性“通常”是好的)。因此,对于您的应用程序来说,它更像是一种全局设计选择,而不仅仅是一个用例。如果您确实使用了ImmutableList
,我认为这对客户端来说不是一个真正的问题,名称是明确的,并且可以通过您的IDE轻松地看到它是List
的实现,如果他们需要更多信息,他们可以访问javadoc。谁知道呢,他们可能会喜欢它,并开始使用它,加上番石榴提供的所有其他好吃的东西:-)从你的问题陈述(“一组给定的字符串应该只有一个类”),听起来你真正想要的是一个Interner
- 是一个实用程序(使用
Interners.newStrongInterner()
构造一个),用于确保只有一个对象实例和任何给定数据
- 正确答案是c吗
import java.util.List;
import com.google.common.collect.ImmutableList;
class BritnetSpearsSpellings implements Iterable<String> {
public static BritnetSpearsSpellings of(String... spellings) {
BritnetSpearsSpellings britneySpears = new BritnetSpearsSpellings();
britneySpears.spellings = ImmutableList.copyOf(spellings);
return britneySpears;
}
private List<String> spellings;
private BritnetSpearsSpellings() {
}
public List<String> getSpellings() {
return spellings;
}
}
@Override
public Iterator<String> iterator() {
return spellings.iterator();
}
public class Usage {
public static void main(String[] args) {
for (String sepllin : BritnetSpearsSpellings.of("Brittany Spears", "Brittney Spears", "Britany Spears"))
System.out.printf("You spel Britni like so: %s%n", sepllin);
}
}
}
class BritnetSpearsSpellings implements Iterable<String> {
public static BritnetSpearsSpellings of(String... spellings) {
BritnetSpearsSpellings britneySpears = new BritnetSpearsSpellings();
britneySpears.spellings = ImmutableList.copyOf(spellings);
return britneySpears;
}
private ImmutableList<String> spellings;
private BritnetSpearsSpellings() {
}
public ImmutableList<String> getSpellings() {
return spellings;
}
@Override
public Iterator<String> iterator() {
return spellings.iterator();
}
}
class BritnetSpearsSpellings implements Iterable<String> {
public static BritnetSpearsSpellings of(String... spellings) {
BritnetSpearsSpellings britneySpears = new BritnetSpearsSpellings(ImmutableList.copyOf(spellings));
return britneySpears;
}
private final ImmutableList<String> spellings;
private BritnetSpearsSpellings(ImmutableList<String> spellings) {
this.spellings = spellings;
}
public ImmutableList<String> getSpellings() {
return spellings;
}
@Override
public Iterator<String> iterator() {
return spellings.iterator();
}
}