Recently I felt the need to write a Mutable<T>
class so that I can pass immutable objects through methods, whose value can then be changed. Some examples of immutable classes (including primitive types):
int
long
short
byte
double
float
String
(though already has aStringBuilder
classBigInteger
and others.
There is a lot of repetition in the classes, especially the primitive number types. I am sure there is a way around the repetition, but I couldn't figure out how.
Mutable.java
It's quite simple, right?
public class Mutable<T> {
protected T value;
public Mutable(T value) {
setValue(value);
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
I also added some extra primitive number support, so that:
Mutable<Integer> i = new Mutable<>(10);
i.setValue(i.getValue() + 10);
becomes:
MutableInteger i = new MutableInteger(10);
i.add(10);
The interface:
MutableNumber.java
public interface MutableNumber<T extends Number> {
public abstract void add(T number);
public abstract T addAndGet(T number);
public abstract void sustract(T number);
public abstract T sustractAndGet(T number);
public abstract void multiply(T number);
public abstract T multiplyAndGet(T number);
public abstract void divide(T number);
public abstract T divideAndGet(T number);
}
Now the repetitive part:
MutableInteger.java
public class MutableInteger extends Mutable<Integer> implements
MutableNumber<Integer> {
public MutableInteger(Integer value) {
super(value);
}
public void increment() {
value++;
}
public int incrementAndGet() {
return ++value;
}
public void decrement() {
value--;
}
public int decrementAndGet() {
return --value;
}
@Override
public void add(Integer number) {
value += number;
}
@Override
public Integer addAndGet(Integer number) {
value += number;
return value;
}
@Override
public void sustract(Integer number) {
value -= number;
}
@Override
public Integer sustractAndGet(Integer number) {
value -= number;
return value;
}
@Override
public void multiply(Integer number) {
value *= number;
}
@Override
public Integer multiplyAndGet(Integer number) {
value *= number;
return value;
}
@Override
public void divide(Integer number) {
value /= number;
}
@Override
public Integer divideAndGet(Integer number) {
value /= number;
return value;
}
}
MutableLong.java
public class MutableLong extends Mutable<Long> implements MutableNumber<Long> {
public MutableLong(Long value) {
super(value);
}
@Override
public void add(Long number) {
value += number;
}
@Override
public Long addAndGet(Long number) {
value += number;
return value;
}
@Override
public void sustract(Long number) {
value -= number;
}
@Override
public Long sustractAndGet(Long number) {
value -= number;
return value;
}
@Override
public void multiply(Long number) {
value *= number;
}
@Override
public Long multiplyAndGet(Long number) {
value *= number;
return value;
}
@Override
public void divide(Long number) {
value /= number;
}
@Override
public Long divideAndGet(Long number) {
value /= number;
return value;
}
}
MutableDouble.java
public class MutableDouble extends Mutable<Double> implements
MutableNumber<Double> {
public MutableDouble(Double value) {
super(value);
}
@Override
public void add(Double number) {
value += number;
}
@Override
public Double addAndGet(Double number) {
value += number;
return value;
}
@Override
public void sustract(Double number) {
value -= number;
}
@Override
public Double sustractAndGet(Double number) {
value -= number;
return value;
}
@Override
public void multiply(Double number) {
value *= number;
}
@Override
public Double multiplyAndGet(Double number) {
value *= number;
return value;
}
@Override
public void divide(Double number) {
value /= number;
}
@Override
public Double divideAndGet(Double number) {
value /= number;
return value;
}
}
MutableFloat.java
public class MutableFloat extends Mutable<Float> implements
MutableNumber<Float> {
public MutableFloat(Float value) {
super(value);
}
@Override
public void add(Float number) {
value += number;
}
@Override
public Float addAndGet(Float number) {
value += number;
return value;
}
@Override
public void sustract(Float number) {
value -= number;
}
@Override
public Float sustractAndGet(Float number) {
value -= number;
return value;
}
@Override
public void multiply(Float number) {
value *= number;
}
@Override
public Float multiplyAndGet(Float number) {
value *= number;
return value;
}
@Override
public void divide(Float number) {
value /= number;
}
@Override
public Float divideAndGet(Float number) {
value /= number;
return value;
}
}
Concerns:
- Is there a way to remove all the repetition?
- Is my class structure good?
And as usual, anything else is welcome.
Number
-based class. – h.j.k. Nov 18 '15 at 1:24Mutable<T>
class so that I can pass immutable objects"... does not compute? – h.j.k. Nov 18 '15 at 1:25incrementAndGet
doesn't that make theMutable<T>
(partially) immutable? Why not justincrement
and then change the internal state? Other than that, I have never felt the need for making value types mutable. Ask yourself again, what is the real problem you are trying to solve? – Roy T. Nov 18 '15 at 7:52