I am trying to create a list of objects from a database but whenever I add another element to the end of the list it changes the values of the previous elements. I have seen similar questions on here but none seem to help my problem.
Here is the code for the class Deck
public static class Deck {
private static int deckid;
private static String deckName;
private static int deckCreatorID;
private static boolean isDeckPublic;
private static String deckDescription;
public Deck(int id, String name, int creator, boolean isPublic, String description){
deckid = id;
deckName = name;
deckCreatorID = creator;
isDeckPublic = isPublic;
deckDescription = description;
}
public String getDeckName(){
return deckName;
}
public String getDeckDescription(){
return deckDescription;
}
public int getDeckCreator(){
return deckCreatorID;
}
public int getDeckid() { return deckid; }
public boolean getDeckPublic() { return isDeckPublic; }
}
Here is the code to create and add the objects to the list:
public static List<marketplaceController.Deck> getAllCards(){
List<marketplaceController.Deck> deckList = new ArrayList<>();
List<Integer> idList = new ArrayList<>();
List<String> nameList = new ArrayList<>();
List<Integer> cIdList = new ArrayList<>();
List<Boolean> publicList = new ArrayList<>();
List<String> descList = new ArrayList<>();
try{ // This try-catch block is mainly from https://www.javatpoint.com/example-to-connect-to-the-mysql-database
Class.forName("com.mysql.cj.jdbc.Driver"); // Define the driver to use
Connection con=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/users","root","UnlockDB.123"); // Connect to the local db
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("select * from decks"); // Execute the query on the db
while(rs.next()) { // Runs while columns are to be store
idList.add(rs.getInt(1));
nameList.add(rs.getString(2));
cIdList.add(rs.getInt(3));
publicList.add(rs.getBoolean(4));
descList.add(rs.getString(5));
}
con.close();
}
catch(Exception e){
loginController.popup("An error occurred connecting to the database", "An error occurred");
}
for(int i = 0; i < idList.size(); ++i){ // This loop outputs the correct data
deckList.add(new marketplaceController.Deck(idList.get(i), nameList.get(i), cIdList.get(i), publicList.get(i), descList.get(i)));
System.out.println(deckList.get(i).getDeckid());
System.out.println(deckList.get(i).getDeckName());
System.out.println(deckList.get(i).getDeckCreator());
System.out.println(deckList.get(i).getDeckPublic());
System.out.println(deckList.get(i).getDeckDescription());
}
for(int i = 0; i < deckList.size(); ++i){ // This outputs the overwitten data
System.out.println(deckList.get(i).getDeckid());
System.out.println(deckList.get(i).getDeckName());
System.out.println(deckList.get(i).getDeckCreator());
System.out.println(deckList.get(i).getDeckPublic());
System.out.println(deckList.get(i).getDeckDescription());
}
return deckList;
}
When the elements of deckList are printed straight after they are created they show the correct elements e.g.
1
TESTDECK
1
true
""
2
TESTDECK2
1
true
""
However, when I iterate through the completed list and print the contents the following is printed:
2
TESTDECK2
1
true
""
2
TESTDECK2
1
true
""
This is probably a very stupiud question but I'm reltively new to Java and so any help is greatly appreciated
As #jhamon pointed out using static variables can be a very bad idea when you don't know what this means. Simply put a static field is shared among all instances of a class because it is a property of the class and not the instance. So when you have 10 instances of Deck all of them will return the same value for e.g. deckid.
Related
I am writing a program to store certain Recipe info. into an array. Using method RecipeEntry(), with its parameters, the program is meant to store up to a maximum of 3 recipes into an array named: totalEntry[].
Below is my attempt at writing this program, however, I am getting errors .. unable to figure out what it is that I am missing.
import java.util.*;
public class RecipeArray
{
private String author;
private Recipe recpH_1;
private Recipe recpC_2;
private static RecipeEntry[] totalEntry = new RecipeEntry[3];
private static int entryCount;
public RecipeArray(String author, Recipe hot, Recipe cold) // constructor
{
entryCount = 0;
this.author = author;
recpH_1 = hot;
recpC_2 = cold;
totalEntry[entryCount] = new RecipeArray(author, recpH_1, recpC_2);
}
public static void main(String[] args)
{
RecipeEntry("Mary Bush", SpaghettiHOT, SpaghettiCOLD);
// RecipeEntry method, when called should pass its parameter values into
// totalEntry [] array. entryCount variable should keep count of every entry.
System.out.println("ALL ENTRY = " + entryCount + Arrays.toString(totalEntry));
}
}
public class Recipe //create class data of type recipe
{
private String name;
private int id, rating;
public Recipe(String name)
{
this.name = name;
id = 0;
rating = 0;
}
}
The expected output should print a list of the entries - Example:
Output:
index 0 - [Mary Bush, SpaghettiHOT{id=0, rating=0}, SpaghettiCOLD{id=0, rating=0}]
The problem is that you didn't catch the returned Array from your method:
RecipeEntry("Mary Bush", SpaghettiHOT, SpaghettiCOLD);
Actually the RecipeArray as you wrote will return an Array; it means that the method will pass and Array to it's caller.
Changing the mentioned line with the following line will solve the problem:
RecipeEntry[] totalEntry = RecipeEntry("Mary Bush", SpaghettiHOT, SpaghettiCOLD);
Visit https://www.tutorialspoint.com/importance-of-return-type-in-java for better understanding of Java Methods:
I am trying to get an arraylist of objects from another class to display it an modify it (delete object in ArrayList) so the original ArrayList has to be modified also...I have tried the method below whitout success.
Class Atribute
private int number; //user imput
Methods
public String DisplayObj() {
String result;
FormularioPedido form = new FormularioPedido(); //instance of the other class so I can access the arrayList
ArrayList<Pedido> lista = form.getListaPedido();
number -= 1;
Pedido pedido = lista.get(number);
result = pedido.getTamanio() + pedido.getIngredientesToString()
+ pedido.getBebida() + pedido.getExtra() + pedido.getCelular();
return result;
}
public void deleteObj() {
FormularioPedido form = new FormularioPedido();
List<Pedido> lista = form.getListaPedido();
number -= 1;
lista.remove(number);
}
You need to store the lista as a Class attribut.
That way the list you are displaying will be the same as the one you are deleting from.
At the moment it's 2 separates lists and everytime you call the display method you recreate one.
private int number; //user imput
private FormularioPedido form = new FormularioPedido();
public String DisplayObj() {
String result;
ArrayList<Pedido> lista = form.getListaPedido();
number -= 1;
Pedido pedido = lista.get(number);
result = pedido.getTamanio() + pedido.getIngredientesToString()
+ pedido.getBebida() + pedido.getExtra() + pedido.getCelular();
return result;
}
public void deleteObj() {
List<Pedido> lista = form.getListaPedido();
number -= 1;
lista.remove(number);
}
Of course you would need to check for the list size before doing delete or display as to avoid exception.
Everytime you write new FormularioPedido(), you create a new list (returned when you call to the form.getListaPedido()). You should think a little more about your class design. For example, the list could be a class attribute and you could opperate over the same list instance.
I'm trying to populate an ArrayList with data stored in a text file, the data is 5 different values separated by white space, and a mix of boolean, strings and integers. Also, I'm using BlueJ, not sure if that changes anything though.
When the data is read from the file, objects of type Room should be created based on that data
I am new to Java, I've just started learning it within the last few weeks, my read data class is as follows:
Room Data Class:
public class RoomData
{
//Default Values of a Room
private int roomNumber = 0;
private int bookingNights = 0;
private boolean hasEnSuite = false;
private boolean isBooked = false;
private String bookingName = "<None>";
public void setRoomNumber(int roomNumber)
{
this.roomNumber = roomNumber;
}
public void setBookingNights(int bookingNights)
{
this.bookingNights = bookingNights;
}
public void setHasEnSuite()
{
this.hasEnSuite = hasEnSuite;
}
public void setIsBooked()
{
this.isBooked = isBooked;
}
public void setBookingName()
{
this.bookingName = bookingName;
}
}
ReadDataClass:
public class ReadHotelData
{
private String filePath;
public ReadHotelData()
{
filePath = "hotelData.txt";
}
private List<RoomData> list = new ArrayList <>();
public boolean hasNext() throws FileNotFoundException
{
Scanner s = new Scanner(new File("hotelData.txt"));
while (s.hasNext())
{
String nextLine = s.nextLine(); //reads text file line by line
RoomData roomData = new RoomData();
String[] values = nextLine.split(" "); // splits the text file by white space
roomData.setRoomNumber(Integer.parseInt(values[0]));
roomData.setBookingNights(Integer.parseInt(values[1]));
roomData.setHasEnSuite(Boolean.parseBoolean(values[2]));
roomData.setIsBooked(Boolean.parseBoolean(values[3]));
roomData.setBookingName(String.parseString(values[4]));
list.add(roomData);
}// end loop
s.close();
return true;
}
public List <RoomData> getRoomDataList()
{
return list;
}
}
Like I said I'm new so if I'm missed anything I'd really appreciate any help!
Example of data stored in text file:
0 false David 0 false
0 true John 0 false
0 false Jim 0 true
First create a class RoomData to hold the data for each room and give each variable a meaningful name along with the appropriate type.
Change your arraylist to hold that type instead of String
private List<RoomData> list = new ArrayList<>();
Read each line using s.nextLine()
while(s.hasNext())
{
String nextLine = s.nextLine();
RoomData roomData = new RoomData();
Create an instance of that class, split and parse each value into the corresponding variable in the instance of RoomData you have created.
String[] values = nextLine.split(" ") // split by space
// lets say you have "0 false David 0 false"
// values[0] would be "0"
// values[1] would be "false"
// values[2] would be "David"
// values[3] would be "0"
// values[4] would be "false"
All the values in values would be of type String you will need to convert those from String to the type you have defined in RoomData, for int you can use Integer.parseInt(String s), for boolean there is a similar method (Boolean.parseBoolean(String s))[http://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html#parseBoolean-java.lang.String-], string values can be set directly.
Add that instance to the arraylist.
list.add(roomData);
} // end of while
Add a getter method to return that list for use in other classes.
public List<RoomData> getRoomDataList() {
return list;
}
I need to insert different result into the row of my JTable. I search my record by using purchaseID which is the pID, it will find 2 result for that particular purchaseID. The problem is when I insert it into row, it just duplicate the result of the first one. EG : P0001 have 2 purchase details and when I insert it into row, I have 2 same row. Is there any way for me to insert into row one by one ?
PS. I've been coding since morning, brain is not functioning well.
UI:
else if(e.getSource() == jbtRetrieve)
{
String pID = jTF3.getText();
Purchase purchase = purcControl.selectRecord(pID);
if (purchase != null) {
String pdCountStr = purchase.getPurchaseDetailsID();
String pdCountStr2 = pdCountStr.substring(2,5);
int pdCount = Integer.parseInt(pdCountStr2);
for(int g = 0; g<pdCount;g++){ //g =1
tableModel.addRow(new Object[]{ purchase.getPurchaseDetailsID(),purchase.getStockID(),purchase.getPrice(),purchase.getQuantity()});
}}
DA :
public Purchase getRecord(String pID){
String queryStr = "SELECT PD.PURCHASEDETAILID,PD.PURCHASEID,PD.STOCKID,PD.ORDERQTY,S.STOCKPRICE FROM "+tableName+" PD, STOCKS S WHERE PD.STOCKID = S.STOCKID AND PurchaseID = ?";
Purchase purchase = null;
System.out.println("asd");
try{
stmt = conn.prepareStatement(queryStr);
stmt.setString(1,pID);
ResultSet rs = stmt.executeQuery();
if(rs.next()){
purchase = new Purchase(pID, rs.getString("purchaseID"),rs.getString("stockID"),rs.getDouble("stockprice"),rs.getInt("orderqty"));
}
}
catch (SQLException ex){
JOptionPane.showMessageDialog(null,ex.getMessage(),"ERROR",JOptionPane.ERROR_MESSAGE);
}
return purchase;
}
Domain:
public Purchase(String purchaseDetailsID,String purchaseID,String stockID,double price,int quantity)
{
this.purchaseDetailsID = purchaseDetailsID;
this.purchaseID = purchaseID;
this.stockID = stockID;
this.price = price;
this.quantity = quantity;
}
public void setPurchaseID(String u){
this.purchaseID = u;
}
public String getPurchaseID(){
return purchaseID;
}
public String getPurchaseDetailsID(){
return purchaseDetailsID ;
}
public double getPrice(){
return price;
}
public String getStockID(){
return stockID;
}
public int getQuantity(){
return quantity;
}
public void setPurchaseDetailsID(String r){
this.purchaseDetailsID = r ;
}
public void setPrice(double p){
this.price = p;
}
public void setStockID(String s){
this.stockID = s;
}
public void setQuantity(int q){
this.quantity = q;
}
Control :
public Purchase selectRecord(String pID){
return purcDA.getRecord(pID);
}
Edit: Set Purchase to ArrayList<> to accept the List and I get this Exception.
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:635) at java.util.ArrayList.rangeCheck(ArrayList.java:635)
at java.util.ArrayList.get(ArrayList.java:411)
at ui.MainPurchasingFrame$ListenerClass.actionPerformed(MainPurchasingFrame.java:183)
code:
ArrayList<Purchase> purchase = purcControl.selectRecord(pID);
if (purchase != null) {
String pdCountStr = purchase.get(0).getPurchaseDetailsID();
String pdCountStr2 = pdCountStr.substring(2,5);
int pdCount = Integer.parseInt(pdCountStr2);
System.out.print(pdCount);
for(int g = 0; g<pdCount;g++){
tableModel.addRow(new Object[]{ purchase.get(g).getPurchaseDetailsID(),purchase.get(g).getStockID(),purchase.get(g).getPrice(),purchase.get(g).getQuantity()}); //This is where the exception occurs.
}
If you want to return multiple objects from a query, your return type should be either an array or a collection of that type.
So instead of defining
public Purchase getRecord(String pID){…}
You should define the DA method as:
public List<Purchase> getRecords(String pID) {…}
Inside the method, define a list object such as:
List<Purchase> foundPurchases = new ArrayList<>();
And then after issuing the query and getting the result set, you use a while loop to fill it:
while ( rs.next() ) {
purchase = new Purchase(pID, rs.getString("purchaseID"),rs.getString("stockID"),rs.getDouble("stockprice"),rs.getInt("orderqty"));
foundPurchases.add( purchase );
}
Then, after you finish and close your statement, you should return the foundPurchases:
return foundPurchases;
The calling code should, of course, expect to receive a List of purchases rather than a purchase, and then iterate and display it.
Now regarding your edited part. You are doing several things improperly.
First of all, you don't have to go inside the purchase records to see how many records there were. If there were none, the list will be empty. If there was 1, it's size is going to be 1, and if there are two, its size is going to be two.
Second, you actually don't need to know how many elements there are, because you can traverse a list by using its iterator, in a simple for loop:
ArrayList<Purchase> purchaseList = purcControl.selectRecord(pID);
for ( Purchase purchase : purchaseList ) {
…
}
You don't actually have to use get. You have the current individual purchase in the variable purchase (Note that I changed the name of your original variable to something that shows it's a list and not a purchase), and you can use it directly.
Note also that you don't need to check for nulls. The way I've written it, the DA method always returns a reference to a List, even if it's an empty list. And the loop always adds an actual new Purchase(…) to the list so the list's items are also never null.
One thing, though: from the way the error looks, it seems that you have only one row when the details ID says there should be two. Check your query directly with the database to be sure there are actually two records.
If you want to display an error when nothing was found, you should check with an if statement if the list is empty. This means that no records have been returned at all.
if ( purchasedList.isEmpty() ) {
// Display error dialog
} else {
// Do the for loop to fill the rows
}
Having to ask this question because I am a fool and overwrote old work.
Right now what I need to do is loop through a multidimensional array in one class, then loop through an arraylist(thats currently empty) and use an if statement to check whether or not there are duplicates inside that arraylist, if there aren't, then it will add the record to the arraylist, if it is, it will simply make isFound = false
This is the method that will add the records to the arraylist. Right now it only works up to the second loop. this is the main class, called EAC
public void PopulateRecords()
{
ArrayList<String> categories = new ArrayList<String>();
for (int i = 0; i < Data.stats.length; i++)
{ //System.out.println(Data.stats[i][1]);
for (String category : categories)
{
boolean isFound = false;
if (Data.stats[i][1].equals(category))
{
isFound = true;
}
if (!isFound)
{
categories.add(Data.stats[i][0]);
System.out.println(categories);
}
}
}
}
This is the Category class, and the GetCategory here was used within the populaterecords() method somehow, but that's the one stage of this i'm not fully understanding, because there's a bit or two missing from here that's presumably preventing the method from working
public class Category
{
public String categoryname;
public Category categories;
public static void main(String[] args)
{
new Category();
}
public Category()
{
}
public String GetCategory()
{
return categoryname;
}
public void SetCategory()
{
}
}
This is as specific as I can go, I'm by every definition a pure newbie at java, so any help here is much appreciated
You're looping through an empty ArrayList, so the 2nd loop body will execute 0 times.
ArrayList<String> categories = new ArrayList<String>();
for (int i = 0; i < Data.stats.length; i++)
{ //System.out.println(Data.stats[i][1]);
for (String category : categories) // Here categories is empty, so no loop iterations occur