I am setting values to an API and I need to set values for class data type variable which is an array and I need to know how to set the value?
I have tried in java, and I keep on getting compile time error
Items equipmenxxts = new Items ();
equipmenxxts.setDKU(savedRequest.DKUType());
equipmenxxts.setQuantity(savedRequest.getQuantity());
item.setEquipments(equipmenxxts);
**//error setEquipments(Items[]) in ItemOrder cannot be applied to (Items)**
api class to set values
public class ItemOrder implements java.io.Serializable {
private java.lang.String company,
private Items[] equipments; // class given below
public ItemOrder() {
}
public ItemOrder(Items[] equipments) {
this.equipments = equipments;
}
public java.lang.String getCompany() {
return company;
}
public void setCompany(java.lang.String company) {
this.company = company;
}
public Items[] getEquipments() {
return equipments;
}
public void setEquipments(Items[] equipments) {
this.equipments = equipments;
}
}
data type of this class used above
public class Items implements java.io.Serializable {
private java.lang.String DKU;
private int quantity;
public Items() {
}
public Items(String DKU, int quantity) {
this.DKU = DKU;
this.quantity = quantity;
}
}
api class to set up value
#Service("clApiService")
public class NewApiImpl implements NewApiService {
#Override
public Request completeapiNewOrderRep(ServletWebRequest webRequest) {
try {
ItemOrder item = new ItemOrder();
item.setCompany(req.getCompany());
item.setEquipments(); //error setEquipments(Items[]) in ItemOrder cannot be applied to ()**
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
I expect just to set the values of (req.setDKU and Quantity) to item.setEquipments( );
.setEquipments(Items[]) demands an array of items, but you pass only a single item.
try creating an array containing your item first:
item.setEquipments(new Items[] {equipmenxxts});
Alternatively you can create equipmentxxts as an array:
final Items[] equipmenxxts = new Items[1];
equipmenxxts[0].setDKU(savedRequest.DKUType());
equipmenxxts[0].setQuantity(savedRequest.getQuantity());
item.setEquipments(equipmenxxts);
Also, when setting a number of items this way, make sure you do not expose your class' internal state, unless you really know what you are doing—and why! You may consider a variable number of arguments for your method:
public Items[] getEquipments() {
return Arrays.copyOf(equipments, equipments.length);
}
public void setEquipments(Items... equipments) {
this.equipments = Arrays.copyOf(equipments, equipments.length);
}
Now you can either call .setEquipments(...) with an array as parameter, or with a custom number of items:
item.setEquipments(e1, e2, e3);
You may reconsider the names of your variables. I do not understand, why an ItemOrder object is called "item" - and you set "Items" objects through .setEquipments(...)
For what I studied, making a set for an array is somewhat a design error. You can, however, make a void setItems(Items i), introducing on parameters a certain index of an ItemOrder or you can make a "superset", which is not a real set:
public void superSet(ItemOrder io){
this.equipments=io.setEquipments(Items[] i);
}
Related
I have a parent class named Set representing a set of a tennis matches.
public class Set {
private String set1;
private String set2;
private String set3;
//private Object[] match;
public Set() {
setSet1(set1);
setSet2(set2);
setSet3(set3);
}
public void setSet1(String set1) {
this.set1 = set1;
}
public String getSet1() {
return set1;
}
public void setSet2(String set2) {
this.set2 = set2;
}
public String getSet2() {
return set2;
}
public void setSet3(String set3) {
this.set3 = set3;
}
public String getSet3() {
return set3;
}
public String toString(){
return String.format("set1: %s, set2: %s, set3: %s", set1, set2, set3);
}
}
and a sub class of Set named SingleSet where I try to add the sets into an array named `game.
public class SingleSet extends Set{
private Object homePlayer;
private Object awayPlayer;
private String[] game;
public SingleSet(Object homePlayer, Object awayPlayer){
super();
game = new String[3];
game[0] = super.getSet1();
game[1] = super.getSet2();
game[2] = super.getSet3();
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
public void setHomePlayer(Object homePlayer) {
this.homePlayer = homePlayer;
}
public Object getHomePlayer() {
return homePlayer;
}
public void setAwayPlayer(Object awayPlayer) {
this.awayPlayer = awayPlayer;
}
public Object getAwayPlayer() {
return awayPlayer;
}
public void setGame(String[] game) {
this.game = game;
}
public String[] getGame() {
return game;
}
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
}
This is where I am trying to add the Sets from my parents class into my sub class (this is for FXML, so the code is in my controller):
public void submit() {
SingleSet game1 = new SingleSet(homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue());
game1.setSet1(set1Box1.getText());
game1.setSet2(set1Box2.getText());
game1.setSet3(set1Box3.getText());
System.out.println(game1);
}
When I print the result, my array values are null. I tried printing them individually and that worked fine, so I know the set1Box.getText() is working fine.
The reason you are seeing null values when you print is because they are actually null.
SingleSet game1 = new SingleSet(homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue()); is creating a new SingleSet, which extends Set.
SingleSet constructor makes a super() call to Set constructor.
When Set is created for the first time, all its values are null. Then constructor kicks in, but Set constructor actually does nothing, so Set's instance variables remain null.
Ten SingleSet carries on on building your object with parameter given, which do nothing for setting a value for set1, set2, set3.
game1.setSet1(set1Box1.getText());
game1.setSet2(set1Box2.getText());
game1.setSet3(set1Box3.getText());
They actually set a value to set1, set2, set3 (since you are saying that set1Box1.getText() and others are working). So why you are still seeing null when printing?
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
That's why: you are printing game[0], and so on, that are actually null because when you set your game array, those values where null!
public SingleSet(Object homePlayer, Object awayPlayer){
super(); //setting null values to set1, set2, set3
game = new String[3];
game[0] = super.getSet1(); //this returns null!
game[1] = super.getSet2(); //this returns null!
game[2] = super.getSet3(); //this returns null!
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
Print some values when you build your object and will see :)
To solve, one way is to use a parametrized constructor public Set(String set1, String set2, String set3), use a parametrized child constructor public SingleSet(String set1, String set2, String set3, Object homePlayer, Object awayPlayer) and a parametrized call to super, super(set1, set2, set3)
Then you should set values when creating game1
SingleSet game1 = new SingleSet(set1Box1.getText(), set1Box1.getText(), set1Box1.getText()homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue());
You are not setting anything in Set's default constructor
Should really find a better name for your class as "Set" is confusing with collections Set.
Make use of immutable for both of your classes to save yourself from trouble - remove all the setters and initialize in constructor.
I'm not that good at tennis scoring rules, but to my best knowledge a "set" has number of "games", and "match" consists from a number of sets. What is the logic for this relation "Set <- SingleSet"? What if you change your hierarchy in this way (in pseudo-code, will skip most method bodies for brevity):
class Player{
private String name;
public Player(String name);
}
class Match{
private Player homePlayer;
private Player awayPlayer;
private List<Set> sets;
public Match(Player homePlayer, Public awayPlayer);
public List<Set> getSets(){
if(sets == null){
sets = new ArrayList<>();
}
return sets;
}
}
class Set{
public Set(Game... games);
}
class Game{
// game score details
public Game(int scoreHomePlayer, int scoreAwayPlayer);
}
So that in your Controller, you could use it like this:
Match match = new Match(new Player("Williams"), new Player("Johnson"))
match.getSets().add(new Set(
new Game(6, 1),
new Game(4, 6),
new Game(7, 0)
// etc.
))
You could further refactor #4 hierarchy and spare all these "new ()" constructor calls using Builder Pattern, something along the line:
Match match = new MatchBuilder("Williams","Johnson").addSet()
.addGame(6,1).addGame(4,6).addGame(7,0)
.build()
you should override set method .Instead of in the set after the constructor is instantiated
public SingleSet(Object homePlayer, Object awayPlayer) {
super();
game = new String[3];
// game[0] = super.getSet1();
// game[1] = super.getSet2();
// game[2] = super.getSet3();
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
#Override
public void setSet1(String set1) {
this.game[0]=set1;
super.setSet1(set1);
}
#Override
public void setSet2(String set2) {
this.game[1]=set2;
super.setSet2(set2);
}
#Override
public void setSet3(String set3) {
this.game[2]=set3;
super.setSet3(set3);
}
I have created a class like this, which contains a bunch of arraylist as you can see. I've been setting the array with the methods add.. and then retrieving it with get.., when i tried to System.out.println numberofcitizen for example it is returning 0. Note that i have instantiated the class in another class to set the values.
public int numberOfCitizen;
private final ArrayList<Integer> citizenid = new ArrayList<>();
private final ArrayList<String> citizenName = new ArrayList<>();
private final ArrayList<Integer> citizenWaste = new ArrayList<>();
private final ArrayList<Float> longitude = new ArrayList<>();
private final ArrayList<Float> latitude = new ArrayList<>();
private final ArrayList<String> address = new ArrayList<>();
public void working() {
System.out.println("executing fine");
}
public void setnoOfcit(int number) {
this.numberOfCitizen = number;
}
public int getnumber() {
return this.numberOfCitizen;
}
public void addCitizenId(int citizen) {
citizenid.add(citizen);
}
public int getCitizenid(int i) {
int citId = citizenid.get(i);
return citId;
}
public void addCitizenName(String citizenname) {
citizenName.add(citizenname);
}
public String getCitizenName(int i) {
return citizenName.get(i);
}
public void addCitizenWaste(int waste) {
citizenWaste.add(waste);
}
public int getCitizenWaste(int i) {
return citizenWaste.get(i);
}
public void addLatitude(float lat) {
latitude.add(lat);
}
public float getLat(int i) {
return latitude.get(i);
}
public void addlng(float lng) {
longitude.add(lng);
}
public float getlng(int i) {
return longitude.get(i);
}
com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder vrpBuilder = com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder.newInstance();
public void runVPRSolver() {
System.out.println(numberOfCitizen);
System.out.println(getCitizenName(0));
//create a loop to fill parameters
Probable source of problem :
numberOfCitizen is a member attribute that you seem to never change. If you want it to represent the number of elements in your lists, either use citizenName.size() or increment the value of numberOfCitizen in one of the add methods.
Design flaw :
Your design takes for granted that your other class always use that one properly. Anytime you or someone uses that class, he must make sure that he add every single element manually. This adds code that could be grouped inside your class, which would be cleaner and easier to maintain.
So instead of several add method like this :
addCitizenid();
addCitizenName();
addCitizenWaste();
addLongitude();
addLatitude();
addAddress();
Design an other Citizen class which will contain those elements, and use a single list of instances of that class. That way you can use only one method :
private List<Citizen> citizenList = new ArrayList<>();
public void addCitizen(Citizen c) {
/*Add element in your list*/
citizenList.add(c);
}
This programming methodology is called "Encapsulation" which you can read about here
You need to increment numberOfCitizen in your add methods. For example:
public void addCitizenId(int citizen){
citizenid.add(citizen);
numberOfCitizen++;
}
I would also suggest encapsulating your variables into Objects, so create a citizen class:
public class Citizen {
private Integer id;
private Integer name;
private Integer waste;
}
And change your variable to an ArrayList of objects:
ArrayList<Citizen> citizens;
I would like to make a generic method to get a List from the parameter object.
The problem is because I have a declared object with a instance of the other class that extends the declared class.
I don't want to use the instanceof solution because the number of classes that extends LimitedValue can be big.
I thought to use reflection for a solution, but I don't know how to use that with an instance of object, in this part of the code:
Class cls = Class.forName(limitedValue.getClass().getName());
Object obj = cls.newInstance();
//This is wrong, I don't want a new instance.
Method[] methods = cls.getDeclaredMethods();
for(int x= 0; x < methods.length; x++) {
Method method = methods[x];
if ("java.util.List".equals(method.getReturnType().getName())) {
//How to get the value of this method from limitedValue instance ?
}
}
This is my full code:
public class CalculatorLimitedValue {
public static void main(String[] args) throws Exception {
StoreItem storeItem = new StoreItem(1L, "Name of StoreItem", 50L);
List listOfStoreItems = new ArrayList();
listOfStoreItems.add(storeItem);
LimitedValue limitedValue0 = new Store(listOfStoreItems);
List firstList = calculator(limitedValue0);
//do something with the list
SupermarketItem supermarketItem = new SupermarketItem(1L, "Name of SupermarketItem", 21L);
List listOfSupermarketItems = new ArrayList();
listOfSupermarketItems.add(supermarketItem);
LimitedValue limitedValue1 = new Supermarket(listOfSupermarketItems);
List secondList = calculator(limitedValue1);
//do something with the list
}
/** This is the method that I'd like to make generic to return a List */
private static List calculator(LimitedValue limitedValue) throws Exception{
Class cls = Class.forName(limitedValue.getClass().getName());
Object obj = cls.newInstance();
//This is wrong, I don't want a new instance.
Method[] methods = cls.getDeclaredMethods();
for(int x= 0; x < methods.length; x++) {
Method method = methods[x];
if ("java.util.List".equals(method.getReturnType().getName())) {
//How to get the value of this method from limitedValue instance ?
}
}
/* I don't want to use this one way, because my classes that extends LimitedValue
can be big. I would like to made a generic way to get de list of classes. */
if (limitedValue instanceof Store) {
System.out.println("This is a store");
return ((Store) limitedValue).getStoreItems();
} else if (limitedValue instanceof Supermarket) {
System.out.println("This is a supermarket");
return ((Supermarket) limitedValue).getSupermarketItems();
}
return null;
}
}
If it help, these are my other classes:
LimitedValue.class
public class LimitedValue { }
StoreItem.class
public class StoreItem {
private Long id;
private String nameOfStoreItem;
private Long valueOfStoreItem;
public StoreItem(Long id, String nameOfStoreItem, Long valueOfStoreItem){
this.id = id;
this.nameOfStoreItem = nameOfStoreItem;
this.valueOfStoreItem = valueOfStoreItem;
}
//getters and setters...
}
SupermarketItem.class
public class SupermarketItem {
private Long id;
private String nameOfSupermarketItem;
private Long valueOfSupermarketItem;
public SupermarketItem() {
}
public SupermarketItem(Long id, String nameOfSupermarketItem, Long valueOfSupermarketItem) {
this.id = id;
this.nameOfSupermarketItem = nameOfSupermarketItem;
this.valueOfSupermarketItem = valueOfSupermarketItem;
}
//getters and setters...
}
Store.class
public class Store extends LimitedValue {
private List<StoreItem> storeItems;
public Store(List<StoreItem> storeItems) {
this.storeItems = storeItems;
}
//getters and setters
}
Supermarket.class
public class Supermarket extends LimitedValue {
private List<SupermarketItem> supermarketItems;
public Supermarket(List<SupermarketItem> supermarketItems) {
this.supermarketItems = supermarketItems;
}
//getters and setters
}
You could try to use reflection here to try to achieve what you want, but it would be better to reconsider your overall design and try to use a better object oriented design that solves the problem at hand.
In particular, lets say we consider adding a method called getItems to the LimitedValue class that returns a List of items, which may be SupermarketItems or may be StoreItems. If it is structured correctly, you won't need to know the actual type because the code will be abstracted over it polymorphically.
public abstract class LimitedValue {
List<? extends Item> getItems();
}
We've now defined a new method on LimitedValue, but we also have to consider that we've introduced this new Item thing. I note that the SupermarketItem and StoreItem all share similiar attributes, name, id and value, so it seems that it might be possible to use a single class to represent them all.
public abstract class Item {
final Long id;
final String name;
final Long value;
public Item(final Long id, final Long name, final Long value) {
this.id = id;
this.name = name;
this.value = value;
}
String getName() {
return name;
}
// other getters and setters
}
public class SupermarketItem extends Item {
public SupermarketItem(final Long id, final Long name, final Long value) {
super(id, name, value);
}
}
public class StoreItem extends Item {
public StoreItem(final Long id, final Long name, final Long value) {
super(id, name, value);
}
}
Now we've completely abstracted away the need for any reflection when accessing these objects - you can simply call item.getValue() as you will know that every item in the list is of type Item.
Of course, you'll also need to refactor the Store and SuperMarket classes, for example:
public class Supermarket extends LimitedValue {
private List<SupermarketItem> supermarketItems;
public Supermarket(List<SupermarketItem> supermarketItems) {
this.supermarketItems = supermarketItems;
}
public List<? extends Item> getItems() {
return supermarketItems;
}
}
and because you are only returning a List<Item> you always know what is in it, and you can change your main code to work with this.
This is a much cleaner long term solution.
To get the List value, use Method#invoke:
List list = method.invoke(limitedValue);
You don't need Object obj = cls.newInstance(); - you're not using it at all in the method.
In any case, you're making it very difficult for yourself. You could also define an interface
public interface HasList<E> {
List<E> getList();
}
and have all classes implement this.
I'm making a small RPG. There is an Item class which is the parent of each item in the game. These items could be Potion (which is a class) or Bandage (which is a class).
The Item class looks like this:
public class Item
{
int qty;
String name;
Hero hero1;
public void passHero(Hero hero1)
{
this.hero1 = hero1;
}
public void use()
{
if(qty == 0)
{
System.out.println("You have no more of this item to use.");
}
else
{
qty--;
}
}
public void addInv(int value)
{
qty = qty + value;
}
}
A method for passing in the Hero class.
A method for using an item.
A method for adding to the inventory of the item.
This method activates these item classes:
public void initializeItemInventory()
{
items[0] = new Potion();
items[1] = new Bandage();
}
And this method would theoretically print all the items and their quantities:
public void useInventory()
{
for(int i = 0; i<items.length; i++)
{
System.out.println("Enter: " + i + " for " + items[i].name);
}
int response = input.nextInt();
items[response].use();
}
The Potion class, as an example, has an instance variable like:
String name = "Potion";
So my question. Why isn't the name variable from Potion being called correctly in the useInventory method. It returns null which tells me it's returning the parent class Item name, and not the name of the individual subclass variables.
public class Item
{
int qty;
String name;
...
The Item class already has name, and that's what you access from an Item-typed variable:
items[0].name
So if you have
public class Potion extends Item
{
String name = "Potion";
...
then the Potion class has two name fields:
Potion p = new Potion();
System.out.println(p.name);
System.out.println((Item) p).name);
As you say, you want polymorphism, but it only applies to methods. Therefore you need a getter:
public class Item
{
String name;
public String getName() { return name; }
...
In the Potion subclass you may have
public class Potion extends Item
{
public Potion() { this.name = "Potion"; }
...
and items[0].getName() will now work as expected.
Additional note
I'll add this to show a bit of the power of polymorphism.
If you happened to have the name property always the same for all the instances of the same class, you could easily refactor your getter-based solution by completely eliminating the need to store a name variable:
public class Item
{
public String getName() { return "Generic item"; }
...
public class Potion extends Item
{
#Override public String getName() { return "Potion"; }
...
Instead of declaring a new variable in your subclass like "String name = "Potion";"
Use your constructor to pass the value to your superclass, something like this:
// the Item supuerclass has one constructor
public Item(name) {
this.name = name;
}
// the Potion subclass has one constructor
public Potion() {
super("Potion");
}
CLARIFICATION:
I do not know the objects name. That is where the problem comes in. I am creating an object like such:
`new Object(String attributes);
I am trying to run code in another class such as:
***.getStuff();
the trick to it is, there is no name for the Object. but i do know what String attributes is
The question: Is there any way to accomplish this without using the dreaded for loop?
This question is a bit tricky to word, but I will try my best. What I want to is get an object that matches a particular field without making a messy for loop. Something along the lines of:
Object A has the field String name.
String nameObj = "Tickle";
Object A has the name "Tickle"
if(nameObj.equals(Object A)){
//bla bla
}
Very confusing wording, yes. Sorry about that. I want to use Object A in my code without having to figure out which object it is, assuming all I have is its name. I am looking for a shortcut around using a for loop, I suppose.
Feel free to ask questions about what I am looking for. Sorry about the terribly worded question.
Poor coding, but this is what I am looking for...
nameObj.getName().getObjectA();
If you have a bunch of objects with names, and you want to grab an object by its name, I suggest you look up the class HashMap. HashMap lets you put in objects under keys, and when you give the hash map a key it returns the object associated with that key. So in your example, the keys would be string names.
Take at this implementation, that demonstrates what #Patashu said, create a map to the objects, in this case I just add an abstract class at the top of all.
import java.util.HashMap;
public class FindMeBaby {
public static void main(String[] args) {
Factory.add(new NiceGuy("first one"));
Factory.add(new FirstChild("ok im late"));
System.out.println(Factory.get("first one")
.getVeryImportantInformationThatOnlyThisClassKnows());
}
}
abstract class ParentOfAll {
protected String id;
public ParentOfAll(String id) {
this.id = id;
}
public String getId(){
return id;
}
public abstract String getVeryImportantInformationThatOnlyThisClassKnows();
}
class FirstChild extends ParentOfAll {
public FirstChild(String id) {
super(id);
}
public String getVeryImportantInformationThatOnlyThisClassKnows() {
return "this is a secret";
}
}
class NiceGuy extends ParentOfAll {
public NiceGuy(String id) {
super(id);
}
public String getVeryImportantInformationThatOnlyThisClassKnows() {
return "to say the true, i'm not that nice :)";
}
}
class Factory {
private static HashMap allTheObjects = new HashMap();
public static Object add(ParentOfAll object) {
allTheObjects.put(object.getId(), object);
return object;
}
public static ParentOfAll get(String key) {
return (ParentOfAll) allTheObjects.get(key);
}
}
This is another version, of the same implementation with a more transparent aproach, without the Factory class, the Parent itself will keep track of the instances and save in a list.
import java.util.HashMap;
public class FindMeBaby {
public static void main(String[] args) {
NiceGuy foo = new NiceGuy("first one");
FirstChild bar = new FirstChild("ok im late");
System.out.println(ParentOfAll.get("first one")
.getVeryImportantInformationThatOnlyThisClassKnows());
}
}
abstract class ParentOfAll {
protected String id;
public ParentOfAll(String id) {
this.id = id;
add(this);
}
public String getId() {
return id;
}
public abstract String getVeryImportantInformationThatOnlyThisClassKnows();
private static HashMap allTheObjects = new HashMap();
private static Object add(ParentOfAll object) {
allTheObjects.put(object.getId(), object);
return object;
}
public static ParentOfAll get(String key) {
return (ParentOfAll) allTheObjects.get(key);
}
}
class FirstChild extends ParentOfAll {
public FirstChild(String id) {
super(id);
}
public String getVeryImportantInformationThatOnlyThisClassKnows() {
return "this is a secret";
}
}
class NiceGuy extends ParentOfAll {
public NiceGuy(String id) {
super(id);
}
public String getVeryImportantInformationThatOnlyThisClassKnows() {
return "to say the true, i'm not that nice :)";
}
}