Consider the below example, what is a good way to avoid the warning with respect to unchecked conversion below?
Usercase is as
An interface which represent a generic statemachine
Each statemachine implementation requires a service, a set of utils required while running corresponding statemachines.
A default service which provides common services across statemachines
A transaction(txn) a binder of state and service.
import java.util.function.Consumer;
public class GenericsTest {
public static void main(String[] args) {
AService service = new AService("Aservice");
new Txn<>(service).next();
new Txn<>(new DefaultState()).next();
}
}
// ----------------------------------------------------------- //
interface Service {
String getName();
<T extends Service> State<T> getState();// this is unclear how to use generics here
}
interface State<T extends Service> {
Consumer<Txn<T>> getFunction();
int getN();
}
// ----------------------------------------------------------- //
class Txn<T extends Service> {
private T service;
private State<T> current;
Txn(State<T> current) {
this.current = current;
}
Txn(T service) {
this.service = service;
this.current = this.service.getState();
}
int next() {
do {
current.getFunction().accept(this);
} while (current.getN()>0);
return current.getN();
}
public State<T> getCurrent() {
return current;
}
public void setCurrent(State<T> current) {
this.current = current;
}
}
// ----------------------------------------------------------- //
abstract class DefaultService implements Service {
private String name;
public DefaultService(String name) {
this.name = name;
}
public String getName(){
return this.name.toUpperCase();
}
}
class AService extends DefaultService implements Service {
public AService(String name) {
super(name);
}
#Override
public State<AService> getState() {
return new AState(6);
}
}
// ----------------------------------------------------------- //
class DefaultState implements State<DefaultService> {
#Override
public Consumer<Txn<DefaultService>> getFunction() {
return (txn) -> System.out.println("hurray now left is to do default at "+txn.getCurrent().getN());
}
#Override
public int getN() {
return 0;
}
}
class AState implements State<AService> {
private int n;
AState(int n) {
this.n = n;
}
#Override
public int getN() {
return n;
}
#Override
public Consumer<Txn<AService>> getFunction() {
return (txn) -> {
int n = txn.getCurrent().getN();
System.out.println(n);
txn.setCurrent(new AState(--n));
};
}
}
Basically Please program to the interfaces (4 changes listed below):
DefaultService already implements Service
State<AService> change to State<Service>
class AState implements State<Service>
program to the interfaces: class Txn<T extends Service> {
Corrected code below:
import java.util.function.Consumer;
public class GenericsTest {
AService service = new AService("Aservice");
new Txn<>(service).next();
new Txn<>(new DefaultState()).next();
}
}
// ----------------------------------------------------------- //
interface Service {
String getName();
<T extends Service> State<T> getState();// this is unclear how to use generics here
}
interface State<T extends Service> {
Consumer<Txn<T>> getFunction();
int getN();
}
// ----------------------------------------------------------- //
class Txn<T extends Service> {
private T service;
private State<T> current;
Txn(State<T> current) {
this.current = current;
}
Txn(T service) {
this.service = service;
this.current = this.service.getState();
}
int next() {
do {
current.getFunction().accept(this);
} while (current.getN()>0);
return current.getN();
}
public State<T> getCurrent() {
return current;
}
public void setCurrent(State<T> current) {
this.current = current;
}
}
// ----------------------------------------------------------- //
abstract class DefaultService implements Service {
private String name;
public DefaultService(String name) {
this.name = name;
}
public String getName(){
return this.name.toUpperCase();
}
}
class AService extends DefaultService {
public AService(String name) {
super(name);
}
#Override
public State<Service> getState() {
return new AState(6);
}
}
// ----------------------------------------------------------- //
class DefaultState implements State<DefaultService> {
#Override
public Consumer<Txn<DefaultService>> getFunction() {
return (txn) -> System.out.println("hurray now left is to do default at "+txn.getCurrent().getN());
}
#Override
public int getN() {
return 0;
}
}
class AState implements State<Service> {
private int n;
AState(int n) {
this.n = n;
}
#Override
public int getN() {
return n;
}
#Override
public Consumer<Txn<Service>> getFunction() {
return (txn) -> {
int n = txn.getCurrent().getN();
System.out.println(n);
txn.setCurrent(new AState(--n));
};
}
}
Related
I am creating DTO structure with Builder pattern. Because of existence of many requests I created parent request AbstractRequest to create concrete requests - e.g. ConcreteRequest in this example.
Base Buildable interface defines contract to all Requests.
public interface Buildable<T> {
T build();
void validate();
}
Parent request AbstractRequest to create concrete ConcreteRequest that holds parameters used by all descendants (for brevity globalValue only in this example).
public abstract class AbstractRequest {
private final String globalValue;
public AbstractRequest(BuilderImpl builder) {
this.globalValue = builder.global;
}
public interface Builder<T> extends Buildable<T> {
Builder<T> globalValue(String globalValue);
}
public abstract static class BuilderImpl<T> implements Builder<T> {
private String global;
#Override
public Builder<T> globalValue(String globalValue) {
this.global = globalValue;
return this;
}
}
}
Concrete request that has one private parameter localValue:
public final class ConcreteRequest extends AbstractRequest {
private final String localValue;
public ConcreteRequest(BuilderImpl builder) {
super(builder);
this.localValue = builder.localValue;
}
public String getLocalValue() {
return localValue;
}
public static Builder builder(){
return new BuilderImpl();
}
public interface Builder extends AbstractRequest.Builder<ConcreteRequest> {
Builder localValue(String localValue);
}
public static final class BuilderImpl extends AbstractRequest.BuilderImpl<ConcreteRequest> implements Builder {
private String localValue;
#Override
public ConcreteRequest build() {
this.validate();
return new ConcreteRequest(this);
}
#Override
public void validate() {
// do validation
}
#Override
public Builder localValue(String localValue) {
this.localValue = localValue;
return this;
}
}
}
Q: Why is not ConcreteRequest#getLocalValue accessible while ConcreteRequest#build is available?
I modified my code and it seems it works.
public interface Buildable<T> {
T build();
void validate();
}
Parent class:
public abstract class AbstractRequest {
private final String globalValue;
public AbstractRequest(BuilderImpl builder) {
this.globalValue = builder.global;
}
public String getGlobalValue() {
return globalValue;
}
public interface Builder<B extends Builder, C extends AbstractRequest> extends Buildable<C> {
B globalValue(String globalValue);
}
public abstract static class BuilderImpl<B extends Builder, C extends AbstractRequest> implements Builder<B, C> {
private String global;
#Override
public B globalValue(String globalValue) {
this.global = globalValue;
return (B) this;
}
#Override
public void validate() {
if (global == null) {
throw new IllegalArgumentException("Global must not be null");
}
}
}
}
and
public final class ConcreteRequest extends AbstractRequest {
private final String localValue;
public ConcreteRequest(BuilderImpl builder) {
super(builder);
this.localValue = builder.localValue;
}
public static Builder builder() {
return new BuilderImpl();
}
public String getLocalValue() {
return localValue;
}
public interface Builder extends AbstractRequest.Builder<Builder, ConcreteRequest> {
Builder localValue(String localValue);
}
public static final class BuilderImpl extends AbstractRequest.BuilderImpl<Builder, ConcreteRequest> implements Builder {
private String localValue;
#Override
public Builder localValue(String localValue) {
this.localValue = localValue;
return this;
}
#Override
public ConcreteRequest build() {
this.validate();
return new ConcreteRequest(this);
}
#Override
public void validate() {
super.validate();
if (localValue == null) {
throw new IllegalArgumentException("Local must not be null");
}
}
}
}
And now I can see all methods:
I am new to java programming and I am learning generics.I tried to do some generics program by myself and I am getting Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.ashwin.model.Car;.
I have a Vehicle Class:
public class Vehicle {
private int id;
private String name;
private String color;
private int plateNo;
//omitted getters and setters
}
I have a Car class extending Vehicle Class.
public class Car extends Vehicle {
public Car(int id, String name, String color, int plateNo) {
super.setId(id);
super.setColor(color);
super.setPlateNo(plateNo);
}
}
I have CarDAOImpl.java class:
public class CarDAOImpl implements VehicleDAO<Car> {
private static ParkingLot<Car> park=new ParkingLot<Car>(10);
#Override
public boolean insert(Car v) {
if(park.getSpace()==-1) {
return false;
}
else {
park.setSpace(park.getSpace()-1);
park.setVehicle(v);
return true;
}
}
#Override
public boolean delete(Car k) {
if(park.getSpace()==10) {
return false;
}
else {
boolean result=park.deleteVehicle(k);
return result;
}
}
#Override
public Car[] getAll() {
return park.getVehicle();
}
}
I have another ParkingLot.java class:
public class ParkingLot<T> {
private int space;
private T[] vehicle;
public ParkingLot() {
}
public ParkingLot(int sp) {
this.vehicle=(T[])new Object[sp];
this.space=sp;
}
public int getSpace() {
return space;
}
public void setSpace(int space) {
this.space = space;
}
public T[] getVehicle() {
return vehicle;
}
public void setVehicle(T vehicle) {
this.vehicle[space]=vehicle;
}
public <T extends Vehicle> boolean deleteVehicle(T v) {
for(int i=0;i<vehicle.length;i++) {
if(((Vehicle) vehicle[i]).getId()==v.getId()) {
vehicle[i]=null;
return true;
}
}
return false;
}
}
My main method is:
public class Main {
public static void main(String[] args) {
VehicleDAO<Car> v=new CarDAOImpl();
boolean inserted=v.insert(new Car(1,"ford","Red",1234));
System.out.println(inserted);
Car[] c=v.getAll();
for(int i=0;i<c.length;i++)
{
System.out.println(c[i]);
}
}
}
I am getting error at this line of CarDAOImpl.java class:
#Override
public Car[] getAll() {
return park.getVehicle();
}
The exception is:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.ashwin.model.Car;
You need to update your constructor to include the class object as a parameter:
public ParkingLot(Class<T> clazz, int sp) {
this.vehicle= (T[]) Array.newInstance(clazz, sp);
this.space=sp;
}
And your variable declaration should look like this:
private static ParkingLot<Car> park = new ParkingLot<>(Car.class, 10);
I have class-Composite:
public class CompositeText implements ComponentText {
private TypeComponent type;
private String value;
private final List<ComponentText> childComponents;
private CompositeText() {
childComponents = new ArrayList<>();
}
public CompositeText(String value, TypeComponent typeComponent) {
this.value = value;
this.type = typeComponent;
childComponents = new ArrayList<>();
}
#Override
public void add(ComponentText componentText) {
childComponents.add(componentText);
}
#Override
public void remove(ComponentText componentText) {
childComponents.remove(componentText);
}
#Override
public TypeComponent getComponentType() {
return this.type;
}
#Override
public ComponentText getChild(int index) {
return childComponents.get(index);
}
#Override
public int getCountChildElements() {
return childComponents.size();
}
#Override
public int getCountAllElements() {
return childComponents.stream()
.mapToInt(ComponentText::getCountAllElements)
.sum();
}
#Override
public String toString() {
return null;
}
}
I created classes that perform the same action - parsing, parsing text into paragraphs, into sentences, into tokens, into symbols.
public class IntoParagraphParser implements ActionParser {
// call IntoSentenceParser
}
public class IntoSentenceParser implements ActionParser {
// call IntoLexemeParser
}
public class IntoLexemeParser implements ActionParser {
// call IntoSymbolParser
}
public class IntoSymbolParser implements ActionParser {
}
All data is stored in List <ComponentText> childComponents in class-Composite - CompositeText.
How to properly create a method so that it prints all the data that is inside the composite?
I think this will be the method toString() in CompositeText.
Class IntoParagraphParser look:
public class IntoParagraphParser implements ActionParser {
private static final String PARAGRAPH_SPLIT_REGEX = "(?m)(?=^\\s{4})";
private static final IntoParagraphParser paragraphParser = new IntoParagraphParser();
private static final IntoSentenceParser sentenceParser = IntoSentenceParser.getInstance();
private IntoParagraphParser() {
}
public static IntoParagraphParser getInstance() {
return paragraphParser;
}
public ComponentText parse(String text) throws TextException {
ComponentText oneParagraph;
ComponentText componentParagraph = new CompositeText(text, TypeComponent.PARAGRAPH);
String[] arrayParagraph = text.split(PARAGRAPH_SPLIT_REGEX);
for(String element: arrayParagraph) {
oneParagraph = new CompositeText(element, TypeComponent.PARAGRAPH);
oneParagraph.add(sentenceParser.parse(element));
componentParagraph.add(oneParagraph);
}
return componentParagraph;
}
}
Need #Override the method toString() in CompositeText like this:
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (ComponentText component : childComponents) {
builder.append(component.toString());
}
return builder.toString();
}
But how to write this code correctly with Stream API?
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
childComponents.stream().map(...????
return builder.toString();
}
I would appreciate any help in solving the following question.
Design and implement a subclass of GenericOrder called ComputerPartyOrder that takes an arbitrary number of different classes of ComputerPart objects, Peripheral objects, Cheese objects, Fruit objects and Service objects.
here is the code for Product class and GerericOrder class.
abstract class Product {
protected float price;
// return the price of a particular product
abstract float price();
//public getType() {
//
//}
}
//------------------------------------------------------------
class ComputerPart extends Product {
public ComputerPart(float p) {
price = p;
}
public float price() { return price; }
}
class Motherboard extends ComputerPart {
protected String manufacturer;
public Motherboard(String mfg, float p) {
super(p);
manufacturer = mfg;
}
public String getManufacturer() { return manufacturer; }
}
class RAM extends ComputerPart {
protected int size;
protected String manufacturer;
public RAM(String mfg, int size, float p) {
super(p);
this.manufacturer = mfg;
this.size = size;
}
public String getManufacturer() { return manufacturer; }
}
class Drive extends ComputerPart {
protected String type;
protected int speed;
public Drive(String type, int speed, float p) {
super(p);
this.type = type;
this.speed = speed;
}
public String getType() { return type; }
public int getSpeed() { return speed; }
}
class Peripheral extends Product {
public Peripheral(float p) {
price = p;
}
public float price() { return price; }
}
class Printer extends Peripheral {
protected String model;
public Printer(String model, float p) {
super(p);
this.model = model;
}
public String getModel() { return model; }
}
class Monitor extends Peripheral {
protected String model;
public Monitor(String model, float p) {
super(p);
this.model = model;
}
public String getModel() { return model; }
}
class Service extends Product {
public Service(float p) {
price = p;
}
public float price() { return price; }
}
class AssemblyService extends Service {
String provider;
public AssemblyService(String pv, float p) {
super(p);
provider = pv;
}
public String getProvider() { return provider; }
}
class DeliveryService extends Service {
String courier;
public DeliveryService(String c, float p) {
super(p);
courier = c;
}
public String getCourier() { return courier; }
}
//-------------------------------------------------------
class Cheese extends Product {
public Cheese(float p) {
price = p;
}
public float price() { return price; }
}
class Cheddar extends Cheese {
public Cheddar(float p) {
super(p);
}
}
class Mozzarella extends Cheese {
public Mozzarella(float p) {
super(p);
}
}
class Fruit extends Product {
public Fruit(float p) {
price = p;
}
public float price() { return price; }
}
class Apple extends Fruit {
public Apple(float p) {
super(p);
}
}
class Orange extends Fruit {
public Orange(float p) {
super(p);
}
}
GenericOrder:
import java.util.ArrayList;
import java.util.List;
public abstract class GenericOrder<T> extends Product {
private static long counter = 1;
private final long id = counter++;
private List<T> Item;
public GenericOrder() {
Item = new ArrayList<T>();
}
public long getid() {
return id;
}
public void addItem(T newItem) {
Item.add(newItem);
}
public List<T> getItem() {
return Item;
}
public void setItem(List<T> Item) {
this.Item = Item;
}
}
EDIT: Code so far
public abstract class ComputerPartyOrder extends GenericOrder {
GenericOrder GOrder = new GenericOrder() {
#Override
float price() {
return 0;
}
};
public void input(Product newitem) {
GOrder.addItem(newitem);
}
public void output() {
System.out.println(GOrder.getItem());
}
}
You have the right idea, but GenericOrder does not need a type parameter T. Instead, you can set the type of Item to Product (the superclass of all the different types of products).
public abstract class GenericOrder extends Product {
private static long counter = 1;
private final long id = counter++;
private List<Product> Item;
public GenericOrder() {
Item = new ArrayList<Product>();
}
public long getid() {
return id;
}
public void addItem(Product newItem) {
Item.add(newItem);
}
public List<Product> getItem() {
return Item;
}
public void setItem(List<Product> Item) {
this.Item = Item;
}
}
You will still be able to call addItem with any instance of a subclass of Product.
I would also suggest renaming Item to item, uppercase names are usually used for types, not variables.
I am implementing Hierarchical Builder Pattern. I have used generics to make return type of my Parent Builder setter as that for child. Still I am facing problem when I use the child setter method after calling parent setter method. I don't want to define my child specific method (setEngine(String) here) in my Parent Builder. Is there any other way around for this problem?
I have made an example snippet for the mentioned problem, identical to this case.
CarFactory -> It returns the object of specific car that user wants
Car -> Parent for all Car types, Swift, Duster etc
Swift -> Specific car
Parent->Child Hierarchy
Car -> Swift
CarBuilder -> SwiftBuilder
Car.java
package Builders;
public class Car {
int tyre;
int seat;
public int getTyre() {
return tyre;
}
public void setTyre(int tyre) {
this.tyre = tyre;
}
public int getSeat() {
return seat;
}
public void setSeat(int seat) {
this.seat = seat;
}
}
Swift.java
package Builders;
public class Swift extends Car {
boolean safetyAirbag;
String engine;
public boolean isSafetyAirbag() {
return safetyAirbag;
}
public String getEngine() {
return engine;
}
public void setSafetyAirbag(boolean safetyAirbag) {
this.safetyAirbag = safetyAirbag;
}
public void setEngine(String engine) {
this.engine = engine;
}
}
CarBuilder.java
package Builders;
public abstract class CarBuilder {
int tyre;
int seat;
public abstract <B extends CarBuilder>B self();
public abstract <T extends Car>T typeOfCar();
public <B extends CarBuilder>B setTyre(int tyre) {
this.tyre = tyre;
return self();
}
public <B extends CarBuilder> B setSeat(int seat) {
this.seat = seat;
return self();
}
public <C extends Car>C build()
{ C car=this.typeOfCar();
car.setSeat(seat);
car.setTyre(tyre);
return car;
}
}
SwiftBuilder.java
package Builders;
public class SwiftBuilder extends CarBuilder {
String engine;
#Override
public
SwiftBuilder self() {
return this;
}
#Override
public
Swift typeOfCar() {
return new Swift();
}
public SwiftBuilder setEngine(String string) {
this.engine=string;
return this;
}
public Swift build()
{ Swift s=(Swift)super.build();
return s;
}
}
CarFactory.java
package Builders;
public class CarFactory {
public SwiftBuilder getSwiftDesire()
{
return new SwiftBuilder();
}
}
Drivers.java
package Builders;
public class Drivers {
Swift getMyCar() {
Swift s= this.factory().getSwiftDesire().setSeat(4).setEngine("CC").build();
return s;
}
CarFactory factory() {
return new CarFactory();
}
}
In Drivers.java class I am not able to use setEngine() method after setSeat() method,
this.factory().getSwiftDesire().setSeat(4).setEngine("CC").build();
I don't want to declare setEngine in parent class, is there any way around for same?
Thank you in advance!
You need to use generics on the class level, not on the method level, in your CarBuilder:
package Builders;
public abstract class CarBuilder<B extends CarBuilder<B, C>, C extends Car> {
int tyre;
int seat;
public abstract B self();
public abstract C typeOfCar();
public B setTyre(int tyre) {
this.tyre = tyre;
return self();
}
public B setSeat(int seat) {
this.seat = seat;
return self();
}
public C build() {
C car = this.typeOfCar();
car.setSeat(seat);
car.setTyre(tyre);
return car;
}
}
And then you define your SwiftBuilder:
package Builders;
public class SwiftBuilder extends CarBuilder<SwiftBuilder, Swift> {
String engine;
#Override
public SwiftBuilder self() {
return this;
}
#Override
public Swift typeOfCar() {
return new Swift();
}
public SwiftBuilder setEngine(String string) {
this.engine = string;
return this;
}
public Swift build() {
Swift s = super.build();
s.setEngine(engine);
return s;
}
}
And it works.