public abstract class OuterClass<OT extends OuterClass<OT>> {
public <C extends OuterClass<?>> C parse(Class<C> clazz) {
if (clazz.isInstance(this)) {
return (C) this;
}
return null;
}
public abstract class InnerClass<CT extends InnerClass<CT> {
public <C extends InnerClass<?>> C parse(Class<C> clazz) {
if (clazz.isInstance(this)) {
return (C) this;
}
return null;
}
}
}
OuterClass<?> oInstance;
InnerClass<?> iInstance;
In the above example the iInstance variable works fine. However the iInstance variable shows an error when adding the generics part
Type arguments given on a raw type
If I remove the generics part from variables, then the below test cases will fail with type errors
public class ExtendedOuter extends OuterClass<ExtendedOuter> {
}
// This only works on OuterClass<?> and not on OuterClass
ExtendedOuter eInstance = oInstance.parse(ExtendedOuter.class);
Found: OuterClass, required: ExtendedOuter
This is no problem on static/outer classes as they can be defined as ClassName<?>, but non-static inner classes cannot be defined with <?>
How can I add <?> to iInstance without making InnerClass static?
EDIT:
Let me give some examples why these classes uses their extended versions as generic.
public abstract class OuterClass<OT extends OuterClass<OT>> {
public abstract OT returnMe();
}
public class ExtendedOuter extends OuterClass<ExtendedOuter> {
#Override
public ExtendedOuter returnMe() {
return this;
}
}
The above for an example would not work if I simply made the return type OuterClass on the abstract version. If so, any extended versions would have to be casted whenever this method was used, which does not seam ideal.
Also just got an error from AndroidStudio as well after removing <CT> in <T extends OuterClass<CT>>
The parameter OT is not within it's bound
This error is shown in extended classes when doing ClassName extends OuterClass<ClassName>. In other words it will not work just using <T extends OuterClass> on the abstract classes.
Similar to a previous post I did which showcased a builder patter which uses generic types and inheritance to reduce the actual code in inheritance cases, this is also possible for none-static classes. I therefore modified the builder example accordingly to avoid static inner-classes:
Parent class with parent builder:
public abstract class TestParam<Z>
{
public abstract class CommonBuilder<T extends CommonBuilder<T>>
{
protected final String a;
protected final String b;
protected final String c;
protected Z z = null;
public CommonBuilder(String a, String b, String c)
{
this.a = a;
this.b = b;
this.c = c;
}
#SuppressWarnings("unchecked")
public T withOptionalZ(Z z)
{
this.z = z;
return (T)this;
}
#SuppressWarnings("hiding")
public abstract <T> T build();
}
protected String name;
protected String a;
protected String b;
protected String c;
protected Z z = null;
protected TestParam() {
}
protected TestParam(String name, String a, String b, String c)
{
this.name = name;
this.a = a;
this.b = b;
this.c = c;
}
protected TestParam(String name, String a, String b, String c, Z z)
{
this.name = name;
this.a = a;
this.b = b;
this.c = c;
this.z = z;
}
public String getA()
{
return a;
}
public String getB()
{
return b;
}
public String getC()
{
return c;
}
protected abstract String getContent();
#Override
public String toString()
{
return name+"[A: " + a + ", B: " + b + ", C: " + c + (z != null ? ", Z: " + z.toString() : "") + getContent() +"]";
}
}
A child class with a none-static builder looks like this:
#SuppressWarnings({"hiding", "unchecked"})
public class TestParamA<D,E,Z> extends TestParam<Z>
{
public class Builder<T extends TestParamA<D,E,Z>,
B extends TestParamA<D,E,Z>.Builder<? extends TestParamA<D,E,Z>, ? extends B, D, E>,
D,E>
extends TestParam<Z>.CommonBuilder<Builder<TestParamA<D,E,Z>,B, D,E>>
{
protected D d;
protected E e;
public Builder(String a, String b, String c)
{
super(a, b, c);
}
public B withD(D d)
{
this.d = d;
return (B)this;
}
public B withE(E e)
{
this.e = e;
return (B)this;
}
#Override
public <T> T build()
{
TestParamA<D,E,Z> t = new TestParamA<>("TestParamA", a, b, c, z, d, e);
return (T)t;
}
}
protected D d;
protected E e;
public TestParamA() {
super();
}
protected TestParamA(String name, String a, String b, String c, Z z, D d, E e)
{
super(name, a, b, c, z);
this.d = d;
this.e = e;
}
public D getD()
{
return d;
}
public E getE()
{
return e;
}
#Override
protected String getContent()
{
return ", D: " + d + ", E: " + e;
}
}
To test the functionality of this outer/inner classes you can implement something like this:
public class Main
{
public static void main(String ... args)
{
TestParamA<D,E,String> a = new TestParamA<>().new Builder<>("a","b","c").withD(new D()).withE(new E()).build();
TestParamB<F,G,String> b = new TestParamB<>().new Builder<>("a","b","c").withF(new F()).withG(new G()).withOptionalZ("z").build();
TestParam<String> c = new TestParamA<>().new Builder<>("a","b","c").withD(new D()).withE(new E()).withOptionalZ("z").build();
TestParam<?> d = new TestParamB<>().new Builder<>("a","b","c").withF(new F()).withG(new G()).build();
test(a);
test(b);
test(c);
test(d);
TestParam<?>.CommonBuilder<? extends TestParam<?>.CommonBuilder<?>> builder =
new TestParamA<>().new Builder<>("a", "b", "c").withD(new D()).withE(new E());
test(builder);
// or a bit shorter
TestParam<?>.CommonBuilder<?> builder2 =
new TestParamB<>().new Builder<>("a", "b", "c").withF(new F()).withG(new G());
test(builder2);
}
public static void test(TestParamA<?,?,?> testParam)
{
System.out.println("Test for ParamA: " + testParam.toString());
}
public static void test(TestParamB<?,?,?> testParam)
{
System.out.println("Test for ParamB: " + testParam.toString());
}
public static void test(TestParam<?> testParam)
{
System.out.println("Test for Param: " + testParam.toString());
}
public static void test(TestParam<?>.CommonBuilder<?> builder)
{
System.out.println("Test for CommonBuilder: " + builder.build().toString());
}
}
TestParamB is identical to TestParamA - it only contains varialbe and builder-methods for F and G instead of D and E. Furthermore, D, E, F and G are only classes with a simple toString() implementation which returns just the simple classname.
This will print the following output:
Test for ParamA: TestParamA[A: a, B: b, C: c, D: D, E: E]
Test for ParamB: TestParamB[A: a, B: b, C: c, Z: z, F: F, G: G]
Test for Param: TestParamA[A: a, B: b, C: c, Z: z, D: D, E: E]
Test for Param: TestParamB[A: a, B: b, C: c, F: F, G: G]
Test for CommonBuilder: TestParamA[A: a, B: b, C: c, D: D, E: E]
Test for CommonBuilder: TestParamB[A: a, B: b, C: c, F: F, G: G]
However the iInstance variable shows an error when adding the generics
part
Type arguments given on a raw type
First of all, that's not the problem you should be getting, because InnerClass is not defined in the scope. Being an inner class, it is scoped inside the outer class's scope. So when it is outside the outer class, you need to explicitly qualify it with an outer class, or it will give you a InnerClass symbol not found error. So you are not showing your real code (maybe you have another InnerClass somewhere) or not show your real error.
If I remove the generics part from variables, then the below test
cases will fail with type errors
When you use a raw type to access members, that turns off all generics on those members. So .parse() is erased to public OuterClass parse(Class clazz) (this is true even though CT is not used by the method), and that's why oInstance.parse(ExtendedOuter.class) returns type OuterClass which is not compatible with ExtendedOuter.
How can I add <?> to iInstance without making InnerClass static?
Like OuterClass<?>.InnerClass<?>, or OuterClass<Something>.InnerClass<SomethingElse>
Related
I have 3 objects (let them be object a of class A, object b of class B and object c of class C) and I need to combine them to a single instance of java.lang.Object (let it be o). So in the end object o will contain inside it the three objects mentioned above. Any ideas on how this one can be achieved?
Do you mean something like this?
public class Triplet<A, B, C> {
private final A a;
private final B b;
private final C c;
Triplet(A a, B b, C c){
this.a = a;
this.b = b;
this.c = c;
}
}
public class MyClassA {}
public class MyClassB {}
public class MyClassC {}
public class Main {
public static void main(String[] args){
Object o = new Triplet<>(new MyClassA(), new MyClassB(), new MyClassC());
}
}
For getter , no issues you can return the current array
for setter , you can use the Collections algorithm addAll for exemple :
String[] values = { "cat", "dog", "bird" };
setArray(values);
public void setArray(String[] sourceArray){
ArrayList<String> list = new ArrayList<>();
list.add("elephant");
Collections.addAll(list, values);
}
I have a base class with a method called execute :
class A {
public execute(int a){}
}
I also have a class B, which extends A, but the execute method needs more parameters:
Currently, my solution is using optional parameters :
class B extends A {
public execute(int a, Object... parameters){
long b = (long)parameters[0];
boolean c = (boolean)parameters[1];
....
}
}
This would still be ugly because I must cast on parameters. Are there other options for this situation?
you can add an execute(int a, int b) in B, but it won't override the execute(int a) method, it will overload it. Both method will be callable on an instance of B.
This would break the OO paradigm. The L in solid stands for Liskov substitution principle.
The principle applied for you example is that B should behave as A.
A better solution would be to injects those parameters via the constructor and have an execute without any parameters.
class A {
int a;
public A(int a){
this.a = a;
}
public execute(){ // do something with a}
}
class B {
int a;
long b;
boolean c;
public B (int a, long b, boolean c) {
this.a = a;
this.b = b;
this.c = c;
}
public execute(){ // do something with a, b and c}
}
I'd like to be able to do this:
public class ConcreteA<B extends AbstractC<D>> {
public D getD() {...}
}
or even:
public class ConcreteA<B extends AbstractC<?>> {
public <D> D getD() {return cInst.dRelatedMethod();}
}
But it seems I have to do this:
public class ConcreteA<D, AbstractB extends C<D>> {
public D getD() {...}
}
Which gets messy if D has its own type parameters. Is there any way to get this type inference working the way I'd like? Does the Java Community Process have improved type inference in the works?
Eligible answers:
1) A type inference solution exists that gives me what I want without resorting to the solution in block #3
2) A reference to any JSR that seeks to improve type inference in an applicable fashion
3) A refutation of the validity of the concept
4) An authoritative declaration that such a JSR does not exist
Sure! For example the following code compiles (although I don't have any idea why the hell someone would need such a strange construction):
public class ConcreteA<B extends AbstractC<D>> {
AbstractC<D> c;
ConcreteA(B b) {
c = b;
}
public D getD() {
return c.getE();
}
}
class AbstractC<E> {
E e;
AbstractC(E e) {
this.e = e;
}
E getE() { return e; };
}
class D {
}
Note that according to your class definition, ConcreteA, AbstractC and D (!) are classes while B is just a template parameter. Don't mix this up!
If you want to have D as template parameter too, you must explicitely specify this in the class header of ConcreteA:
public class ConcreteA<B extends AbstractC<D>, D> {
AbstractC<D> c;
ConcreteA(B b) {
c = b;
}
public D getD() {
return c.getE();
}
}
class AbstractC<E> {
E e;
AbstractC(E e) {
this.e = e;
}
E getE() { return e; };
}
Now, B and D (and E) are template parameters.
The commonest technique to achieve nearly what you are looking from is to pass the Class<T> of the class you are wanting as a parameter.
Here's an example but it does not stop with newInstance. You can use T as normal anywhere inside the getT method.
public class A<B extends Set<String>> {
final B b;
public A(B b) {
this.b = b;
}
// Hard-coded - not the best.
public String getString () {
return "";
}
// Internally stored so type is retained.
public B getB () {
return b;
}
// Inferred from a parameter passed as a Class<T>.
public <T> T getT(Class<T> clazz) throws InstantiationException, IllegalAccessException {
return clazz.newInstance();
}
}
I've got two methods with the same list and types of arguments and almost the same body but each of them calls another function to fetch list of elements. To be more precise:
public void method1 (int a, int b) {
//body (the same in both of methods)
List<SomeObject> list = service.getListA(int c, int d);
//rest of the body (the same in both of methods)
}
public void method2 (int a, int b) {
//body (the same in both of methods)
List<SomeObject> list = service.getListB(int c, int d, int e);
//rest of the body (the same in both of methods)
}
What is the best approach to the problem avoiding code duplication in that case? I thought about Strategy pattern, but there is a problem with difference in argument list.
UPDATE:
public void method1 (int a, int b) {
//body (the same in both of methods)
int c = some_value;
List<SomeObject> list = service.getListA(a, b, c);
//rest of the body (the same in both of methods)
}
public void method2 (int a, int b) {
//body (the same in both of methods)
int c = some_value;
int d = another_value;
List<SomeObject> list = service.getListB(a, b, c, d);
//rest of the body (the same in both of methods)
}
So some variables are local and some are passed through arguments.
Factor them out into additional methods.
public void method1 (int a, int b) {
MyClass myClass = method3(a, b);
List<SomeObject> list = service.getListA(myClass.getC(), myClass.getD());
method4(list);
}
public void method2 (int a, int b) {
MyClass myClass = method3(a, b);
List<SomeObject> list = service.getListB(myClass.getC(), myClass.getD(), myClass.getE());
method4(list);
}
public MyClass {
private final int c;
private final int d;
private final int e;
...
}
public MyClass method3(int a, int b) {
// body
return new MyClass(c, d, e)
}
public void method4(List<SomeObject> list) {
// rest of body
}
One way of avoiding code duplication in your case could be to introduce an extra parameter that is used to decide which method to retrieve the list is going to be used:
public void method (int a, int b, int method) {
//body (the same in both of methods)
List<SomeObject> list = null;
switch (method) {
case 1:
list = service.getListA(int c, int d);
break;
case 2:
list = service.getListB(int c, int d, int e);
break;
}
//rest of the body (the same in both of methods)
}
instead of using int method as the additional parameter I would use an new enum type and define a default case in the switch statement.
Encapsulate the invocation of service.getListA or service.getListB in an ListSource class/interface, implement each version in concrete classes and pass a concrete instance as a third argument. This is basically the object-oriented version of the answer proposed by jlordo.
interface ListSource {
List<SomeObject> getList(int c, int d, int e);
}
class ListSourceA implements ListSource {
// constructor etc.
#Override
public getList(int c, int d, int e) {
return service.getListB(c, d);
}
}
class ListSourceB implements ListSource {
// constructor etc.
#Override
public getList(int c, int d, int e) {
return service.getListA(c, d, e);
}
}
public void method (int a, int b, ListSource source) {
//body (the same in both of methods)
List<SomeObject> list = source.getList(int c, int d, int e);
//rest of the body (the same in both of methods)
}
public void method (int a, int b, List<SomeObject> theList) {
//body (the same in both of methods)
List<SomeObject> list = theList;
//rest of the body (the same in both of methods)
}
This to me removes ALL the code duplication, means the method NEVER has to be modified each time we want to operate on a list derived using a different method signature.
I believe you could further this if the type SomeObject is not known using generics i.e. (and I am not a java programmer so you will have to read the docs)
public void method (int a, int b, List<T> theList) {
//body (the same in both of methods)
List<T> list = theList;
//rest of the body (the same in both of methods)
}
You could also use an enum:
public void method(int a, int b, Service service) {
// body
List<SomeObject> list = service.getList(myClass);
// rest
}
public enum Service {
METHOD_1 {
#Override
public List<SomeObject> getList(MyClass myClass) {}
},
METHOD_2 {
#Override
public List<SomeObject> getList(MyClass myClass) {}
};
public abstract List<SomeObject> getList(MyClass myClass);
}
public MyClass {
private final int c;
private final int d;
private final int e;
...
}
Essentially the same as #proskor except in a different form.
If the body parts depend upon one another so you can't do as #dicarlo2's answer:
private interface GetObjects {
List<SomeObject> get();
}
public void method1(int a, int b) {
impl(a, b, new GetObjects() { public List<SomeObject> get() {
return service.getListA(c, d);
}});
}
public void method2(int a, int b) {
impl(a, b, new GetObjects() { public List<SomeObject> get() {
return service.getListB(c, d, e);
}});
}
private void impl(int a, int b, GetObjects getObjects) {
//body (the same in both of methods)
List<SomeObject> list = getObjects.get();
//rest of the body (the same in both of methods)
}
You can use an enum in place of GetObjects if you are concerned about the new, but don't mind getting the order mixed up, missing out on outer this and don't want to open this up (although it could implement an public interface).
Better syntax coming in Java SE 8, possibly. IIRC, along the lines of:
public void method1(int a, int b) {
impl(a, b, { -> service.getListA(c, d) });
}
I know this is heresy, but I tried to translate the examples from http://www.haskell.org/haskellwiki/Memoization to Java. So far I have:
public abstract class F<A,B> {
public abstract B f(A a);
}
...
public static <A, B> F<A, B> memoize(final F<A, B> fn) {
return new F<A, B>() {
private final Map<A, B> map = new HashMap<A, B>();
public B f(A a) {
B b = map.get(a);
if (b == null) {
b = fn.f(a);
map.put(a, b);
}
return b;
}
};
}
//usage:
private class Cell<X> {
public X value = null;
}
...
final Cell<F<Integer, BigInteger>> fibCell = new Cell<F<Integer, BigInteger>>();
fibCell.value = memoize(new F<Integer, BigInteger>() {
public BigInteger f(Integer a) {
return a <= 1 ? BigInteger.valueOf(a) : fibCell.value.f(a - 1).add(fibCell.value.f(a - 2));
}
});
System.out.println(fibCell.value.f(1000));
That works fine. Now I tried to implement the memoFix combinator defined as
memoFix :: ((a -> b) -> (a -> b)) -> a -> b
memoFix f =
let mf = memoize (f mf) in mf
But I got stuck. Does this even make sense in Java, especially concerning its inherent lack of lazyness?
The Guava library actually implements something similar with its MapMaker:
final Map<Integer, String> memoizingMap = new MapMaker().makeComputingMap(
new Function<Integer, String>() {
#Override
public String apply(final Integer input) {
System.out.println("Calculating ...");
return Integer.toHexString(input.intValue());
}
});
System.out.println(memoizingMap.get(1));
System.out.println(memoizingMap.get(100));
System.out.println(memoizingMap.get(100000));
System.out.println("The following should not calculate:");
System.out.println(memoizingMap.get(1));
Output:
Calculating ...
1
Calculating ...
64
Calculating ...
186a0
The following should not calculate:
1
The nice thing is that you can fine-tune the generated map for different aspects as expiration, concurrency level etc.
Okay, this has convinced me that functional programming is ususally a bad idea with Java. Lack of laziness can be worked around using a reference object (which essentially implements laziness). Here's a solution:
public static class FunctionRef<A, B> {
private F<A, B> func;
public void set(F<A, B> f) { func = f; }
public F<A, B> get() { return func; }
}
public static class Pair<A, B> {
public final A first; public final B second;
public Pair(A a, B b) {
this.first = a; this.second = b;
}
}
public static <A, B> F<A, B> memoFix(final F<Pair<FunctionRef<A, B>, A>, B> func) {
final FunctionRef<A, B> y = new FunctionRef<A, B>();
y.set(
memoize(new F<A, B>() {
#Override
public B f(A a) {
return func.f(new Pair<FunctionRef<A, B>, A>(y, a));
}
})
);
return y.get();
}
//Test that it works
public static void main(String[] args) {
F<Pair<FunctionRef<Integer, Integer>,Integer>, Integer> fib = new F<Pair<FunctionRef<Integer, Integer>,Integer>, Integer>() {
#Override
public Integer f(Pair<FunctionRef<Integer, Integer>, Integer> a) {
int value = a.second;
System.out.println("computing fib of " + value);
if (value == 0) return 0;
if (value == 1) return 1;
return a.first.get().f(value - 2) + a.first.get().f(value - 1);
}
};
F<Integer, Integer> memoized = memoFix(fib);
System.out.println(memoized.f(10));
}
Note that when the program is run, it only outputs "computing fib of" once for each value!
The memoFix solution by Joe K was really impressive :-)
For practical purposes, this seems to be the most elegant solution for recursive (and non-recursive) functions, as it avoids the need for some reference variable:
import java.util.HashMap;
import java.util.Map;
public abstract class MemoF<A,B> extends F<A,B> {
private final Map<A, B> map = new HashMap<A, B>();
#Override
public B f(A a) {
B b = map.get(a);
if (b == null) {
b = func(a);
map.put(a, b);
}
return b;
}
public abstract B func(A a);
}
Now you have to implement func as usual, except that you never call it recursively, but call f instead:
F<Integer, BigInteger> memoFib = new MemoF<Integer, BigInteger>(){
public BigInteger func(Integer a) {
return a <= 1 ? BigInteger.valueOf(a) : f(a - 1).add(f(a - 2));
}
};
System.out.println(memoFib.f(100));
//--> 354224848179261915075
Why are you stuck? It looks like you're done.
You've successfully memoized calls to a function using a Map.
Here is a snippet from my recent solution for the exact same problem:
private final static class MutableFunction<A, B> implements Function<A, B> {
public Function<A, B> f;
#Override
public B apply(A argument) {
return f.apply(argument);
}
}
/**
* Computes the fixed point of function f.
* Only terminates successfully if f is non-strict (that is returns without calling its argument).
*/
public static <A, B, R extends Function<A,B>> R fix(final Function<? super Function<A, B>, ? extends R> f) {
MutableFunction<A, B> mutable = new MutableFunction<A, B>();
R result = f.apply(mutable);
mutable.f = result;
return result;
}
Memofix of f is just a fix(composition(memo, f)) then!