Java 为一个分数类重新创建一个字符串池之类的东西有意义吗? 我制作了一个不可变分数类(我想是的,一切都是最终的)。我读到字符串有一个“池”,一旦“asd”被实例化,所有其他对“asd”的引用都会指向第一个。(如果我理解正确的话)那么将这个“池”重新创建为一个包含所有已创建分数的超类对我来说有意义吗。可能有一种静态工厂方法,在创建新分数之前首先检查现有分数池? var a = new Fraction(3,4); var b = a; var c = new Fraction(3,2); System.out.println(a + " " + b + " " + (a == b)); // 3/4 3/4 true b = a.add(b); System.out.println(a + " " + b + " " + (a == b)); // 3/4 3/2 false System.out.println(b + " " + c + " " + (b == c)); // 3/2 3/2 false (should be true but add() returns a new fraction)

Java 为一个分数类重新创建一个字符串池之类的东西有意义吗? 我制作了一个不可变分数类(我想是的,一切都是最终的)。我读到字符串有一个“池”,一旦“asd”被实例化,所有其他对“asd”的引用都会指向第一个。(如果我理解正确的话)那么将这个“池”重新创建为一个包含所有已创建分数的超类对我来说有意义吗。可能有一种静态工厂方法,在创建新分数之前首先检查现有分数池? var a = new Fraction(3,4); var b = a; var c = new Fraction(3,2); System.out.println(a + " " + b + " " + (a == b)); // 3/4 3/4 true b = a.add(b); System.out.println(a + " " + b + " " + (a == b)); // 3/4 3/2 false System.out.println(b + " " + c + " " + (b == c)); // 3/2 3/2 false (should be true but add() returns a new fraction),java,Java,这个想法值得做吗?即,它是否比平均实例化具有相同值的新分数更快?如果保存所有创建的分数,则内存泄漏。(请注意,String池并不包含所有创建的字符串,只包含源代码中以文本形式出现的字符串,以及您自己调用的.intern()) 有一个常用分数的缓存可能是有意义的,比如说分数(n,1)用于合理的整数范围,而分数(n,m)用于较小的范围。但您必须权衡不创建新对象所节省的成本与每次检查对象是否已在缓存中的成本;净收益充其量可能是微乎其微的,在许多实际应用程序中可能是负数,因此您需要使用一些合适的基准来测

这个想法值得做吗?即,它是否比平均实例化具有相同值的新分数更快?

如果保存所有创建的分数,则内存泄漏。(请注意,
String
池并不包含所有创建的字符串,只包含源代码中以文本形式出现的字符串,以及您自己调用的
.intern()

有一个常用分数的缓存可能是有意义的,比如说
分数(n,1)
用于合理的整数范围,而
分数(n,m)
用于较小的范围。但您必须权衡不创建新对象所节省的成本与每次检查对象是否已在缓存中的成本;净收益充其量可能是微乎其微的,在许多实际应用程序中可能是负数,因此您需要使用一些合适的基准来测试这一点


一种更简单的方法是提供一些预先制作的常量,如
分数.ZERO
分数.ONE
分数.ONE
分数.ONE\u/code>,等等。然后API的用户可以引用这些常量,而不是在每次需要使用这些公共分数时使用文本值构造新实例。这是标准库类所采用的方法:没有内置的池或缓存,但您可以编写
biginger.ZERO
biginger.ONE
biginger.TEN
,而不是实例化这些常见数字的多个副本。

这可能比它的价值要麻烦得多。对于这个简单的示例,分数,这真的不值得。您必须拥有某种快速、自适应的存储,并且可能需要测量何时从该存储中清除一些以防止内存泄漏。然后,你可能会对哪些数字特别值得保留进行统计分析,你必须对你绝对不想保留的数字范围进行估计,等等。总之,实施起来并不难,但这是一项没有重大收益的大量工作。但是,如果问题更复杂,例如递归的像斐波那契,素数,这可能确实可行是的,看起来我应该坚持我现在的想法,谢谢大家的建议!)谢谢你的回答!:)