I am having an issue with declaring and initializing object arrays within Java using jGrasp. This is an assignment and I copied the code straight from the book and changed the class and array name. I have tried assigning and initializing without an array by using 'itemA, itemB, itemC' with the same duplicate output as you can see at the bottom of the code.
Driver class:
class Driver
{
public static void main(String[] args)
{
RetailItem[] item = new RetailItem[3];
item[0] = new RetailItem("a", 1, 1);
item[1] = new RetailItem("b", 2, 2);
item[2] = new RetailItem("c", 3, 3);
for (int i = 0; i < item.length; i++)
{
System.out.printf("item: " + item[i].getItemName());
}
}
The output results in:
item: c
item: c
item: c
I do not understand as I am a beginner as to why the output is always the last array object initialized.
The output that I am attempting is:
item: a
item: b
item: c
Here is my RetailItem class:
class RetailItem
{
private static String itemName;
private static int unitsOnHand;
private static double priceEach;
//Constructor(s)
public RetailItem(String name, int qty, double price)
{
itemName = name;
unitsOnHand = qty;
priceEach = price;
}
//Public Methods
public static double getPriceEach()
{
return priceEach;
}
public static String getItemName()
{
return itemName;
}
public static int getUnitsOnHand()
{
return unitsOnHand;
}
}
Your problem is that itemName (and all your other variables) have been declared static. This binds them to the class, not to an instance, so when your constructor alters itemName, it alters that variable for the whole class.
To see what I mean by "class variable", try this: define a main method in RetailItem that looks like this:
public static void main(String[] args) {
// Print the property of the RetailItem *class*: remember, you don't even have an instance of the class at this point.
System.out.println(RetailItem.itemName); // null
RetailItem item = new RetailItem("a", 1, 1);
// Print the property of the class again, ignoring the instance that you created.
System.out.println(RetailItem.itemName); // "a"
}
To resolve this, just remove the static declaration from anything you intend to be an instance variable (as well as the setters/getters!).
private String itemName;
public String getItemName() {
return itemName;
}
The problem is that you're setting the itemName, unitsOnHand, and priceEach as static. Basically this means that all instances of RetailItem will have the same value for each of those variables. If you remove the static keyword each instance will have their own itemName, unisOnHand, and priceEach variables.
Related
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 have a class Components:
public class Components {
int numberOfNets;
String nameOfComp;
String nameOfCompPart;
int numOfPin;
public components(int i, String compName, String partName, int pin) {
this.numberOfNets = i;
this.nameOfComp = compName;
this.nameOfCompPart = partName;
this.numOfPin = pin;
}
}
Inside another class I created an arraylist of Components class:
List<Components> compList = new ArrayList<Components>();
Later in the code, I am adding the elements in List in this way:
compList.add(new Components(0,compName,partName,0));
See, here numberOfNets and numOfPin variables in Components class are initiated with 0 values. But these values are getting calculated/incremented in a later part of code and hence I need to update the new values of only these two variables in each list element. Now from ArrayList doc I get the idea of updating a list element using its index by set operation. But I am confused how to set/update a particular variable of a class in an ArrayList of a class. I need to update only these two mentioned variables, not all of the four variables in Components class. Is there any way to do that?
You should add getter/setter to your component class so that outer class can update component's members
public class Components {
private int numberOfNets;
private String nameOfComp;
private String nameOfCompPart;
private int numOfPin;
public components(int i, String compName, String partName, int pin) {
setNumberOfNets(i);
setNameOfComp(compName);
setNameOfCompPart(partName);
setNumOfPin(pin);
}
public void setNumberOfNets(int numberOfNets) {
this.numberOfNets = numberOfNets;
}
// Similarly other getter and setters
}
You can now modify any data by using following code because get() will return reference to original object so modifying this object will update in ArrayList
compList.get(0).setNumberOfNets(newNumberOfNets);
Example code.
public class Main {
public static void main(String[] args) {
List<Components> compList = new ArrayList<Components>();
compList.add(new Components(0, "compName", "partName", 0));
System.out.println(compList.get(0).toString());
compList.get(0).numberOfNets = 3;
compList.get(0).numOfPin = 3;
System.out.println(compList.get(0).toString());
}
}
Your class.
public class Components {
int numberOfNets;
String nameOfComp;
String nameOfCompPart;
int numOfPin;
public Components(int i, String compName, String partName, int pin) {
this.numberOfNets = i;
this.nameOfComp = compName;
this.nameOfCompPart = partName;
this.numOfPin = pin;
}
public String toString() {
return this.numberOfNets + " " + nameOfComp + " " + nameOfCompPart
+ " " + numOfPin;
}
}
The output:
0 compName partName 0
3 compName partName 3
I've never seen this before.. I have the following code, a simple nested loop assigning an object from one ArrayList to an object of another.
But, inside the inner loop, the object has some (not all) duplicate variables with null values?!? What am I doing wrong?!?
The first image shows the local variable "member", a reference to an object inside the ArrayList "members". This is the object with duplicate variables with null values.
The second image show the other object "offer", looking like one would expect.
Code below. Help?
public static void setMembersForOffers(ArrayList<WPMemberPost> members, ArrayList<WPOfferPost> offers)
{
int memberCount = members.size();
int offerCount = offers.size();
for (int i=0; i<offerCount; i++)
{
WPOfferPost offer = offers.get(i);
if (offer.memberIdentifier != null)
{
for (int j=0; j<memberCount; j++)
{
WPMemberPost member = members.get(j);
String id = member.identifier; // NULL?!? (Expected "436")
if (offer.memberIdentifier.equalsIgnoreCase(id))
{
offer.member = member;
break;
}
}
}
}
}
Of course two variables with the same name can exist in an inheritance hierarchy
Try this code and make a breakpoint in the main method at System.out.println(subclass);.
In the debugger you will see that the variable exists two times, because it is defined in Base and Subclass.
public class Main {
public static void main(String[] args) {
Subclass subclass = new Subclass();
subclass.someString = "test";
System.out.println(subclass);
}
private static class Base {
public String someString;
}
private static class Subclass extends Base {
public String someString;
}
}
This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 9 years ago.
I am trying to make a Java package 'mylib' with classes Library{} and Book{}.
Here is the code for class Library{}:
/*
Create collection of books
List books and status
User input:
'B' - Borrow a book
'R' - Reserve a book
'I' - Return a book
'X' - Exit program
*/
package mylib;
public class Library {
public static void main(String[] args) {
Book[] MyBooks = new Book[3];
Book x;
MyBooks[0] = new Book("The Lover's Dictionary", "Levithan, D.", 211);
MyBooks[1] = new Book("White Tiger", "Adiga, A.", 304);
MyBooks[2] = new Book("Thirteen R3asons Why", "Asher, J.", 336);
for (int i = 0; i < MyBooks.length; i++) {
x = MyBooks[i];
System.out.println((i + 1) + " " + x.sTitle);
}
}
}
Here is the code for class Book{}:
package mylib;
class Book {
// Declare fields
byte iStatus;
int iPages;
String sTitle, sAuthor;
String sBorrowedBy, sReservedBy;
String sDueDate, sReturnDate;
public static final byte BORROWED = 0, AVAILABLE = 1, RESERVED = 2;
// Constructor
public Book(String Title, String Author, int Pages) {
this.sTitle = Title;
this.sAuthor = Author;
this.iPages = Pages;
this.iStatus = this.AVAILABLE;
}
// Borrow method
static void borrowBook(String Borrower, String Due) {
if (this.iStatus == this.AVAILABLE) {
this.sBorrowedBy = Borrower;
this.sDueDate = Due;
this.iStatus = this.BORROWED;
} else if (this.iStatus == this.RESERVED
&& this.sReservedBy == Borrower) {
this.sBorrowedBy = Borrower;
this.sDueDate = Due;
this.sReservedBy = "";
this.iStatus = this.BORROWED;
}
}
/*
* static int reserveBook(String Borrower) {
*
* }
*
* static void returnBook(String Return) {
*
* }
*/
}
The partial codes above are given by the professor. I commented out the empty methods and tested the program just to see if it would compile.
I am having 14 errors with the this keyword. Any help?
in this method
static void borrowBook(String Borrower, String Due) {
You cannot use this in a static context
As I see ,there is no need of making that method static.
Prefer to read Understanding Instance and Class Members
You cannot use this in static context , like static methods. Why are you making your borrowBook() method as static. It should be an instance method without the static keyword.
static methods belong to the class and is shared by all its instances. You can invoke them directly using the classname like Book.borrowBook(....) , if this happens the run time will have no idea what/which object this refers to in that context .
Read JLS.3 15.8
The keyword this may be used only in the body of an instance method, instance initializer, or constructor, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs.
In your case better to make the borrowBook() method an instance method as it changes the state of the invoking object i.e. modifies its attributes.Just change the method declaration and remove static:
void borrowBook(String Borrower, String Due) {....... }
Since you are using this in a static context it is giving you the error. Try the following code:
package myLib;
class Book {
// Declare fields
byte iStatus;
int iPages;
String sTitle, sAuthor;
String sBorrowedBy, sReservedBy;
String sDueDate, sReturnDate;
public static final byte BORROWED = 0, AVAILABLE = 1, RESERVED = 2;
// Constructor
public Book(String Title, String Author, int Pages) {
this.sTitle = Title;
this.sAuthor = Author;
this.iPages = Pages;
this.iStatus = Book.AVAILABLE;
}
// Borrow method
//Remove the static keyword
//Refer to the remaining static variables like AVAILABLE OR BORROWED using Book and not this keyword.
void borrowBook(String Borrower, String Due) {
if(this.iStatus == Book.AVAILABLE) {
this.sBorrowedBy = Borrower;
this.sDueDate = Due;
this.iStatus = Book.BORROWED;
}
else if(this.iStatus == Book.RESERVED && this.sReservedBy == Borrower) {
this.sBorrowedBy = Borrower;
this.sDueDate = Due;
this.sReservedBy = "";
this.iStatus = Book.BORROWED;
}
}
}
I suggest you to use IDE to coding since this issue will understand by your own. because error is here use this in a static block.
this keyword is used to refer non-static variables from non-static methods. You are referring to non-static variables from static method.
just change this line :
static void borrowBook(String Borrower, String Due) {
to
public void borrowBook(String Borrower, String Due) {
VERY new to Java, so I am feeling like a child right now. The joys of learning a new language I guess.
Here is my Invoice Class:
public class Invoice {
//member inits
private int numberOfInvoices = 0;
private String companyName;
private double amountDue;
private String chargeDate;
private static int invoiceNumber = 0;
//constructor
public Invoice(String _companyName, double _amountDue, String _chargeDate)
{
numberOfInvoices++;
companyName = _companyName;
amountDue = _amountDue;
chargeDate = _chargeDate;
invoiceNumber = numberOfInvoices;
}
//getters
public String getCompanyName()
{
return companyName;
}
public double getAmountDue()
{
return amountDue;
}
public String getChargeDate()
{
return chargeDate;
}
public int getInvoiceNumber()
{
invoiceNumber = numberOfInvoices + 1;
return invoiceNumber;
}
//setters
public void setCompanyName(String _companyName)
{
companyName = _companyName;
}
public void setAmountDue(double _amountDue)
{
amountDue = _amountDue;
}
public void setChargeDate(String _chargeDate)
{
chargeDate = _chargeDate;
}
//helpers
public int incrementInvoices()
{
return numberOfInvoices++;
}
}
And here is the main method where I am trying to create three of these invoices, but increment the invoice number each time a new one is created.
public class InvoiceCreator {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Invoice invoice1 = new Invoice("Amazing Software", 5000.00, "January 18, 2009");
System.out.println(invoice1);
Invoice invoice2 = new Invoice("Best Programs", 4000.00, "February 18, 2009");
System.out.println(invoice2);
Invoice invoice3 = new Invoice("Champion Code", 3000.00, "March 18, 2009");
System.out.println(invoice3);
}
}
I'm also new to the IDE (netbeans), but through debugging and looking at each of the classes I created, all the fields are being initialized correctly, but the invoiceNumber = 1 on every one of them.
What am I doing incorrectly here?
You need to use a static field to generate incremental invoice numbers, not store the individual invoice numbers.
Try this:
public class Invoice {
//member inits
private static int nextInvoiceNumber = 0;
private String companyName;
private double amountDue;
private String chargeDate;
private int invoiceNumber = 0;
//constructor
public Invoice(String _companyName, double _amountDue, String _chargeDate)
{
invoiceNumber = nextInvoiceNumber;
nextInvoiceNumber++;
companyName = _companyName;
amountDue = _amountDue;
chargeDate = _chargeDate;
}
....
Declare numberOfInvoices to be static, so that there is a single value for the entire class, rather than a separate value for each instance.
private static int numberOfInvoices = 0;
You declared invoiceNumber as static, but numberOfInvoices is not static. In your constructor you are incrementing the number of invoices - which, being non-static, is initialised to 0 every time you create an instance of it. Then you assign this value to your invoice number.
The simple fix for your case is to declare the numberOfInvoices as static and invoiceNumber as non static:
private static int numberOfInvoices = 0;
private int invoiceNumber;
then you'll get the desired behaviour.
At the same time, it's worth noting that this implementation is ok for the purpose of learning the language, however it will not work for a production system, because the number will still be reset to 0 when the application exits and is restarted. In a production system, you would want to keep this number in a database or external file somewhere. You would then need to ensure that it's incremented in a thread-safe manner. In a production system, your logic would be something like this:
private int invoiceNumber;
private Object sync;
public Invoice(...) {
synchronised(sync) {
invoiceNumber = loadLastInvoiceNumberFromStorage();
invoiceNumber++;
writeLastInvoiceNumberFromStorage(invoiceNumber);
}
...
}
numberOfInvoices should be static. invoiceNumber should not be static. And you should synchronize the access to this field. See also: What is the best way to increase number of locks?
numberOfInvoices isn't the static member.
You currently increment an instance property and set it to the static property.
I suspect you want the opposite.
You could use a static field numberOfInvoices in your class, and increment it in the constructor.
Then you could have a static getter for the field.
numberOfInvoices will always be 0 when a new object is created. So, everytime you increment it and assign it to invoiceNumber, invoiceNumber gets the value 1. Instead, why dont you directly increment invoiceNumber .
use
private static int numberOfInvoices = 0;
Reason:
Static variables are related to class while nonstatic variables are related to object. As in this case you are storing the count of the object of the class so this is related to class. Thus you have to store it as static variable ( also called class variable)
For more details see here
You should declare your numberOfInvoices member as a static member :
private static int numberOfInvoices = 0;
This way all Invoice instance will share this member. If you don't declare it each Invoice instance will have their own value.