Reputation: 3076
I have two classes, classB and classC, that both extend classLetters. In a separate class, which classB and classC call to, there are two methods: getBType() and getCType(). The code within the two is near duplicate because they both do the same thing, except one grabs B types and one grabs C types. Is there a way to combine these two into a single method called getType(String className), for example, that can detect which class is calling it and get the correct type depending on who called the method? It is so I can call from either classB or from classC with just one method, getType(String className) instead of having to call getBType() from classB and getCType() from classC. This is important because I will be adding a lot more classes that will extend from this, and I would like to reduce the amount of duplicate code.
Collection<classB> bstuff = new Collection<classB>();
Collection<classC> cstuff = new Collection<classC>();
public Collection<classB> getBType() {
ArrayList<classB> b = new ArrayList<classb>(); //this can just return bstuff instead
b.addAll(bstuff); //but i would like to leave this here for the example
return b;
}
public Collection<classC> getCType() {
ArrayList<classC> c = new ArrayList<classc>(); //this can just return cstuff instead
c.addAll(cstuff); //but i would like to leave this here for the example
return c;
}
I have thought of something like this: Make a data structure that holds the collections indexed by their class:
static HashMap<String, Collection<? extends classLetters>> allLetters = new HashMa..... etc(); //just an example
//then here i would statically add each class type to the hashmap
public Collection<? extends classLetters> getType(className) {
if (className == "classB") {
ArrayList<classB> b = new ArrayList<classb>();
b.addAll(bstuff);
return b;
}
else if (className == "classC") {
ArrayList<classC> c = new ArrayList<classc>();
c.addAll(cstuff);
return c;
}
}
This still has duplicate code within itself though. Is it possbile to have something using generics?
public <T> Collection<T> getType() {
ArrayList<T> anyLetter = new ArrayList<T>;
anyLetter.addAll(/* somehow distingush which letter class to put here */);
return anyLetter;
}
Upvotes: 1
Views: 2574
Reputation: 52
class A{}
class B extends A{}
class C extends A{}
class Container{
private Map<Class<? extends A>, Collection<? extends A>> things = new HashMap<Class<? extends A>, Collection<? extends A>>();
<Athing extends A> Collection<Athing> get(Class<Athing> clazz)
{
return (Collection<Athing>)things.get(clazz);
}
<Athing extends A> void put(Class<Athing> clazz, Athing thing)
{
Collection<Athing> coll = get(clazz);
if(coll == null)
{
coll = new ArrayList<Athing>();
things.put(clazz, coll);
}
coll.add(thing);
}
public static void main(String []args){
Container con = new Container();
con.put(B.class, new B());
con.put(A.class, new A());
}
}
Upvotes: 1
Reputation: 109595
Instead of inheritance one can use "templating" like in Arrays, Collections.
List<String> ls = new ArrayList<>();
List<Integer> li = new ArrayList<>();
public static <T> List<T> copy(Collection<T> list) {
List<T> result = new ArrayList<>();
result.addAll(list);
return result;
}
public List<String> getLS() {
return copy(ls);
}
public List<Integer> getLI() {
return copy(li);
}
Upvotes: 3