gpt4 book ai didi

java - 将具有两个字段的类和具有单个参数的构造函数重写为记录类

转载 作者:行者123 更新时间:2023-12-05 01:03:55 27 4
gpt4 key购买 nike

我想知道如何重写这个类

public class ClassA {
private final String foo;
private final String bar;

public ClassA(String foo) {
this.foo = foo;
this.bar = foo.toUpperCase();
}

// getters...
}

作为记录类。
我能做到的最好的就是这个

public record ClassA(String foo, String bar) {
public ClassA(String foo) {
this(foo, foo.toUpperCase());
}
}

问题是这个解决方案创建了两个构造函数,而我只想要一个接受字符串 foo 的构造函数

最佳答案

这更像是对 https://stackoverflow.com/a/73137529/3553087 的回应比任何关于如何做到这一点的建议。引用的答案比 OP 的版本要好,但它仍然在颠覆记录的精神,即它们是 名义元组,可能带有一些限制组件的不变量。

下面是一个很好地使用不变量记录的例子:

record Range(int low, int hi) { 
public Range {
if (low > hi) throw new IllegalArgumentException();
}
}

规范的构造函数验证参数,拒绝无效的参数,然后,整个事情就像一个透明的、不可变的容器一样用于某些元组,派生出有用的 API(构造函数、解构模式(从 Java 19 开始)、访问器、equals , hashCode, toString) 来自元组。

这里的等价物是老实说,承认你正在写的是一个任意字符串的元组,以及它的大写版本:

record StringWithCachedUppercase(String value, String uppercased) { 
public StringWithCachedUppercase {
if (!uppercased.equals(value.toUpperCase(Local.ROOT)))
throw new IllegalArgumentException();
}

public StringWithCachedUppercase(String value) {
this(value, value.toUpperCase(Locale.ROOT));
}
}

为什么链接的答案不太受欢迎?因为规范的构造函数拉得很快,并且破坏了 new XyRecord(x, y).y() 应该返回与传递给构造函数。也许它是一个标准化版本,但它应该是可识别的——在链接的答案中,它被完全忽略了。

有些人可能会犹豫“但是你计算了两次大写版本”,但这不是使用错误机制的借口。 (而且,由于这种事情的全部理由是“我想缓存这个看似昂贵的计算”,所以使用它的唯一一点是如果你要多次请求大写版本。在这种情况下,O(1) 的额外 build 成本无关紧要。)

此示例说明记录是“几乎”的常见情况,即“元组,但缓存派生数量”。我们在设计记录的过程中对这个案例进行了很长时间的考虑,但最终得出的结论是,它应该保留在记录设计中心之外。

如果您真的对缓存派生量感兴趣,那么它们可以被延迟计算并缓存在 WHM 中:

record StringWrapper(String s) { 
static Map<StringWrapper, String> uppers = Collections.synchronizedMap(new WeakHashMap<>());

public String uppercase() {
return uppers.computeIfAbsent(this, r -> r.s.toUpperCase(Locale.ROOT));
}
}

关于java - 将具有两个字段的类和具有单个参数的构造函数重写为记录类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73135962/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com