Use generic class as method input - java

I have a iterative code like below with is used in different place of my project:
List<NewsItem> thisitem = Select.from(NewsItem.class).where(Condition.prop("_id").eq(item.get_id())).list();
if (thisitem.size() > 0) {
thisitem.get(0).delete();
image_bookmark.setImageResource(R.drawable.ic_bookmark_normal);
} else {
item.save();
image_bookmark.setImageResource(R.drawable.ic_bookmarkfill);
}
I want to write a method witch contain above code ,but worked for every object of class witch extend SugarOrmItem class . i write the below but apparently it's not true:
public static void insert_bookmark(String prop,SugarOrmItem record ,ImageView imageView)
{
List<SugarOrmItem> thisitem = Select.from(SugarOrmItem.class).where(Condition.prop(prop).eq(record.get_id())).list();
if (thisitem.size() > 0) {
thisitem.get(0).delete();
imageView.setImageResource(R.drawable.ic_bookmark_normal);
} else {
imageView.setImageResource(R.drawable.ic_bookmarkfill);
}
}
what should i do?
Edit:
this is my SugarItem class:
import com.orm.SugarRecord;
public abstract class SugarOrmItem extends SugarRecord {
public abstract int get_id();
}

I think it needs to be this:
public static <T extends SugarOrmItem> void insert_bookmark(
String prop, T record, ImageView imageView, Class<T> clazz)
{
List<T> thisitem = Select.from(clazz).
where(Condition.prop(prop).eq(record.get_id())).list();
if (thisitem.size() > 0) {
thisitem.get(0).delete();
imageView.setImageResource(R.drawable.ic_bookmark_normal);
} else {
imageView.setImageResource(R.drawable.ic_bookmarkfill);
}
}

Related

Raw use of parameterized class - when returning base class with generic parameter with factory design pattern

Background
I learned Factory pattern, and the power of generics and I'm attempting to piece them together.
Here are my efforts
Without generic input parameter - No warnings
public abstract class ArtifactCreator {
public abstract void setArtifacts(String workflowInput);
}
public class FooArtifactCreator extends ArtifactCreator {
#Override
public void setArtifacts(String input) {
return null;
}
}
public class BarArtifactCreator extends ArtifactCreator {
#Override
public void setArtifacts(String input) {
return null;
}
}
public class Factory {
public ArtifactCreator getArtifactCreator(String domain) {
if (domain == "foo") {
return new FooArtifactCreator()
} else if (domain == "bar") {
return new BarArtifactCreator()
}
return null;
}
}
My whole problem is the workflowInput is relegated to the type String. But I want it to be some generic POJO.
With generics - I get warnings in Factory.java and Store.java that I want to get rid of correctly. (I want to be using generics for my use-case the right way).
Raw use of parameterized class 'ArtifactCreator' on both the files in Store.java and Factory.java
Unchecked call to 'setArtifacts(T)' as a member of raw type 'ArtifactCreator' in Store.java
public abstract class ArtifactCreator {
public abstract void setArtifacts(T workflowInput);
}
public class FooArtifactCreator extends ArtifactCreator<FooInput> {
#Override
public void setArtifacts(FooInput input) {
return null;
}
}
public class BarArtifactCreator extends ArtifactCreator<BarInput> {
#Override
public void setArtifacts(BarInput input) {
return null;
}
}
public class Factory {
public ArtifactCreator getArtifactCreator(String domain) {
if (domain == "foo") {
return new FooArtifactCreator()
} else if (domain == "bar") {
return new BarArtifactCreator()
}
return null;
}
}
public class Input {
private String domain;
private String otherInput;
}
public class Store {
private final Factory factory;
public Store(Factory factory) {
this.factory = factory;
}
public ArtifactCreator getCaseClosureArtifactFactory(Input req) {
ArtifactCreator artifactCreator = factory.setArtifacts(req.getDomain());
//In reality - Create either FooInput or BarInput depending on
//`otherInput` field in `Input` POJO. Assume that there will be another
//factory/HashMap to return the input needed
FooInput input = new FooInput();
artifactCreator.setArtifacts(input);
}
}
One way I can think of solving my problems is do something like:
public class WorkflowInput {
private FooInput input;
private BarInput input;
}
public abstract class ArtifactCreator {
public abstract void setArtifacts(WorkflowInput workflowInput);
}
public class FooArtifactCreator extends ArtifactCreator {
#Override
public void setArtifacts(WorkflowInput input) {
FooInput input = input.getFooInput(); //Extract specific input
}
}
public class BarArtifactCreator extends ArtifactCreator {
#Override
public void setArtifacts(WorkflowInput input) {
BarInput input = input.getBarInput(); //Extract specific input
}
}
This feels a bit unecessary to keep some fields in WorkflowInput null.

