I'm trying to add a list of purchases to an array and then be able to perform some calculations based on the doubles in the array. Im having trouble trying to add purchases to the double array
Here's what I have:
public abstract class Customer {
protected String category;
protected String acctNumber;
protected String name;
protected double[] purchases;
protected static final double SALES_TAX_RATE = 0.08;
/**
*Reads in customer data.
*#param acctNumberIn customers account number.
*#param nameIn customers name.
*/
public Customer(String acctNumberIn, String nameIn) {
acctNumber = acctNumberIn;
name = nameIn;
purchases = new double[0];
}
Add purchases method where I'm having problems:
public void addPurchases(double ... pur) {
purchases = Arrays.copyOf(purchases, purchases.length + 1);
int a = purchases.length;
for (int i = 0; i < purchases.length; i++) {
purchases[a] = pur;
}
}
The problem is that pur is of type double[]. So you will need to create a new array with the size of purchases + pur, and copy each element of pur to the end of purchases.
Please try the following code:
public void addPurchases(double ... pur) {
int purchasesLength = purchases.length;
int combinedLength = pur.length + purchasesLength;
purchases = Arrays.copyOf(purchases, combinedLength);
for (int i = purchasesLength, j = 0; i < combinedLength; i++, j++) {
purchases[i] = pur[j];
}
}
Using an ArrayList instead of an array would be much simpler, as well as improve your code performance and quality. To create one to hold your purchases you could do
protected ArrayList<Double> purchases = new ArrayList<Double>();
And then your addPurchases method can easily be simplified to:
public void addPurchases(double... pur) {
for (double purchase : pur) {
purchases.add(purchase);
}
}
pur is an array, double... pur is away that allows you to pass zero or more values to a method, but which are treated as an array from within the method.
With this in mind, you are attempting to assign every element in your purchases array to the same value pur (or a double[]) which obviously won't work.
Instead, you need to get the current length of the array, re-size the array by the length of pur (purchases.length + pur.length), then from the previously last position begin adding in the new elements from pur
Maybe something like...
public void addPurchases(double... pur) {
int start = purchases.length;
purchases = Arrays.copyOf(purchases, purchases.length + pur.length);
for (int i = start; i < purchases.length; i++) {
purchases[i] = pur[i - start];
}
}
Now, any time you think this might be a good idea, you should consider using a List of some kind instead, maybe something like...
public static class Customer {
protected String category;
protected String acctNumber;
protected String name;
protected List<Double> purchases;
protected static final double SALES_TAX_RATE = 0.08;
/**
* Reads in customer data.
*
* #param acctNumberIn customers account number.
* #param nameIn customers name.
*/
public Customer(String acctNumberIn, String nameIn) {
acctNumber = acctNumberIn;
name = nameIn;
purchases = new ArrayList<>(25);
}
public void addPurchases(double... pur) {
for (double p : pur) {
purchases.add(p);
}
}
}
Have a look at the Collections Trail for more details
You can simply do:
public void addPurchases(double ... pur) {
int a = purchases.length;
purchases = Arrays.copyOf(purchases, purchases.length + pur.length);
for (int i = 0; i < pur.length; i++) {
purchases[a + i] = pur[i];
}
}
However, DO NOT use arrays and resize it manually. If you need to insert unknown number of items into a collection, use dynamic-size collections like java.util.List or java.util.ArrayList.
Related
When I try to use scanner on another class I can't update the array.
private int numClients;
private int[] clients;
These are variables from my class Rooms.
public Hotel(String name, int numRooms, int numClients){
this.name = name;
this.numRooms = numRooms;
this.numClients= numClients;
this.clients = new int[numClients];
}
Of course I added setters and getters:
public String getName() {
return name;
}
public void setNaziv(String name) {
this.name = name;
}
public int getNumRooms() {
return numRooms;
}
public void setNumRooms(int numRooms) {
this.numRooms = numRooms;
}
public int getNumClients() {
return numClients;
}
public void setNumClients(int numClients) {
this.numClients = numClients;
}
When I tried to add it to test it in another class, name and numRooms change. numClients change too but array doesn't update.
Hotel h1 = new Hotel(" ", 0, 0);
String name= sc.nextLine();
h1.setName(name);
int numRooms= sc.nextInt();
h1.setNumRooms(numRooms);
int numClients= sc.nextInt();
h1.numClients(numClients);
h1.show();
This is the show method:
public void show(){
System.out.println("Name: " + this.name);
System.out.println("Rooms: " + this.numRooms);
System.out.println("Number of clients: " + this.numClients);
for(int i = 0; i < clients.length; i++) {
System.out.println(clients[i]);
}
}
Maybe there will be some typing errors I translated the var names to English for question purposes.
Once you have created the array, it's size is fixed. You can test this with a few rows:
int size = 10; // Start with size 10
int[] array = new int[size]; // Array is 10 elements long
System.out.println(size); // Prints 10
System.out.println(array.length); // Also prints 10
size = 1000; // Change size ??
System.out.println(size); // Prints 1000
System.out.println(array.length); // Still prints 10
Output:
10
10
1000
10
You also don't appear to actually set any elements in the array in your code. That would be something like
h1.getClients()[0] = 3;
Edit
When this line in your constructor is exectuted:
this.clients = new int[numClients];
The array is created with the size that numClients has right at that moment. After that, there is no relation between numClients and clients anymore.
You would need to create a new array, copy contents (if you want to preserve it) and reassign clients with the new array in order to change the size.
You can do this with Arrays.copyOf() :
int newLength = 20;
array = Arrays.copyOf(array, newLength);
System.out.println(array.length); // Prints 20!!
The constructor will run once for a single object. So, if you want to add more values in the clients array then a method is a must.
The main Class:
class Main {
public static void main(String[] args) {
Hotel hotel = new Hotel("romeo",5,10);
hotel.addClients(6);
hotel.addClients(10);
hotel.addClients(5);
hotel.show();
}
}
The Hotel Class:
class Hotel{
private int numRooms,numClients;
private String name;
private int clients[] = new int[10];
public Hotel(String name, int numRooms, int numClients){
this.name = name;
this.numRooms = numRooms;
this.numClients= numClients;
this.clients[0] = numClients;
}
The method to add Clients in the clients array:
public void addClients(int numClients){
for(int i = 0; i < clients.length; i++){
if(clients[i] == 0){
clients[i] = numClients;
break;
}
}
}
Show method output:
Name: romeo
Rooms: 5
Number of clients: 10
10
6
10
5
The Total number of clients can be found by summation of the clients array.
To make the array dynamic, the linked list data structure can be applied.
What I did to fix this without updating and making new methods is defining values with scanner and putting it into constructor.
public void test(){
Scanner sc = new Scanner(System.in);
System.out.print("Type in the name of Hotel: ");
String name= sc.nextLine();
System.out.print("Type in number of rooms: ");
int numRooms = sc.nextInt();
System.out.print("Type in the number of clients");
int numClients= sc.nextInt();
Hotel h1 = new Hotel(name, numRooms, numClients);
h1.show();
}
I'm trying to make a program with three class files, two Objects files and one Main that accesses both and runs operations. The first object file creates objects with one parameter, and then assigns attributes to itself based on said parameter, for example.
public class People {
private int height, weight;
private String specificPerson;
public People(String person){
this.specificPerson = person;
this.height = person.length * 12;
this.weight = person.length * 40;
}
public int getHeight(){return height;}
public int getWeight() {return weight;}
}
These objects are then stored within the array of another object which has a capacity and an array:
public class peopleIndexer {
private int pcapacity, size;
private String[] peopleArray;
public peopleIndexer(int capacity){
this.pcapacity = capacity;
this.peopleArray = new String [capacity];
}
public int getCapacity(){
return pcapacity;
}
public int[] getInfo(String person){
int[] getInfo = new int[2];
int found = Arrays.binarySearch(peopleArray,person);
getInfo[0] = ?.getHeight();
getInfo[1] = ?.getWeight();//I dont know the object name yet so I put "?" for I am not sure
System.out.println("Person" + person + "is " + getInfo[0] + "tall and " + getInfo[1] + " pounds.");
}
}
What I need to know is how to allow the user to make multiple people in the list with input that I can then allow them to retrieve later, for example:
String user_input;
People user_input = new People("user_input");
So that if the users input were to be jack, ryan, and nick, I would have three objects placed in the peopleIndexer as such:
People jack = new People(jack);
People ryan = new People(ryan);
People nick = new People(nick);
Your People constructor takes only one argument and creates a People object..You do not have setters for some of your private variables in the peopleIndexer class, so best to have your main method as part of the peopleIndexer class.
Your "length" attribute in the People constructor is not initialized or declared anywhere, so let's assume it's not there. You must change your "private String[] peopleArray;" to be "private People[] peopleArray;" in order to have people in the array.
public static void main(String args[]){
Scanner input = new Scanner(System.in);
int capacity;
int peopleCount = 0; //used to keep track of people we have in our array
String person = "";
// get the capacity from the user
System.out.println("Enter the number of people you want to capture: ");
capacity = Integer.parseInt(input.nextLine());
//create peopleIndexer object using the given capacity
peopleIndexer pIndexer = new peopleIndexer(capacity);
while(peopleCount < capacity){
//prompt the user for the "People" name, this is the only attibute we need according to your constructor.
System.out.println("Enter person "+(peopleCount + 1)+" name: ");
person = input.nextLine();
//add a new person into the array
peopleArray[peopleCount] = new People(person);
//increase the number of people captured
peopleCount += 1;
}
}
The task was to create a program which organises a users name with their corresponding mark and displays this in descending order. I'm asking how to sort both arrays at the same time but only by comparing the elements of one of the arrays. As a restriction, I cannot use classes, only associated arrays.
int [] ArrMarks = new int [5];
String [] ArrNames = new String [5];
Button to Accept user input
for (int i = 0; i < 5; i++)
{
ArrNames[i] = JOptionPane.showInputDialog("Enter a Name:");
ArrMarks[i] = Integer.parseInt(JOptionPane.showInputDialog("Enter a mark:"));
}
Display button including the part which sorts the code, this is the main part I am unsure of.
int Hi = ArrMarks[0];
for(int i = 0; i < 5; i++) {
if(ArrMarks[i] > Hi) {
Hi = ArrMarks[i];
}
}
txaDisplay.append("Names:"+"\t\t"+"Marks");
for (int i = 0; i < 5; i++) {
txaDisplay.append(ArrNames[i]+"\t\t"+ArrMarks[i]+"\n");
}
First of all, I would like to give a suggestion. Use lists instead of arrays. This kind of coding is not a good conventional way of coding. I will show a conventional way to handle the issue. You may take this if you like.
Create another class Mark.java with the following content
class Mark {
Integer mark;
String name;
public Integer getMark() {
return this.mark
}
public void setMark(Integer mark) {
this.mark = mark
}
public String getName() {
return this.name
}
public void setName(String name) {
this.name = name
}
}
Then in your current class create a List of this class.
List<Mark> marks = new ArrayList<Mark>();
Then after reading content from the user, you can add them to the list like following
for (int i = 0; i < 5; i++)
{
Mark mark = new Mark();
String name = JOptionPane.showInputDialog("Name:");
Integer mark = Integer.parseInt(JOptionPane.showInputDialog("Mark:"));
marks.add(mark)
}
Write a comparator class named MarkComparator.java. It deals with the sorting part.
public class MarkComparator implements Comparator<Mark> {
#Override
public int compare(Mark m1, Mark m2) {
return m1.getMark().compareTo(m2.getMark());
}
}
The use
Collections.sort(marks, new MarkComparator());
Now the List<Mark> of marks will be sorted.
You may then view the list the same way.
txaDisplay.append("Names:"+"\t\t"+"Marks");
for (Mark mark : marks)
{
txaDisplay.append(mark.getName()+"\t\t"+mark.getMark()+"\n");
}
The solution to my question required using a sorting technique to sort the names and marks, so that the program prints the corresponding mark to the name.
for(int i = 0; i < 5-1; i ++)
{
for(int j = i +1; j < 5; j++)
{
if (ArrMarks[i] < ArrMarks[j])
{
//sorting the names
String temp = ArrNames[i];
ArrNames[i] = ArrNames[j];
ArrNames[j] = temp;
//sorting the marks
int temp1 = ArrMarks[i];
ArrMarks[i] = ArrMarks[j];
ArrMarks[j] = temp1;
}
}
txaDisplay.append("Names:"+"\t\t"+"Marks"+"\n");
txaDisplay.append(ArrNames[i]+"\t\t"+ArrMarks[i]+"\n");
}
I am trying to add items to my array list with an action listener on a pop up window. You can see the action listener here. The problem that I am now having is I do not know how to add the inputs to my array list. Part of this problem is that I need to set my item number to 1 higher than the highest in my list. My array list is named as such:
private static ArrayList<InventoryItem> inventory = new ArrayList<>();
and the class for InventoryItem looks like this:
public class InventoryItem { //Delcare variables below
DecimalFormat formatted = new DecimalFormat("#,###.00");//set up decimal format for displaying 12.34 type values
String itemName;
int itemNumber;
public String getItemName() {
return itemName;
}
public int getItemNumber(){
return itemNumber;
}
int inStock;
double unitPrice;
double value;
double restockingFee;
double inventoryValue;
public InventoryItem(String itemName, int itemNumber, int inStock, double unitPrice) { //declare variables for this class
this.itemName = itemName;
this.itemNumber = itemNumber;
this.inStock = inStock;
this.unitPrice = unitPrice;
stockValue(); //call stock value
}
}
So my question is two parts. The first is how do I get my itemNumber to increment to 1 higher than the highest? Do I simply do a bubble sort to find the highest? And the second part is how do I get it to add all items, including this incremented itemNumber, into my original arraylist?
Note
If needed I can paste my code in it's entirety on pastebin as it is somewhat large.
EDIT: Per #Prabhakaran I have added some code and I am almost there. I have almost gotten this to work, however when I start to look through my list I do not see the added feature so how can I be sure that I am actually adding it?
String newItemName = String.valueOf(xField);
String text1 = yField.getText();
String newInventoryAmount = String.valueOf(text1);
int newNumber = Integer.parseInt(newInventoryAmount);
String text2 = zField.getText();
String newUnitPrice = String.valueOf(text2);
double newPrice = Double.parseDouble(newUnitPrice);
for (int i = 0; i >= inventory.size(); i++) {
inventory.get(inventory.size() ).getItemNumber();
int newItemNumber;
newItemNumber = i + 1;
InventoryItem item = new InventoryItem(newItemName, newItemNumber, newNumber, newPrice);
inventory.add(item);
What am I missing here? Shouldn't this simply add an item to my arraylist? I know it must be something really easy, I just can't seem to figure it out.
Here is my sort by ItemName:
static ArrayList sortInventory(ArrayList<InventoryItem> unsorted) {
ArrayList<InventoryItem> sorted = new ArrayList<>(); //create new array list to sort
InventoryItem alpha = null;
int lowestIndex = **-1**;
while (unsorted.size() > 0) { //while my unsorted array is less than 0 do the following
for (int i = 0; i < unsorted.size(); i++) { //increment through
if (alpha == null) {
alpha = unsorted.get(i); //get the next line in the inventoryItem array
lowestIndex = i;
} else if (unsorted.get(i).itemName.compareToIgnoreCase(alpha.itemName) < 0) { //compare items to determine which has a higher value
alpha = unsorted.get(i);
lowestIndex = i;
}
}
sorted.add(alpha); //reset the index so it will loop until there are no more items in the unsorted array
unsorted.remove(lowestIndex);
alpha = null;
lowestIndex = **0**;
}
return sorted; //return the sorted arraylist
}
EDIT: Corrected the lowestIndex and it goes good as gold.
Do like this
private static ArrayList<InventoryItem> inventory = new ArrayList<>();
String newItemName = String.valueOf(xField);
String newInventoryNumber = String.valueOf(yField);
int newNumber = Integer.parseInt(newInventoryNumber);
String newUnitPrice = String.valueOf(zField);
double newPrice = Double.parseDouble(newUnitPrice);
InventoryItem item =new InventoryItem(newItemName , newInventoryNumber , newNumber , newUnitPrice ) ;
inventory.add(item);
update
class SimpleComparator implements Comparator<InventoryItem> {
#Override
public int compare(InventoryItem o1, InventoryItem o2) {
return new Integer(o1.getItemNumber()).compareTo(o2.getItemNumber());
}
}
//Sorting based on the itemNumber.
Collections.sort(inventory,new SimpleComparator());
int newItemNumber = inventory.get(inventory.size() - 1).getItemNumber();
newItemNumber ++;
You could create your own ArrayList with Observer support:
public class InventoryItemArrayList extends ArrayList {
private static final long serialVersionUID = 4550719458611714650L;
private List listeners = new ArrayList();
public void addInventoryItemAddedListener(InventoryItemAddedListener listener) {
this.listeners.add(listener);
}
#Override
public boolean add(InventoryItem e) {
boolean add = super.add(e);
fireInventoryItemAdded(e);
return add;
}
private void fireInventoryItemAdded(InventoryItem e) {
for (InventoryItemAddedListener element : listeners) {
element.inventoryItemAdd(e);
}
}
#Override
public void add(int index, InventoryItem element) {
super.add(index, element);
fireInventoryItemAdded(element);
}
#Override
public boolean addAll(Collection c) {
boolean addAll = super.addAll(c);
fireInventoryItemAdded(c);
return addAll;
}
private void fireInventoryItemAdded(Collection c) {
for (InventoryItem inventoryItem : c) {
fireInventoryItemAdded(inventoryItem);
}
}
#Override
public boolean addAll(int index, Collection c) {
boolean addAll = super.addAll(index, c);
fireInventoryItemAdded(c);
return addAll;
}
}
I have two different arrays an ArrayList of doubles and an Array of Strings
public class tester {
private final static String TIME[]={ "8:00", "9:00", "10:00", "11:00",
"12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00" };
public static void main(String[] args){
ArrayList<Double> stat = new ArrayList<>();
stat.add(1.0);
stat.add(2.0);
stat.add(3.0);
stat.add(4.0);
stat.add(5.0);
stat.add(6.0);
stat.add(7.0);
stat.add(8.0);
stat.add(9.0);
stat.add(10.0);
stat.add(11.0);
stat.add(12.0);
int i = 0;
for (String time : TIME) {
System.out.println(time+" "+stat.get(i));
i++;
}
My question is quite simple is this the best way to loop through each array if I want to get the same position of each array to match? so that stat.get(0) ==TIME.get(0)?
Update
First of all thank you all for your quick response i like the idea of creating a class however there is something you need to know.
The thing you saw was a test class that i use to test my data.
i KNOW that the two arrays will ALWAYS be the same size due to the fact that the stat ArrayList normally defined like the following:
stat is a calculated value of data gained from the database the value of stat is based on time and then sent back to the GUI to be put into a graph and a table.
This means that for each of the TIME there is an exisiting value so that stat.get(0) is ALWAYS equal to TIME.get(0) == "8:00".
With this in mind do you still think i should create a class or should i keep the class showed below and then add a HashMap containing the data then iterate over that map to insert the data in my GUI?
public class Statistics {
private ArrayList<CallQueue> queues = new ArrayList<CallQueue>();
private ArrayList<Double> averageData = new ArrayList<Double>();
private Provider p;
public Statistics(){
try {
this.p = new Provider();
} catch (DopeDBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* This recursive method calculates the average of each time table and then adds its to the arrayList in the following order:
* 8.00 = 0
* 9.00 = 1
* 10.00 = 2
* 11.00 = 3
* 12.00 = 4
* 13.00 = 5
* 14.00 = 6
* ect.
* #param time
*/
public void calculateAverage(){
int data = 0;
for (int i = 8; i < 20; i++) {
for (CallQueue cq : queues) {
data += cq.getCallsByTime(i);
}
if (data == 0) {
Main.createErrorMessage("Fejl i dataen! \r\n kontakt venligst ansvarlige i Dope");
}
averageData.add((double) data/11);
}
}
/**
* #author MRCR
* This method recives the object list from the database and sets the currentlist to the list recived.
*/
public void setQueues(Calendar start, Calendar end){
try {
queues = p.getInformation(start, end, queues);
} catch (DopeDBException e) {
// TODO Auto-generated catch block
Main.createErrorMessage("Message");
} catch (DopeResultSetException e) {
// TODO Auto-generated catch block
Main.createErrorMessage("Message");
}
}
/**
* This method returns the calculated DataList list.
* #author MRCR
* #return averageData
*/
public ArrayList<Double>getData(Calendar start, Calendar end){
setQueues(start, end);
calculateAverage();
return averageData;
}
}
import java.util.HashMap;
public class CallQueue {
private String type;
private HashMap<Integer, Integer> data = new HashMap<Integer,Integer>();
public CallQueue(String type){
this.type = type;
}
public String getType(){
return type;
}
public int getCallsByTime(int time){
return data.get(time);
}
public void addCallsByTime(int hourOfDay, int callAmount) {
data.put(hourOfDay, callAmount);
}
}
I would first check that the lengths of the 2 arrays are the same.
Then iterate using a for loop:
final int timeLength = TIME.length;
if (timeLength != stat.size()) {
//something may not be right
}
for (int i = 0; i < timeLength; i++) {
System.out.println(time[i]+" "+stat.get(i));
}
for (int i = 0; i < TIME.length; i++) {
// use i to access TIME[i] and stat.get(i)
}
but you have to ensure that those arrays are of the same length
You would need to consider the length part also. You would only need to iterate upto the maximum length possible that covers both array, and list.
So, you can first find the lower length between them. And then iterate till that length: -
int lower = TIME.length < stat.size()? TIME.length: stat.size();
for (int i = 0; i < lower; i++) {
System.out.println(TIME[i] + " : " + stat.get(i);
}
Now that was the part of iterating over two arrays.
Now I would say, if you have to iterate over two arrays simultaneously, just make a class with the attributes, you have created arrays for.
So, create a class with attributes: - time, and stats. And then create a List<YourClass>. And iterate over the list of the class instances.
if (TIME.length!=stat.size()) {
// handle error
}
int count = stat.size();
for (int i=0; i<count; ++i) {
double d = stat.get(i);
String s = TIME[i];
}
However
As pointed out in a comment, you should define a class that will gather the information of both arrays.
For instance:
public class MyTime {
private double value;
private String label;
}
Or
In that particular case, I suspect you could use time formatting functions to replace your string array.
String.format("%1$d:00", (int) myDouble);