I created a java project to apply my GraphTheory course and enhance my java skills.
In this project :
I created a class Sommet<S>(Vertex in English) with an attribute Id with a generic type called <S>.
I created a class Arc<S>(Edge in English) with two attributes Sommet(Vertex).
I created a class EnsembleArc which is an HashSet of Arc
I also created a class ArcValue which inherit from Arc and have an int attribute Valeur(Value in English)
Here everything is fine and I dont have any problem.
But then I created a class EnsembleArcValue which inherit from EnsembleArc because every method from EnsembleArc will be useful to EnsembleArcValue.
But I also want EnsembleArcValue to be an HashSet of ArcValue (and I dont want an Arc which is not an ArcValue). And with the inheritance EnsembleArcValue is able to have an "simple" Arc in his Set.
So my question after all this explanation is :
Is there a way for EnsembleArcValue to inherit from EnsembleArc but will only accept an ArcValue in his Set.
Here is an image of The UML Project
I hope it will help to understand my problem (dont look at the bottom).
Here is the code :
public class Sommet<S>
{
//attributes
private S id;
public Sommet(S s)
{
setId(s);
}
public S getId()
{
return id;
}
public void setId(S s)
{
assert s!= null: "Objet null passé en paramètre";
id = s;
}
#SuppressWarnings("unchecked")
#Override
public boolean equals(Object obj)
{
boolean callback;
if(obj.getClass()!=getClass())
{
callback=false;
}
else
{
if(((Sommet<S>)obj).getId().equals(getId()))
{
callback=true;
}
else
{
callback=false;
}
}
return callback;
}
#Override
public int hashCode()
{
return getId().hashCode();
}
#Override
public String toString()
{
return getId().toString();
}
}
public class Arc<S>
{
private Sommet<S> depart;
private Sommet<S> arrivee;
public Arc(Sommet<S> dep, Sommet<S> arr)
{
setDepart(dep);
setArrivee(arr);
}
#Override
public String toString()
{
String str="("+getDepart().getId()+","+getArrivee().getId()+")";
return str;
}
public Sommet<S> getDepart()
{
return depart;
}
public Sommet<S> getArrivee()
{
return arrivee;
}
public void setDepart(Sommet<S> depart)
{
this.depart = depart;
}
public void setArrivee(Sommet<S> arrivee)
{
this.arrivee = arrivee;
}
#SuppressWarnings("unchecked")
#Override
public boolean equals(Object obj)
{
boolean callback;
if(obj.getClass()!=getClass())
{
callback=false;
}
else
{
if(((Arc<S>)obj).getDepart().equals(getDepart())&&((Arc<S>)obj).getArrivee().equals(getArrivee()))
{
callback=true;
}
else
{
callback=false;
}
}
return callback;
}
#Override
public int hashCode()
{
return getArrivee().hashCode()+getDepart().hashCode();
}
}
public class ArcValue<S,V> extends Arc<S>
{
private V valeur;
public ArcValue (Sommet<S> depart, Sommet<S> arrivee, V valeur)
{
super(arrivee,depart);
this.valeur=valeur;
}
public V getValeur()
{
return valeur;
}
}
import java.util.HashSet;
public class Ensemble<E> extends HashSet<E> implements Cloneable
{
private static final long serialVersionUID = -4354387895748449845L;
public Ensemble ()
{
super();
}
public Ensemble (Ensemble<E> ensemble)
{
for (E e : ensemble)
{
add(e);
}
}
public String toString()
{
StringBuffer str=new StringBuffer("{");
for(E e: this)
{
str=str.append(e.toString()+",");
}
str.setCharAt(str.length()-1, '}');
return str.toString();
}
#SuppressWarnings("unchecked")
#Override
public Ensemble<E> clone()
{
return (Ensemble<E>)super.clone();
}
}
public class EnsembleArc<S> extends Ensemble<Arc<S>>
{
public EnsembleArc(Ensemble<Arc<S>> ensemble)
{
super(ensemble);
}
public EnsembleArc()
{
super();
}
private static final long serialVersionUID = -4099925554493145279L;
public EnsembleSommet<S> listSucc(Sommet<S> sommet)
{
EnsembleSommet<S> XSucc=new EnsembleSommet<S>();
for (Arc<S> arc : this)
{
if (arc.getDepart()==sommet)
{
XSucc.add(arc.getArrivee());
}
}
return XSucc;
}
public EnsembleSommet<S> listPred(Sommet<S> sommet)
{
EnsembleSommet<S> XPred=new EnsembleSommet<S>();
for (Arc<S> arc : this)
{
if (arc.getArrivee()==sommet)
{
XPred.add(arc.getDepart());
}
}
return XPred;
}
public void add(Sommet<S> depart,Sommet<S>arrivee)
{
add(new Arc<S>(depart,arrivee));
}
#Override
public EnsembleArc<S> clone ()
{
return (EnsembleArc<S>)super.clone();
}
}
//import java.util.Collection;
public class EnsembleArcValues<S,V> extends EnsembleArc<S> //implements Collection<ArcValue<S,V>>
{
//TODO faire en sorte que ensembleArcValués ne contienne que des ArcsValue
private static final long serialVersionUID = -7163498825360866323L;
}
And you'll need this one to :
public class EnsembleSommet<S> extends Ensemble<Sommet<S>>
{
public EnsembleSommet()
{
super();
}
public EnsembleSommet(EnsembleSommet<S> ensemble)
{
super(ensemble);
}
private static final long serialVersionUID = 7278825382690341067L;
#Override
public EnsembleSommet<S> clone ()
{
return (EnsembleSommet<S>)super.clone();
}
public Sommet<S> firstSommet()
{
#SuppressWarnings("unchecked")
Sommet<S>[] tab=new Sommet[size()];
return toArray(tab)[0];
}
}
The only way you can achieve this is to make the type of Arc you want part of your generic deceleration. Rename your existing EnsembleArc to AbstractEnsembleArc and change it's generic decleration from < S > to < S, T extends Arc< S > > i.e.:
public abstract class AbstractEnsembleArc<S, T extends Arc<S>> extends Ensemble<T> {
// PUT ALL YOUR LOGIC CURRENTLY IN EnsembleArc HERE
}
Now create a new Class Called EnsembleArc and extend the new abstract class you've added, this new class will work identically to your existing EnsembleArc and class decleration should now look like:
public class EnsembleArc<S> extends AbstractEnsembleArc<S, Arc<S>> {
}
Finally have EnsembleArcValues extend the Abstract class instead of EnsembleArc so that you can declare that it should only accepts ArcValue and not simple Arc, do that like this:
public class EnsembleArcValues<S, V> extends AbstractEnsembleArc<S, ArcValue<S, V>> {
}
Related
Help me in the following code and how to used the backup on the Hazelcast
migration of the hazelcast 3.x.x to 5.x.x
package com.hazelcast.map;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.HazelcastInstanceAware;
import com.hazelcast.nio.serialization.impl.BinaryInterface;
import java.util.Map;
// Interface AbstractEntryProcessor
#BinaryInterface
public abstract class AbstractEntryProcessor<K,V> implements EntryProcessor<K,V> {
private final EntryBackupProcessor<K,V> entryBackupProcessor;
// Non Parameterize Constructor
public AbstractEntryProcessor() {
this(true);
}
// Parameterize Constructor AbstractEntryProcessor
public AbstractEntryProcessor(boolean applyOnBackup) {
if (applyOnBackup) {
entryBackupProcessor = new EntryBackupProcessorImpl();
} else {
entryBackupProcessor = null;
}
}
//EntryBackupProcessor
#Override
public final EntryBackupProcessor getBackupProcessor() {
return entryBackupProcessor;
}
// class EntryBackupProcessorImpl
private class EntryBackupProcessorImpl implements EntryBackupProcessor<k,V>, HazelcastInstanceAware {
// generated for EntryBackupProcessorImpl which doesn't implement HazelcastInstanceAware
static final long serialVersionUID = -5081502753526394129L;
#Override
public void processBackup(Map.Entry<K,V> entry) {
process(entry);
}
#Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
final AbstractEntryProcessor<k,V> outer = AbstractEntryProcessor.this;
if (outer instanceof HazelcastInstanceAware) {
((HazelcastInstanceAware) outer).setHazelcastInstance(hazelcastInstance);
}
}
}
}
How to used the backup methods in 5.x.x versons of series
how to used the backup in the above question ?
This should work:
public abstract class AbstractEntryProcessor implements EntryProcessor, HazelcastInstanceAware {
protected transient HazelcastInstance hazelcastInstance;
private final boolean applyOnBackup;
// Non Parameterize Constructor
public AbstractEntryProcessor() {
this(true);
}
// Parameterize Constructor AbstractEntryProcessor
public AbstractEntryProcessor(boolean applyOnBackup) {
this.applyOnBackup = applyOnBackup;
}
//EntryBackupProcessor
#Override
public final EntryProcessor getBackupProcessor() {
if (!applyOnBackup || this instanceof ReadOnly) {
return null;
}
return this;
}
#Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
this.hazelcastInstance = hazelcastInstance;
}
}
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.
I want to check if all the ingredients(toppings and fillings) inside a wrap are both vegan and nut free. This is the solution that I came up with, howver I think its a bit inefficient as there is duplication of code. Is there a more efficient way to do it?
(I have a map for all the toppings and fillings which every one contains boolean to know if the topping/filling is vegan and if it is nut free.
public boolean isVegan() {
for (Topping t : toppings) {
if (!t.isVegan()) {
return false;
}
}
for (Filling f : fillings) {
if (!f.isVegan()) {
return false;
}
}
return bread.isVegan();
}
public boolean isNutFree() {
for (Topping t : toppings) {
if (!t.isNutFree()) {
return false;
}
}
for (Filling f : fillings) {
if (!f.isNutFree()) {
return false;
}
}
return bread.isNutFree();
}
Supposing that Ingredient is the base class of these different classes and that this class defines the isVegan() method, you could create a Stream from all these objects and computing whether all are vegan :
public boolean isVegan() {
return
Stream.concat(toppings.stream(), fillings.stream(), Stream.of(bread))
.allMatch(Ingredient::isVegan);
}
For isNutFree() the idea is the same :
public boolean isNutFree() {
return
Stream.concat(toppings.stream(), fillings.stream(), Stream.of(bread))
.allMatch(Ingredient::isNutFree);
}
Note that you could also generalize a matching method to reduce further the duplication :
public boolean allMatch(Predicate<Ingredient> predicate) {
return
Stream.concat(toppings.stream(), fillings.stream(), Stream.of(bread))
.allMatch( i -> predicate.test(i));
}
And use it such as :
boolean isNutFree = allMatch(Ingredient::isNutFree);
boolean isVegan = allMatch(Ingredient::isVegan);
Here is a food type replacing either Topping or Filling or anything:
public interface FoodPart {
boolean isVegan();
boolean isNutFree();
}
Here we have an abstract Food class containing all common codes:
public abstract class Food {
private List<? extends FoodPart> foodParts;
public boolean isVegan() {
return foodParts.stream().noneMatch(foodPart -> foodPart.isVegan());
}
public boolean isNutFree() {
return foodParts.stream().noneMatch(foodPart -> foodPart.isNutFree());
}
}
And here is a concrete and not abstract food:
public class Lasagne extends Food {}
Edit:
If you don't want to inherit from FoodPart then you can change List<? extends FoodPart> simply to List<FoodPart>.
You can also make Food to not abstract so you can easily use it, and don't forget to add getters/setters to provide the foodParts.
Yeez, you guys are fast :)
What I wrote is pretty much already covered in the other answers here but just posting since mine does have some subtle differences (not necessarily better). And since I already went through the motions of writing the code I might as well post it :)
First an interface for your fillings and toppings:
public interface FoodInformation {
boolean isVegan();
boolean isNutFree();
boolean isGlutenFree();
}
Then an abstract class which your toppings and fillings can extend:
public abstract class Ingredient implements FoodInformation {
private boolean vegan;
private boolean nutFree;
private boolean glutenFree;
public Ingredient(boolean vegan, boolean nutFree, boolean glutenFree) {
this.vegan = vegan;
this.nutFree = nutFree;
this.glutenFree = glutenFree;
}
#Override
public boolean isVegan() {
return vegan;
}
#Override
public boolean isNutFree() {
return nutFree;
}
#Override
public boolean isGlutenFree() {
return glutenFree;
}
}
Your Filling:
public class Filling extends Ingredient {
public Filling(boolean vegan, boolean nutFree, boolean glutenFree) {
super(vegan, nutFree, glutenFree);
}
}
Your Topping:
public class Topping extends Ingredient {
public Topping(boolean vegan, boolean nutFree, boolean glutenFree) {
super(vegan, nutFree, glutenFree);
}
}
And your Wrap:
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Wrap {
private List<Filling> fillings;
private List<Topping> toppings;
public Wrap(List<Filling> fillings, List<Topping> toppings) {
this.fillings = fillings;
this.toppings = toppings;
}
public boolean isNutFree() {
return testIngredient(FoodInformation::isNutFree);
}
public boolean isVegan() {
return testIngredient(FoodInformation::isVegan);
}
public boolean isGlutenFree() {
return testIngredient(FoodInformation::isGlutenFree);
}
private boolean testIngredient(Predicate<FoodInformation> predicate) {
// edited thanks to davidxxx for the Stream.concat notation!
return Stream
.concat(fillings.stream(), toppings.stream())
.allMatch(predicate);
}
}
And a test to show the implementation works:
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertFalse;
public class WrapTest {
private Wrap wrap;
#Before
public void setup() {
Filling filling1 = new Filling(true, true, false);
Filling filling2 = new Filling(true, false, true);
Filling filling3 = new Filling(true, true, true);
Topping topping1 = new Topping(true, true, true);
wrap = new Wrap(Arrays.asList(filling1, filling2, filling3), Collections.singletonList(topping1));
}
#Test
public void testIsGlutenFree() {
assertFalse(wrap.isGlutenFree());
}
#Test
public void testIsNutFree() {
assertFalse(wrap.isNutFree());
}
#Test
public void testIsVegan() {
assertTrue(wrap.isVegan());
}
}
Have fun with your project!
create an interface that has isVegan and isNutFree
public interface MyInterface {
boolean isVegan();
boolean isNutFree();
}
Then each of your classes with implement your interface
public class Topping implements MyInterface {
#Override
public boolean isVegan() {
return isVegan;
}
#Override boolean isNutFree() {
return isNutFree;
}
}
public class Filling implements MyInterface {
#Override
public boolean isVegan() {
return isVegan;
}
#Override boolean isNutFree() {
return isNutFree;
}
}
Next create a method that can test the lists
public boolean isVegan(List<? extends MyInterface> list) {
for(MyInterface myObj : list) {
if (myObj.isVegan()) return true;
}
return false;
}
public boolean isNutFree(List<? extends MyInterface> list) {
for(MyInterface myObj: list) {
if (myObj.isNutFree()) return true;
}
return false;
}
then each list you can pass into the methods to get the results
So, after this question where I basically exploits reflection for passing primitive references to modify the primitive itself, like:
_begin("Another Window", ::showAnotherWindow)
I was looking for something to make something similar possible also from java, where at the moment I am using plains primitive arrays:
private boolean[] showAnotherWindow = {false};
imgui.begin("Another Window", showAnotherWindow);
#hotkey suggested me the possibility to create a class implementing the KMutableProperty0 interface and that automatically gets and sets the corresponding variable
Example:
KMutableProperty0<Boolean> prop =
PropUtils.javaProp(this, t -> t.showAnotherWindow, (t, r) -> { t.showAnotherWindow = r; });
_begin("Another Window", prop);
So, I wanted to give it a try and implemented the following in java.
Getter:
#FunctionalInterface
public interface Getter<T> {
T get();
}
Setter:
#FunctionalInterface
public interface Setter<T> {
void set(T type);
}
And then the class itself (I just wrote the constructor, all the methods are those requested by the interface and automatically implemented by the IDE) :
public class JavaProp <T> implements KMutableProperty0<T> {
private imgui.Getter<T> getter;
private imgui.Setter<T> setter;
public JavaProp(imgui.Getter<T> getter, imgui.Setter<T> setter) {
this.getter = getter;
this.setter = setter;
}
#Override
public void set(T t) {
setter.set(t);
}
#NotNull
#Override
public Setter<T> getSetter() {
return null;
}
#Override
public T get() {
return getter.get();
}
#Nullable
#Override
public Object getDelegate() {
return null;
}
#NotNull
#Override
public Getter<T> getGetter() {
return null;
}
#Override
public T invoke() {
return null;
}
#Override
public boolean isLateinit() {
return false;
}
#Override
public boolean isConst() {
return false;
}
#NotNull
#Override
public String getName() {
return null;
}
#NotNull
#Override
public List<KParameter> getParameters() {
return null;
}
#NotNull
#Override
public KType getReturnType() {
return null;
}
#NotNull
#Override
public List<KTypeParameter> getTypeParameters() {
return null;
}
#Override
public T call(Object... objects) {
return null;
}
#Override
public T callBy(Map<KParameter, ?> map) {
return null;
}
#Nullable
#Override
public KVisibility getVisibility() {
return null;
}
#Override
public boolean isFinal() {
return false;
}
#Override
public boolean isOpen() {
return false;
}
#Override
public boolean isAbstract() {
return false;
}
#NotNull
#Override
public List<Annotation> getAnnotations() {
return null;
}
}
But whenever I try to run that, I get the following:
Error:(45, 12) java: reference to Getter is ambiguous
both interface kotlin.reflect.KProperty0.Getter in kotlin.reflect.KProperty0 and interface kotlin.reflect.KProperty.Getter in kotlin.reflect.KProperty match
The problematic function is this one:
#NotNull
#Override
public Getter<T> getGetter() {
return null;
}
And the relevant file is kotlin.reflect.KProperty.tk, you can find it here
Any idea how could I solve it?
Just specify which interface you mean:
public KProperty0.Getter<T> getGetter()
But I would prefer to implement the class in Kotlin and only consume it from Java.
I have a requirement that is close to extending enums and since that is not possible, after doing some research online, I came up with this approach of using interfaces and making the enums extend them.
My problem is that I have a few basic types A,B and a flag for each type that says if that has to be checked. Similarly I have some extended types C... which do the same stuff after checking their flags.
Here is the code that does this
Type Interface:
public interface Type {
public String name();
}
Here is the class that uses the basic types
public class BasicChecker {
private static boolean checkA = false;
private static boolean checkB = false;
public enum BasicType implements Type {
A, B;
}
public static boolean isCheckA() {
return checkA;
}
public static void setCheckA(boolean checkA) {
BasicChecker.checkA = checkA;
}
public static boolean isCheckB() {
return checkB;
}
public static void setCheckB(boolean checkB) {
BasicChecker.checkB = checkB;
}
public static void doStuff(String message, Type type) {
if (type.name().equalsIgnoreCase(BasicType.A.name())) {
doStuff(message, isCheckA());
} else if (type.name().equalsIgnoreCase(BasicType.B.name())) {
doStuff(message, isCheckB());
}
}
protected static void doStuff(String message, boolean flag) {
if (someCheckMethod() && flag) {
doStuff(message, flag);
}
}
private static boolean someCheckMethod() {
return false;
}
}
And this is the class that uses extended types
public class ExtendedChecker extends BasicChecker {
private static boolean checkC = false;
public enum ExtendedType implements Type {
C;
}
public static boolean isCheckC() {
return checkC;
}
public static void setCheckC(boolean checkC) {
ExtendedChecker.checkC = checkC;
}
public static void doStuff(String message, Type type) {
BasicChecker.doStuff(message, type);
if (type.name().equalsIgnoreCase(ExtendedType.C.name())) {
doStuff(message, isCheckC());
}
}
}
What I am trying to solve now is to remove all the if else cases from log method. I am also trying to see if there is a better way to do this. Please ignore the statics. I do want them to be static fields and methods.
I'm having trouble understanding exactly what you're trying to do from your description, but you may find abstract methods in enums to be useful.
For example, you could add an abstract method "foo" to your enums:
public enum BasicType implements Type {
A {
public void foo(String message) {
// Do special A stuff
}
}, B {
public void foo(String message) {
// Do special B stuff
}
};
public abstract void foo(String message);
}
And you could then use that method like this:
public static void doStuff(String message, Type type) {
type.foo(message);
}
Naturally, you could put any such abstract methods in an interface you extend, if that's useful.
public class BasicChecker {
private static final Set<Type> _doCheck = Collections.newSetFromMap(new ConcurrentHashMap<Type,Boolean>());
public enum BasicType implements Type {
A, B;
}
public static boolean isCheck(Type type) {
return return _doCheck.contains(type);
}
public static void setCheck(Type type, boolean check) {
if(check) {
_doCheck.add(type);
} else {
_doCheck.remove(type);
}
}
public static void doStuff(String message, Type type) {
doStuff(message, isCheck(type));
}
}