创建一个不可变的类
我正在尝试创建一个代表自然数的不可变类。我使用递归来处理增量和减量方法。由于这些字段是最终字段,因此我创建了一个私有构造函数,以便在递减/递增时为必要的字段分配新值。测试此实现后,我似乎无法查明问题所在。如果我递减 100,它将是 10。如果我递增 99,它将是 9。如果我递增/递减一个不在界限上的数字,我会得到一长串乱码。我想我需要朝正确的方向推动。如果它是可变的,我就能让它正常工作,因为我不必担心最终的字段。
public final class SlowBigNatural implements BigNatural{
final private int natural[];
final private int nSize;
final private int HIGHEST = 9;
public SlowBigNatural() {
this.nSize = 1;
this.natural = new int[1];
this.natural[0] = 0;
}
public SlowBigNatural(int p) {
this(Integer.toString(p));
}
public SlowBigNatural(String s) {
this.nSize = s.length();
this.natural = new int[nSize];
for (int i = 0; i < nSize; i++) {
this.natural[i] = Character.digit(s.charAt(i), 10);
}
}
public SlowBigNatural(BigNatural c) {
this(c.toString());
}
private SlowBigNatural(int[] natural, int nSize){
this.nSize = nSize - 1;
this.natural = new int[this.nSize];
for (int i = 0; i < this.nSize; i++) {
this.natural[i] = natural[i];
}
}
public BigNatural increment() {
int[] nClone = new int[nSize];
System.arraycopy(natural, 0, nClone, 0, nSize);
if (nSize == 1 || nClone[nSize - 1] != HIGHEST) {
nClone[nSize - 1]++;
BigNatural nInc = new SlowBigNatural(nClone.toString());
return nInc;
}
else {
nClone[nSize - 1] = 0;
BigNatural temp = new SlowBigNatural(nClone, nSize);
temp.increment();
return temp;
}
}
public BigNatural decrement() {
int[] nClone = natural.clone();
if (nClone[nSize - 1] != 0) {
nClone[nSize - 1]--;
BigNatural nDec = new SlowBigNatural(nClone.toString());
return nDec;
}
else {
if (nSize != 1) {
nClone[nSize - 1] = HIGHEST;
BigNatural temp = new SlowBigNatural(nClone, nSize);
temp.decrement();
return temp;
}
else{
BigNatural nDec = new SlowBigNatural(0);
return nDec;
}
}
}
public String toString() {
String nString = "";
for (int i = 0; i < nSize; i++) {
nString += String.valueOf(natural[i]);
}
return nString.replaceFirst("^0+(?!$)", "");
}
}
我单步执行了代码,当我将数组转换为字符串并将其传递给构造函数时,似乎发生了错误。它把数组变成了一堆疯狂的东西。继续调查。
I'm in the process of trying to make an immutable class in which represents natural numbers. I'm using recursion in order to handle the Increment and Decrement methods. Since the fields are final, I made a private constructor to assign new values to the necessary fields when decrementing/incrementing. After testing this implementation, I can't seem to pin point the problem. If I decrement 100, it will be 10. If I increment 99, it will be 9. If I increment/decrement a number not on the bound, I will get a long string of gibberish. I guess I need a nudge in the right direction. I'm able to get it to work fine if it's mutable because i don't have to worry about the final fields.
public final class SlowBigNatural implements BigNatural{
final private int natural[];
final private int nSize;
final private int HIGHEST = 9;
public SlowBigNatural() {
this.nSize = 1;
this.natural = new int[1];
this.natural[0] = 0;
}
public SlowBigNatural(int p) {
this(Integer.toString(p));
}
public SlowBigNatural(String s) {
this.nSize = s.length();
this.natural = new int[nSize];
for (int i = 0; i < nSize; i++) {
this.natural[i] = Character.digit(s.charAt(i), 10);
}
}
public SlowBigNatural(BigNatural c) {
this(c.toString());
}
private SlowBigNatural(int[] natural, int nSize){
this.nSize = nSize - 1;
this.natural = new int[this.nSize];
for (int i = 0; i < this.nSize; i++) {
this.natural[i] = natural[i];
}
}
public BigNatural increment() {
int[] nClone = new int[nSize];
System.arraycopy(natural, 0, nClone, 0, nSize);
if (nSize == 1 || nClone[nSize - 1] != HIGHEST) {
nClone[nSize - 1]++;
BigNatural nInc = new SlowBigNatural(nClone.toString());
return nInc;
}
else {
nClone[nSize - 1] = 0;
BigNatural temp = new SlowBigNatural(nClone, nSize);
temp.increment();
return temp;
}
}
public BigNatural decrement() {
int[] nClone = natural.clone();
if (nClone[nSize - 1] != 0) {
nClone[nSize - 1]--;
BigNatural nDec = new SlowBigNatural(nClone.toString());
return nDec;
}
else {
if (nSize != 1) {
nClone[nSize - 1] = HIGHEST;
BigNatural temp = new SlowBigNatural(nClone, nSize);
temp.decrement();
return temp;
}
else{
BigNatural nDec = new SlowBigNatural(0);
return nDec;
}
}
}
public String toString() {
String nString = "";
for (int i = 0; i < nSize; i++) {
nString += String.valueOf(natural[i]);
}
return nString.replaceFirst("^0+(?!$)", "");
}
}
I stepped through my code, and the error seems to occur when I convert the array to a string and pass it through the constructor. It turns the array into a bunch of craziness. Continuing to investigate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
还没有完全研究它,但如果 SlowBigNatural 确实是正确的不可变的,那么
据我所知,以下内容不太可能有用。上面对 temp.increment() 的调用创建了一个您忽略的新对象,看到您返回 temp 本身,而不是 temp.increment() 的结果。
您可以尝试将上面的内容更改为:
如果有效,请对 decrement() 执行相同的操作。
Haven't fully looked into it but if SlowBigNatural is really correctly immutable, then the following:
is unlikely to be useful as far as I can see. The above call to temp.increment() creates a new object that you ignore, seen that you return temp itself and not the result of temp.increment().
Could you try changing the above to this:
And if works, do the same for decrement().