Implement a common function accepting argument of two different classes?

I have two classes A and B and they both have a common field in them, and I want to create a function in which if I pass Class A object then I want to set that common field value to the passed value and if I pass Class B object then I want to set that common field value to the passed value. Can anyone please tell me how can I do this, I am new to Java Generic Classes.
Otherwise I would have to make two different functions OR I would have to make an if and else which would decide that passed object belongs to which class ??
Class A
public class A{
int footer;
public void setFooter(int fo) {
footer = fo;
}
}
Class B
public class B{
int footer;
public void setFooter(int fo) {
footer = fo;
}
}
Class D
public class D{
public void change_footer(T generic_param, int value) {
generic_param.setFooter(value);
}
}
Class HelloWorld
public class HelloWorld{
public static void main(String []args){
Here I want to call
A a = new A();
new D().change_footer(a, 5);
B b = new B();
new D().change_footer(b, 5)
}
}
Thank You
And if I got all of the question wrong, and nor A nor B are generic, AND the type of field is fixed.
then you mean something like:
class D {
/*public <T extends Super> would be muuuch nicer here as well!*/
public /*static*/ <T> void change_footer(T obj, int data) {
//otherwise, you could just cast to Super...and set dat field.
if (obj instanceof A) {
((A) obj).setField(data);
} else if (obj instanceof B) {
((B) obj).setField(data);
} // else ... ?
}
}
Original answer:
Easy peasy (the "straight forward" implementation produces the desired results.):
class A<T> {
T daField;
public void setField(T pField) {
daField = pField;
}
public T getField() {
return daField;
}
}
class B<T> extends A {//empty
}
class Test {
public static void main(String... args) {
B<Object> testB1 = new B<>(); //
testB1.setField(new Object());
System.out.println(testB1.getField());
B<String> testB2 = new B<>();
testB2.setField("blah blah");
System.out.println(testB2.getField());
B<Integer> testB3 = new B<>();
testB3.setField(42);
System.out.println(testB3.getField());
}
}
System.out:
java.lang.Object#6d06d69c
blah blah
42
It get's (little) more complicated, when you want to instantiate Ts ...but still possible/other question. :)
Edit to your comment:
If there's only one common field, then why not:
/*abstract */class Super<T> {
T daField;
public void setField(T pField) {
daField = pField;
}
public T getField() {
return daField;
}
}
? ...and:
class A<T> extends Super { ... }
class B<T> extends Super { ... }

When to use super or override in methods when you extend from a class?

