I have three similar classes for different types.
public class IntClass {
private int p1; private int p2;
IntClass(int p1, int p2) { this.p1=p1; this.p2=p2; }
int getP1() { return p1; }
int getP2() { return p2; }
}
public class DoubleClass {
private double p1; private double p2;
DoubleClass(double p1, double p2) { this.p1=p1; this.p2=p2; }
double getP1() { return p1; }
double getP2() { return p2; }
}
public class StringClass {
private String p1; private String p2;
StringClass(String p1, String p2) { this.p1=p1; this.p2=p2; }
String getP1() { return p1; }
String getP2() { return p2; }
}
public class C4 {
...
private IntClass c1;
private DoubleClass c2;
private StringClass c3;
...
IntClass getIntClass() { return C1; }
DoubleClass getDoubleClass() { return C2; }
StringClass getStringClass() { return C3; }
...
}
Somewhere else in codebase, I have following snippet of code with 3 similar methods.
...
int a = getInt(C4::getIntClass, boolValue);
double b = getDouble(C4::getDoubleClass, boolValue);
String c = getString(C4::getStringClass, boolValue);
...
private int getInt(Supplier<IntClass> executable, boolean boolValue) {
...
return boolValue? executable.get().getP1(): executable.get().getP2();
}
private double getDouble(Supplier<DoubleClass> executable, boolean boolValue) {
...
return boolValue? executable.get().getP1(): executable.get().getP2();
}
private String getString(Supplier<StringClass> executable, boolean boolValue) {
...
return boolValue? executable.get().getP1(): executable.get().getP2();
}
I wanted to write a generic method getValue
in replacement of getInt
,getDouble
,getString
. How can we do so?
Edit:- Cant make generic Class for IntClass
, DoubleClass
, StringClass
as they serve some other usecase as well and are in different package library. Just wanted to refactor code at my end by writing a common generic method and removing similar redundant code. Just a thought!! Any suggestions specific to usecase would be appreciated.
CodePudding user response:
@Test
public void test() {
PairOf<String> pairOfStr = new PairOf<>("abc", "def");
PairOf<Integer> pairOfInt = new PairOf<>(1, 2);
PairOf<Double> pairOfDouble = new PairOf<>(1.0, 2.0);
Assertions.assertEquals(pairOfStr.getFirst(), getValue(pairOfStr, true));
Assertions.assertEquals(pairOfInt.getFirst(), getValue(pairOfInt, true));
Assertions.assertEquals(pairOfDouble.getFirst(), getValue(pairOfDouble, true));
}
public class PairOf<T> {
private T first;
private T second;
public PairOf(T first, T second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
}
public <T> T getValue(PairOf<T> t, boolean first) {
return first ? t.getFirst() : t.getSecond();
}
With number, you can cast to primitive by method:
getValue(pairOfInt, true).intValue();
getValue(pairOfDouble, true).doubleValue();
CodePudding user response:
Try this:
public class GenericClass<T> {
private T p1;
private T p2;
GenericClass(T p1, T p2) {
this.p1=p1;
this.p2=p2;
}
T getP1() { return p1; }
T getP2() { return p2; }
}
private T getValue(Supplier<GenericClass<T>> executable, boolean boolValue) {
return boolValue ? executable.get().getP1(): executable.get().getP2();
}
CodePudding user response:
Well you need to start with a generic class and do something like:
public class PairOf<T> {
private T first;
private T second;
public PairOf(T first, T second) {
this.first = first;
this.second = second;
}
public T getFirst() { return first; }
public T getSecond() { return second; }
}
Then you can use this class in place of your specific classes exactly as before.