I have two classes: Position and Order. In Position class, fields like: name, price. In Order class field: quantity. My problem is how to display: name, price and quantity together in Order class. I thought about delete arraylist and make another one with position and quantity but I doubt it would help me.
package programming.com.pl;
public class Position {
private String name;
private double price = 0;
public Position(String name, double price){
this.name = name;
this.price = price;
}
public double getPrice() {
return price;
}
public String toString(){
String str = String.format("%4s,%4s", name,price);
return str;
}
}
public class Order {
private int quantity;
final private ArrayList<Position> positions = new ArrayList<Position>();
private int addedPosition;
public Order(int quantity) {
this.quantity = quantity;
}
private double calculateProduct() {
double sum = 0;
for (int i = 0; i < positions.size(); i++) {
sum = positions.get(i).getPrice();
}
return sum;
}
double sumOrder() {
double sum = 0;
for (Position x : positions) {
sum += calculateProduct();
}
return sum;
}
void addPosition(Position p) {
if (!positions.contains(p)) {
positions.add(p);
} else {
quantity++;
}
}
void deletePosition(int index) {
positions.remove(index);
}
public String toString() {
System.out.println("Order is: ");
for (Position p : positions) {
System.out.println(positions.toString());
}
return "Order sum is: " + sumOrder();
}
}
You already are overriding toString method in Position class so you just need to call that toString method on the position object when iterating the position objects from inside your Order class' toString() method.
And as #Federico points out in the comments you shouldn't System.out.println from toString methods. Just append to a string the details you require displaying and return that string.
You can achieve your desired result like so:
public class Position {
.
.
#Override
public String toString() {
return String.format("%4s,%4s\n", name, price);
}
}
public class Order {
.
.
#Override
public String toString() {
StringBuilder sb = new StringBuilder("Order details: \n");
sb.append("Quantity: ").append(quantity).append("\n");
for (Position p : positions) {
sb.append(p);
}
sb.append("Order sum is: ").append(sumOrder());
return sb.toString();
}
}
Related
I am trying to make a new method that tells the user what the country with the highest point out of my array is. What I have currently done is inputted 2 country names followed by their highest point name and the number of the highest point, but now I am trying to output the one country that has the indefinite highest point, in my case from what i've added, its Argentina with Aconcagua as its highest point as 6960.
Code:
Main file:
public class continentTest
{
public static void main(String[] args) {
Continent southAmerica = new Continent();
Country southAmericanRepublic = new Country("Argentina", new HighestPoint("Aconcagua", 6960));
southAmerica.addCountry(southAmericanRepublic);
Country anotherSouthAmericanRepublic = new Country("Columbia", new HighestPoint("Pico Cristóbal Colón",5730));
southAmerica.addCountry(anotherSouthAmericanRepublic);
System.out.println (southAmerica.toString());
}
}
Other files:
class Country {
String name;
HighestPoint hp;
public Country (String nm, HighestPoint pt) {
name = nm;
hp = pt;
}
public String toString () {
return name + ": " + hp.toString() + "\n";
}
}
class HighestPoint {
String name;
int height;
public HighestPoint (String nm, int ht) {
name = nm;
height = ht;
}
public String toString () {
return name + " " + String.valueOf (height);
}
}
import java.util.*;
class Continent {
ArrayList<Country> countries;
public Continent () {
countries = new ArrayList<Country>();
}
public void addCountry (Country c) {
countries.add (c);
}
public String toString () {
String s = "";
for (Country c : countries)
s += c.toString();
return s;
}
}
I am not quite sure how to take the largest value from an array and display it along with the country name. Any help would be appreciated, thanks!
The following method in the continent class may help:
public Country getHighestPoint() {
int highest = 0;
Country temp;
for(int index = 0; index < countries.size(); index++) {
if(countries.get(index).hp.height > highest) {
highest = countries.get(index).hp.height
temp = countries.get(index)
}
}
return temp;
}
This exercise is a good opportunity to learn about the Comparable and Comparator
Starting with Comparable, you should apply this to your HighestPoint
class HighestPoint implements Comparable<HighestPoint> {
String name;
int height;
public HighestPoint (String nm, int ht) {
name = nm;
height = ht;
}
public String toString () {
return name + " " + String.valueOf (height);
}
public int compareTo(HighestPoint hp) {
return height - hp.height;
}
}
Now that's done, you can compare two HighestPoints and determine which is bigger.
Next: Comparator. We can use this with Continent, as you have a Collection (ArrayList) of all the Countries in a Content.
class Continent {
//... keep what is already in Continent
Comparator countryComparator = new Comparator<Country> () {
public int compare(Country a, Country b) {
return a.highestPoint.compareTo(b.highestPoint);
}
}
}
Now we can compare Countries and sort the array list by their HighestPoint
The reason it makes sense to use Comparable with HighestPoint and Comparator with your Countries array is that HighestPoint is a class defined with two data points: A name and a height. Whereas a Country could have many data points, and you could have many Comparators to sort Countries based on different criteria
You can solve it with Collections.
Country countryWithHighestPoint = Collections.max(southAmerica.countries, Comparator.comparing(s -> s.hp.height));
continentTest
import java.util.Collections;
import java.util.Comparator;
public class continentTest {
public static void main(String[] args) {
Continent southAmerica = new Continent();
Country southAmericanRepublic = new Country("Argentina", new HighestPoint("Aconcagua", 6960));
southAmerica.addCountry(southAmericanRepublic);
Country anotherSouthAmericanRepublic = new Country("Columbia", new HighestPoint("Pico Cristóbal Colón", 5730));
southAmerica.addCountry(anotherSouthAmericanRepublic);
Country countryWithHighestPoint = Collections.max(southAmerica.countries, Comparator.comparing(s -> s.getHighestPoint().getHeight()));
System.out.println(countryWithHighestPoint.toString());
System.out.println(southAmerica.toString());
}
}
Country
class Country {
private String name;
private HighestPoint hp;
public Country (String nm, HighestPoint pt) {
name = nm;
hp = pt;
}
public String toString () {
return name + ": " + hp.toString() + "\n";
}
public HighestPoint getHighestPoint()
{
return hp;
}
}
HighestPoint
class HighestPoint {
private String name;
private int height;
public HighestPoint (String nm, int ht) {
name = nm;
height = ht;
}
public String toString () {
return name + " " + String.valueOf (height);
}
public int getHeight()
{
return height;
}
}
I am a Java beginner and two questions boggle me really hard, so I have these questions.
For instance, I do not understand why in the Class Suitcase the method call getWeight() can be called, but in the Class Hold the method call totalWeight() not.
It works here:
public int totalWeight() {
int momentaryWeight = 0;
for (Item items: this.itemList) {
momentaryWeight = momentaryWeight + items.getWeight();
}
return momentaryWeight;
}
But not here:
public String toString() {
int momentaryWeight = 0;
int index = 0;
for (int i = index; i < this.suitcaseList.size(); i++) {
Suitcase suitcaseChosen = this.suitcaseList.get(i);
int weightOfsuitcaseChosen = suitcaseChosen.totalWeight();
momentaryWeight += weightOfsuitcaseChosen;
}
Also when having a method that returns something and using an if statement (so 2 return statements) it asks me afterwards for another return statement, like here:
public Item printGoods() {
if (this.itemList.isEmpty() == true) {
return null;
} else {
for (Item itemThis: this.itemList) {
return itemThis;
}
}
return null;
}
I know that maybe these are dull questions, but I couldn't think of a better forum to understand it.
Thanks.
The Hold class:
public class Hold {
private int maxWeight;
private ArrayList<Suitcase> suitcaseList;
public Hold(int maxWeightGiven) {
this.maxWeight = maxWeightGiven;
this.suitcaseList = new ArrayList<>();
}
public void addSuitcase(Suitcase suitcase) {
this.suitcaseList.add(suitcase);
}
public String toString() {
int momentaryWeight = 0;
int index = 0;
for (int i = index; i < this.suitcaseList.size(); i++) {
Suitcase suitcaseChosen = this.suitcaseList.get(i);
int weightOfsuitcaseChosen = suitcaseChosen.totalWeight();
momentaryWeight += weightOfsuitcaseChosen;
}
return this.suitcaseList.size() + " suitcases" + " (" + momentaryWeight + " kg)";
}
The Suitcase class:
import java.util.ArrayList;
public class Suitcase {
private int maximumWeight;
private ArrayList<Item> itemList;
public Suitcase(int maximumWeightGiven) {
this.maximumWeight = maximumWeightGiven;
this.itemList = new ArrayList<>();
}
public void addItem(Item item) {
int momentaryWeight = 0;
if (momentaryWeight <= this.maximumWeight && momentaryWeight + item.getWeight() <= this.maximumWeight) {
this.itemList.add(item);
}
}
public int totalWeight() {
int momentaryWeight = 0;
for (Item items: this.itemList) {
momentaryWeight = momentaryWeight + items.getWeight();
}
return momentaryWeight;
}
The class Item looks like this:
public class Item {
private String name;
private int weight;
public Item(String nameGiven, int weightGiven) {
this.name = nameGiven;
this.weight = weightGiven;
}
public String getName() {
return this.name;
}
public int getWeight() {
return this.weight;
}
public String toString() {
return this.name + "( " + this.weight + " kg)";
}
}
}
First question is incomplete code and detail.
Second question: suppose if-condition is false and your loop condition is also false(empty array) then the program will not reach to return statement that's why you have to add an extra return statement.
You can move last return line inside the else block
Don't know what happened, but as I worked on it a while later, suddenly the error messages disappeared and I was able to run the program. Is there a special key in NetBeans for "Refreshing"?
I have an ArrayList that contains objects. Each of the object has 3 values: String name, double price, int quantity. How to write method that will sum all doubles of objects and print the result. And also if int quantity>1, price will be multiplied by quantity.
Code that i wrote so far:
Product class
public class Product {
private String name;
private double price;
private int quantity;
public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public static Product createProduct(String name, double price, int quantity){
return new Product(name, price, quantity);
}
}
Product list class
import java.util.ArrayList;
import java.util.List;
public class ProductList {
private String name;
List<Product> newList;
public ProductList(String name) {
this.name = name;
this.newList = new ArrayList<>();
}
public boolean addNewProduct(Product product) {
if (findProduct(product.getName()) >= 0) {
System.out.println("Product is already on the list");
return false;
}
newList.add(product);
return true;
}
public boolean removeProduct(Product product) {
if (findProduct(product.getName().toUpperCase()) < 0) {
System.out.println("Product not found");
return false;
}
newList.remove(product);
return true;
}
private int findProduct(String productName) {
for (int i = 0; i < newList.size(); i++) {
Product product = newList.get(i);
if (product.getName().equals(productName)) {
return i;
}
}
return -1;
}
public Product queryProduct(String name) {
int position = findProduct(name);
if (position >= 0) {
return this.newList.get(position);
}
return null;
}
public double sumProducts() {
double sum = 0;
for (int i = 0; i < newList.size(); i++) {
sum += newList.get(i).getPrice();
}
return sum;
}
/*public boolean listProducts(){};
public boolean updateProduct(){};
*/
}
Simulation class:
public class Simulation {
private static Scanner scanner = new Scanner(System.in);
private static ProductList myProductList = new ProductList("My list");
private static void addNewProduct() {
System.out.println("Enter new product name: ");
String name = scanner.nextLine();
System.out.println("Enter new product price: ");
double price = scanner.nextDouble();
System.out.println("Enter new product quantity");
int quantity = scanner.nextInt();
Product newProduct = Product.createProduct(name, price, quantity);
if (myProductList.addNewProduct(newProduct) == true) {
System.out.println("New product added: " + name + " | price: " + price + " | quantity: " + quantity);
}
}
private static void removeProduct() {
System.out.println("Enter product name: ");
String name = scanner.nextLine().toUpperCase();
Product existingProduct = myProductList.queryProduct(name);
if (existingProduct == null) {
System.out.println("No such product");
return;
}
if (myProductList.removeProduct(existingProduct)) {
System.out.println("Sucessfully deleted product: " + existingProduct.getName());
} else {
System.out.println("Error deleting");
}
}
private static void printActions() {
System.out.println("Avaiable actions");
System.out.println("press: ");
System.out.println("0 - to shut down\n" +
"1 - to add new product\n" +
"2 - to remove product\n" +
"3 - to sum all products");
}
private static void sumProducts(){
myProductList.sumProducts();
}
public static void main(String[] args) {
printActions();
boolean quit = false;
while (!quit)
try {
System.out.println("\nEnter action: ");
int action = scanner.nextInt();
scanner.nextLine();
switch ((action)) {
case 0:
System.out.println("\nShutting down...");
quit = true;
break;
case 1:
addNewProduct();
break;
case 2:
removeProduct();
break;
}
} catch (InputMismatchException e) {
System.out.println("Bad key pressed, only values form 0 to 2 accepted");
scanner.nextLine();
}
}
}
Thanks in advance
You can do it in one line using Java 8.
public double sumProducts() {
return newList.stream().mapToDouble(product -> product.getPrice() * product.getQuantity()).sum();
}
If you use double to store the price, you will get incorrect answers when you try to add and multiply the values. For example, 0.1 + 0.2 is NOT the same double as 0.3. If you want accurate arithmetic for decimal numbers, you should use the BigDecimal class in place of double. If you don't do that, I can guarantee that your program will sometimes give wrong answers.
So you need to change your Product class as follows.
public class Product {
private String name;
private BigDecimal price;
private int quantity;
public Product(String name, BigDecimal price, int quantity) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public BigDecimal getPrice() {
return price;
}
public static Product createProduct(String name, BigDecimal price, int quantity){
return new Product(name, price, quantity);
}
}
You will also need to make corresponding changes in the code that calls the methods of this class.
Once you've done that, you can use the methods of the BigDecimal class to do arithmetic. It might look something like this.
public BigDecimal calculateTotalPrice() {
BigDecimal total = BigDecimal.ZERO;
for (Product product : newList) {
BigDecimal linePrice = product.getPrice().multiply(new BigDecimal(product.getQuantity()));
total = total.add(linePrice);
}
return total;
}
the sum of each product was missing multiply by its quantity.
public double sumProducts() {
double sum = 0;
for (int i = 0; i < newList.size(); i++) {
Product product = newList.get(i);
sum += product.getPrice() * product.getQuantity();
}
return sum;
}
I am trying to search in a list but I sort as array so that I convert my linked list to array list but when I compile it without this part below. Command prompt gives "Person is not abstract and does not override abstract method compareTo(Person) in Comparable".
How can I fix this?
public int compareTo(Person other){
if (!this.name.equalsIgnoreCase(other.name))
return this.name.compareTo(other.name);
return this.name + " "+other.name;
}
Search list and sort methods:
public void searchList(String search)
{
if(phoneList.size() == 0){
System.out.println("There is no record phone book.");
}
Node<Person> tempNode = phoneList.head;
SLinkedList<Person> tempList = new SLinkedList();
for(int i=1; i<=phoneList.size; i++)
{
if (tempNode.getElement().getName().contains(search) || tempNode.getElement().getSurname().contains(search) || tempNode.getElement().getAddress().contains(search) || tempNode.getElement().getCell().contains(search) || tempNode.getElement().getHome().contains(search) || tempNode.getElement().getWork().contains(search))
{
tempList.addLast(tempNode.getElement());
personArray = new Person[tempList.size()];
Iterator<Person> it = tempList.iterator();
while(it.hasNext()){
int x = 0;
personArray[x] = it.next();
x++;
}
bubbleSort(personArray );
for(int x = 0; x < tempList.size(); x++)
System.out.println((x+1) + ""+ personArray[x]);
}
tempNode = tempNode.getNext();
}
}
public <AnyType extends Comparable<? super AnyType>> void bubbleSort(AnyType[] a) {
int outer, inner;
for (outer = a.length - 1; outer > 0; outer--) { // counting down
for (inner = 0; inner < outer; inner++) { // bubbling up
if (a[inner].compareTo(a[inner + 1]) > 0) { // if out of order...
//then swap
swapReferences(a,inner,inner+1);
}
}
}
}
public <AnyType> void swapReferences( AnyType [ ] a, int index1, int index2 )
{
AnyType tmp = a[ index1 ];
a[ index1 ] = a[ index2 ];
a[ index2 ] = tmp;
}
Person Class:
public class Person implements Comparable<Person>
{
private String name;
private String surname;
public String address;
public String cell;
public String home;
public String work;
public Person(String name, String surname, String address, String cell, String home, String work)
{
this.name = name;
this.surname = surname;
this.address = address;
this.cell = cell;
this.home = home;
this.work = work;
}
// Accessor methods:
public String getName(){
return name;
}
public String getSurname(){
return surname;
}
public String getAddress(){
return address;
}
public String getCell(){
return cell;
}
public String getHome(){
return home;
}
public String getWork(){
return work;
}
// Modifier methods:
public void setName(String name){
this.name = name;
}
public void setSurname(String surname){
this.surname = surname;
}
public void setAddress (String address){
this.address = address;
}
public void setCell (String cell){
this.cell = cell;
}
public void setHome (String home){
this.home = home;
}
public void setWork (String work){
this.work = work;
}
public String toString(){
return name + " " + surname + " " + address + " " + cell + " " + home + " " + work;
}
public int compareTo(Person other){
if (!this.name.equalsIgnoreCase(other.name))
return this.name.compareTo(other.name);
return this.name + " "+other.name;
}
}
Your existing compareTo method has a problem, but removing it violates the implements Comparable contract, since you must provide a compareTo method.
public int compareTo(Person other) {
if (!this.name.equalsIgnoreCase(other.name))
return this.name.compareTo(other.name);
// next line returns a String, but the method needs to return an int
return this.name + " " + other.name;
}
You can instead rely more directly on the standard String compareTo:
public int compareTo(Person other) {
if ( this.name.equalsIgnoreCase( other.name ) ) { return 0 };
return this.name.compareTo( other.name );
}
If you didn't have the ignore case constraint you've coded for, this would simply be
public int compareTo(Person other) {
return this.name.compareTo( other.name );
}
As an aside, there is no reason to make address, cell, home, and work public — and that's generally bad practice.
In order to implement an interface you need to implement all the methods in that interface. You either remove implements Comparable part or add public int compareTo method to your class.
The rule of compareTo method is that :
- if this Person is greater than other , return 1
- if this Person is smaller than other , return -1
- if they are equal, return 0
Basically I have multiple classes and I'm trying to get an array of LineItem for each Item that a customer purchases. LineItem includes the UPC, Description, Price, Quantity, SubTotal and Discount which is all stored in a seperate class. I'm trying to get it that when you use the method addItemToSaleList it will add to the array. I need to use an array and not an array list, so I have to copy over the array to a temp array, and then recreate a new array adding to the number the array can store and then recopying it over. I'm stuck getting the array to generate. Below is the code I have
public class Product {
private double price;
private String description;
private String ProductCode;
private DiscountStrategy discoutStrategy;
public Product(double price, String description, String ProductCode, DiscountStrategy discoutStrategy) {
this.price = price;
this.description = description;
this.ProductCode = ProductCode;
this.discoutStrategy = discoutStrategy;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getProductCode() {
return ProductCode;
}
public void setProductCode(String ProductCode) {
this.ProductCode = ProductCode;
}
public DiscountStrategy getDiscountStrategy() {
return discoutStrategy;
}
public void setDiscoutStrategy(DiscountStrategy discoutStrategy) {
this.discoutStrategy = discoutStrategy;
}
}
public class LineItem {
private Product product;
private double quantity;
public LineItem(Product product, double quantity) {
this.product = product;
this.quantity = quantity;
}
//Calculates the Discount Amount whether or not it's a percentage or dollar
//off
public double getDiscountAmount () {
return product.getDiscountStrategy().getDiscount(product.getPrice(), quantity);
}
//Calculates the Subtotal, gets the quantity from the DiscountStrategy and then
//the price from the product
public double getSubTotal() {
return quantity * product.getPrice();
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public double getQuantity() {
return quantity;
}
public void setQuantity(double quantity) {
this.quantity = quantity;
}
public class Receipt {
private LineItem[] lineItem = new LineItem[0];
public Receipt(LineItem[] lineItem) {
this.lineItem = lineItem;
}
public void addProductToTotalSale(LineItem li) {
addItemToSaleList();
}
public void addItemToSaleList() {
LineItem[] tempItemList = new LineItem[lineItem.length + 1];
for (int i = 0; i < tempItemList.length; i++) {
tempItemList[i] = lineItem[i];
}
lineItem = new LineItem[tempItemList.length];
for (int j = 0; j < lineItem.length; j++) {
lineItem[j] = tempItemList[j];
}
}
public LineItem[] getLineItem() {
return lineItem;
}
I would remove addItemToSaleList() and implement addProductToTotalSale(LineItem) like so
public void addProductToTotalSale(LineItem li) {
// Allocate the memory.
LineItem[] tempLineItem = new LineItem[1 + lineItem.length];
// Copy the array.
if (lineItem.length > 0) {
System.arraycopy(lineItem, 0, tempLineItem, 0, lineItem.length);
}
// add the new item to the new slot.
tempLineItem[lineItem.length] = li;
// update the internal array reference.
lineItem = tempLineItem;
}
Next, you should protect your constructor from null;
public Receipt(LineItem[] lineItem) {
// Try and protect from bad calls, removes need to check for nulls in
// add (addProductToTotalSale) routine.
if (lineItem != null) {
this.lineItem = lineItem;
}
}
Because you provide a default 0 sized array your code appears to be safe to continue to include the default constructor. But, you might consider making your Receipt class immutable.
I'm not sure why you are making two new arrays. You only need one...
public void addProductToTotalSale(LineItem li) {
addItemToSaleList();
lineItem[lineItem.length-1] = li;
}
public void addItemToSaleList() {
LineItem[] tempItemList = new LineItem[lineItem.length + 1];
for (int i = 0; i < tempItemList.length; i++) {
tempItemList[i] = lineItem[i];
}
lineItem = tempItemList;
}