Hi I'm new to java and I currently have two classes(useForce and Attack) that are working fine but these two classes share a lot of code.To reduce duplicated code I extended use Force class from Attack class but I'm not sure how to modify the code?
For example in my attack.java
public class Attack extends SWAffordance implements SWActionInterface {
some code here...
#Override
public boolean canDo(SWActor a) {
SWEntityInterface target = this.getTarget();
return !a.isDead() && target.getHitpoints()>0;
}
#Override
public void act(SWActor a) {
SWEntityInterface target = this.getTarget();
boolean targetIsActor = target instanceof SWActor;
SWActor targetActor = null;
int energyForAttackWithWeapon = 1;//the amount of energy required to attack with a weapon
if (targetIsActor) {
targetActor = (SWActor) target;
}
But the same two methods in my useForce.java is
public class UseForce extends Attack {
some code here....
#Override
public boolean canDo(SWActor a) {
return a.getForcepoints()>=minUsePoints;
}
#Override
public void act(SWActor a) {
SWEntityInterface target = this.getTarget();
boolean targetIsActor = target instanceof SWActor;
SWActor targetActor = null;
int energyForForceAttack = 2;//the amount of energy required to use force
if (targetIsActor) {
targetActor = (SWActor) target;
}
As you can see these two share many similar lines of code in act method except in Attack.java int energyForAttackWithWeapon = 1 whereas in useForce int energyforAttackWithWeapon=2...
How do I use super or override to reduce the lines of duplicated code?Any help will be appreciated.
EDIT:If I use a thirdparty class to extract the duplicated code, how do I do it because Attack already extends from SWAffordance?
The template method pattern could help to solve your duplication issue.
It allows to define a common algorithm in a base class while leaving the subclasses to custom some parts of the algorithm.
So define both common concrete operations and custom operations to define by subclasses in an abstract class : AbstractAttack.
public abstract class AbstractAttack extends SWAffordance implements SWActionInterface {
public abstract int getEnergyForAttack();
public abstract boolean canDo(SWActor a);
public void act(SWActor a) {
SWEntityInterface target = this.getTarget();
boolean targetIsActor = target instanceof SWActor;
SWActor targetActor = null;
int energyForAttack = getEnergyForAttack();
... // use energyForAttack
if (targetIsActor) {
targetActor = (SWActor) target;
}
}
}
Now Attack and Other subclasses inherit from AbstractAttack to benefit from concrete operations and also implement theirs own specificities :
public class DefaultAttack extends AbstractAttack {
#Override
public boolean canDo(SWActor a) {
SWEntityInterface target = this.getTarget();
return !a.isDead() && target.getHitpoints()>0;
}
#Override
public int getEnergyForAttack(){
return 1;
}
}
public class UseForce extends AbstractAttack {
#Override
public boolean canDo(SWActor a) {
return a.getForcepoints()>=minUsePoints;
}
#Override
public int getEnergyForAttack(){
return 2;
}
}

Avoid cast in a generics hierarchy

I have some difficulty to simplify more the problem. Sorry if they are too many code here.
I try to improve the architecture of the code above because I hate warning and cast and I feel something wrong.
Now, the code.
I have a util class with these two parametrized methods (same signature as OpenJPA's CriteriaBuilder...)
public class MyUtil {
public void equal(List<?> l, Object value) {
// do something (see CriteriaBuilder.equal method)
}
public <Y extends Comparable<? super Y>> void greaterThan(List<? extends Y> l, Y value) {
// do something (see CriteriaBuilder.greaterThan method)
}
}
Then, I want to be able to abstract them to call it via an interface.
public interface IOperation<T> {
// maybe make this method generic ? but how ?
public abstract void doOp(List<T> l, T value);
}
public abstract class AbstractOperation<T> implements IOperation<T> {
protected MyUtil myUtil;
}
public class EqualOp extends AbstractOperation<Object> {
#Override
public void doOp(List<Object> path, Object value) {
myUtil.equal(path, value);
}
}
public class GreaterThanOp<T extends Comparable<? super T>> extends AbstractOperation<T> {
#Override
public void doOp(List<T> path, T value) {
myUtil.greaterThan(path, value);
}
}
I create a factory
public class OperationFactory {
private static OperationFactory instance;
public static OperationFactory getInstance() {...}
public IOperation<?> get(String op) {
if ("=".equals(op)) {
return new EqualOp();
} else if (">".equals(op)) {
return new GreaterThanOp<Comparable<? super Object>>();
}
throw new InvalidParameterException();
}
}
Then I use it :
public class Client {
public void needOp(String op) {
IOperation<String> operation = (IOperation<String>) OperationFactory.getInstance().get(op); // How to avoid this cast ?
List<String> l = null;
operation.doOp(l, "a string");
}
}
My question is : is it possible to avoid this cast in the Client class ? How ? Is there a way to have a better architecture ?
Thanks for reading
I'm assuming you can require your type to be Comparable.
Parameterize EqualOp like GreaterThanOp:
public class EqualOp<T extends Comparable<T>> extends AbstractOperation<T> {
#Override public void doOp(List<T> path, T value) ...
And define get() like this:
public <T extends Comparable<T>> IOperation<T> get(String op) {
if ("=".equals(op)) {
return new EqualOp<T>();
} else if (">".equals(op)) {
return new GreaterThanOp<T>();
}
...

Class design question [optional implementation]

I was wondering how to design a system in which I have a class Super and a couple of classes that are subclasses of Super (let's say Sub1, Sub2, Sub3) and I want a class Cool. Now there are two things I want to have:
Sub1 and Sub2 can be Cool's, Sub3 can never be cool.
I must be able to have a List in which there can be Sub1's and Sub2's, if they are cool. If for example I make an object of Sub1 and it is cool I can put it in the list, if it's not it cannot be in the list.
Any suggestions? Hints?
Arne's answer kind of does what you want, but I find it overly complicated. Maybe I'm missing something? Why not just:
class Super { }
interface Cool { boolean isCool(); }
class CoolImpl extends Super implements Cool {
private boolean cool;
public CoolImpl(boolean cool) { this.cool = cool; }
public boolean isCool() { return this.cool; }
}
class Sub1 extends CoolImpl { }
class Sub2 extends CoolImpl { }
class Sub3 extends Super { }
class CoolList extends ArrayList<Cool> {
public boolean add(Cool cool) {
if (!cool.isCool()) {
return false;
}
return super.add(cool);
}
}
Maybe something like this:
class Super {}
interface Cool { boolean isCool(); }
class IsCool implements Cool {
public boolean isCool() { return true; }
}
class NotCool impolements Cool {
public boolean isCool() { return false; }
}
interface CoolSupporter {
boolean isCool();
Cool getCool();
}
class Sub1 extends Super implements CoolSupporter {
private Cool cool;
public Sub1() { this(new NotCool()); }
public Sub1(Cool cool) { this.cool = cool; }
public boolean isCool() { this.cool.isCool(); }
public Cool getCool() { return this.cool; }
}
class Sub2 extends Super implements CoolSupporter {
private Cool cool;
public Sub1() { this(new NotCool()); }
public Sub1(Cool cool) { this.cool = cool; }
public boolean isCool() { this.cool.isCool(); }
public Cool getCool() { return this.cool; }
}
class Sub3 extends Super {}
class CoolList {
private List<CoolSupporter> list = new ArrayList<CoolSupporter>();
public void add(CoolSupporter coolSupporter) {
if (coolSupporter.isCool()) {
list.add(coolSupporter);
} else {
throw new UncoolException();
}
}
}
You can create an marker interface say cool.
Let class Sub1 and Sub2 implements this interface
and before adding to the list check for instance of cool
may be this can help.
You can't have a class optionally belonging to a type in Java. Though you may subclass Sub1, with one subclass implementing an interface Cool and the other not:
class Super { }
interface Cool { }
class Sub1 extends Super { }
class Sub1Cool extends Sub1 implements Cool { }
class Sub2 extends Super { }
class Sub2Cool extends Sub2 implements Cool { }
class Sub3 extends Super { }
class CoolList extends ArrayList<Super> {
public boolean add(Super sup) {
if (!(sup instanceof Cool)) {
return false;
}
return super.add(cool);
}
}
You might also discard the Cool concept and use a visitor pattern:
class Super {
public boolean addTo(List<Super> coolList) {
if (canBeAddedToCoolList()) {
return coolList.add(this);
}
return false;
}
protected boolean canBeAddedToCoolList() {
return false;
}
}
class Sub1 extends Super {
protected boolean canBeAddedToCoolList() {
// check logic to allow/disallow addition
}
}
IMO, you need to have a overrided List (Say MyList, that overrides add()).
In add(), Check if the object you are adding is Cool, if it is so, then add it part of the list. If not then just gracefully disregard it.
Does this help?
The simplest way you can manage this is to further subclass Sub1 (CoolSub1 and NotCoolSub1) and Sub2 (CoolSub2 and NotCoolSub2).
CoolSub1 and CoolSub2 can then implement Cool ( Cool should be an interface and not a class)
You can then define
List<Cool>
which will accept implementations of Sub1 and Sub2, but only if they implement Cool.

Categories

Resources