出自《java puzzle》
作为一项热身活动,我们来测试一下你对BigInteger的了解程度。下面这个程序将打印出什么呢?
import java.math.BigInteger;
public class BigProblem {
public static void main(String[ ] args) {
BigInteger fiveThousand = new BigInteger("5000");
BigInteger fiftyThousand = new BigInteger("50000");
BigInteger fiveHundredThousand = new BigInteger("500000");
BigInteger total = BigInteger.ZERO;
total.add(fiveThousand);
total.add(fiftyThousand);
total.add(fiveHundredThousand);
System.out.println(total);
}
}
你可能会认为这个程序会打印出555000。毕竟,它将total设置为用BigInteger表示的0,然后将5,000、50,000和500,000加到了这个变量上。如果你运行该程序,你就会发现它打印的不是555000,而是0。很明显,所有这些加法对total没有产生任何影响。
对此有一个很好理由可以解释:BigInteger实例是不可变的。String、BigDecimal以及包装器类型:Integer、Long、Short、Byte、Character、Boolean、Float和Double也是如此,你不能修改它们的值。我们不能修改现有实例的值,对这些类型的操作将返回新的实例。起先,不可变类型看起来可能很不自然,但是它们具有很多胜过与其向对应的可变类型的优势。不可变类型更容易设计、实现和使用;它们出错的可能性更小,并且更加安全[EJ Item 13]。
为了在一个包含对不可变对象引用的变量上执行计算,我们需要将计算的结果赋值给该变量。这样做就会产生下面的程序,它将打印出我们所期望的555000:
import java.math.BigInteger;
public class BigProblem {
public static void main(String[] args) {
BigInteger fiveThousand = new BigInteger("5000");
BigInteger fiftyThousand = new BigInteger("50000");
BigInteger fiveHundredThousand = new BigInteger("500000");
BigInteger total = BigInteger.ZERO;
total = total.add(fiveThousand);
total = total.add(fiftyThousand);
total = total.add(fiveHundredThousand);
System.out.println(total);
}
}
本谜题的教训是:不要被误导,认为不可变类型是可变的。这是一个在刚入门的Java程序员中很常见的错误。公正地说,Java不可变类型的某些方法名促使我们走上了歧途。像add、subtract和negate之类的名字似乎是在暗示这些方法将修改它们所调用的实例。也许plus、minus和negation才是更好的名字。
对API设计来说,其教训是:在命名不可变类型的方法时,应该优选介词和名词,而不是动词。介词适用于带有参数的方法,而名词适用于不带参数的方法。对语言设计者而言,其教训与谜题2相同,那就是应该考虑对操作符重载提供有限的支持,这样算数操作符就可以作用于诸如BigInteger这样的数值型的引用类型。由此,即使是初学者也不会认为计算表达式total + fiveThousand将会对total的值产生任何影响。
分享到:
相关推荐
当前中国汽车出口存在三大问题。当前中国汽车出口存在三大问题。当前中国汽车出口存在三大问题。当前中国汽车出口存在三大问题。当前中国汽车出口存在三大问题。
锐捷交换机的堆叠,一个大问题
奥氮平使用八大问题汇总.doc
知识:人才盘点最常见的9大问题
局域网六大问题,解决方法····································
参考资料-年度目标制定与管理的20大问题.zip
AI与机器人的42个大问题91页(1).zip
寿险意义人生五大问题培训教程PPT45页PPT.ppt
全球股票策略:通胀:一个大问题2021.1.29(46页).pdf
问题主要出现在项目中需要上传视频文件,超过500M,但是报错了。 原因是tomcat限制了大小,此问题解决springBoot框架下tomcat启动 模式的文件上传大小限制。
此外,为了提高效率,还可以考虑对大问题进行分布式处理或采用近似方法。 总的来说,MATLAB结合ADMM算法解决Group Lasso问题,不仅提供了高效的求解手段,还便于理解和实现。通过不断迭代优化,我们可以找到一组...
算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业...
1.怎么让选中的item变大。 2.变大后,怎么让item全部显示出来,而不是被gridview的边缘挡住。 3.怎么每次进入gridview当前item变大。即解决setOnItemSelectedListener不响应的方法。
城市旅行商问题(Traveling Salesman Problem,简称TSP)是一个经典的组合优化问题,它询问一个旅行商如何访问n个城市,每个城市仅访问一次,并返回起点,使得总旅行距离最短。这个问题是NP完全问题,没有已知的...
在计算机科学中,分治算法是一种重要的解决问题的策略,它将一个大问题分解为若干个相同或相似的小问题,然后分别解决这些小问题,最后再将这些小问题的解组合成原问题的解。这种算法通常应用于数据结构、排序、搜索...
- 对于问题3,用IEEE 118节点系统测试优化模型,遗传算法在处理大规模问题时显示出明显优势,提供了更优的24小时机组组合计划。 4. 改进方案与讨论: - 针对模型的不足,文章提出了改进措施,这可能涉及优化编码...
分治法是一种解决复杂问题的有效策略,它将一个大问题分解成若干个小问题,然后分别解决这些小问题,最后将结果合并得到原问题的解。在大整数乘法中,分治法通过将两个大整数拆分为较小的部分,然后递归地计算这些...
为了解决这个问题,我们可以使用多线程技术。通过创建新的工作线程来执行耗时任务,主线程可以继续更新UI,保持界面的响应性。例如,我们可以在后台线程上执行数据的导入或导出,而在主线程上更新进度条或者显示提示...
分治策略则是将大问题分解成多个独立的子问题,分别解决后再合并结果。典型的应用包括归并排序、快速排序和汉诺塔问题。C语言中的递归函数能清晰地表达这类算法,但需要注意递归深度可能导致栈溢出的问题。 动态...