I'm making code in Java to put in numbers for variables a, b, c, and a label that calculates dimensions for a ellipsoid. Typing in Ellipsoid ex1 = new Ellipsoid ("Ex 1", 1, 2, 3); should give me the following in Interactions:
Ellipsoid "Ex 1" with axes a = 1.0, b = 2.0, c = 3.0 units has:
volume = 25.1327 cubic units
surface area = 48.9366 square units
But it gives me nothing. It's blank. I suspect that the last return statement at the bottom is coded wrong, but I can't figure out what exactly I'm doing wrong.
import java.text.DecimalFormat;
import java.util.Scanner;
public class Ellipsoid {
private String label = " ";
private double a = 0;
private double b = 0;
private double c = 0;
public Ellipsoid(String labelIn, double aIn, double bIn, double cIn) {
setLabel(labelIn);
setA(aIn);
setB(aIn);
setC(cIn);
}
public String getLabel() {
return label;
}
public boolean setLabel(String labelIn) {
if(label != null) {
this.label = label.trim();
return true;
}
else {
return false;
}
}
public double getA() {
return a;
}
public boolean setA(double aIn) {
if(a > 0) {
this.a = a;
return true;
}
else {
return false;
}
}
public double getB(){
return b;
}
public boolean setB(double bIn) {
if (b > 0) {
this.b = b;
return true;
}
else {
return false;
}
}
public double getC() {
return c;
}
public boolean setC(double cIn) {
if(c > 0) {
this.c = c;
return true;
}
else {
return false;
}
}
public double volume() {
return (4 * Math.PI * a * b * c) / 3;
}
public double surfaceArea() {
double surfaceAreaDouble = (Math.pow((a * b), 1.6) + Math.pow((a * c), 1.6) + Math.pow((b * c), (1 / 1.6)) / 3);
surfaceAreaDouble = 4 * Math.PI * Math.pow(surfaceAreaDouble, (1 / 1.6));
return surfaceAreaDouble;
}
public String toString() {
DecimalFormat decimalFormat = new DecimalFormat("#,##0.0###");
return "Ellipsoid \"" + label + "\" with axes a = " + getA() + ", b = " + getB() + ", c = " +getC() + " units has:\n volume = " + decimalFormat.format(volume()) + " square units" + "\n surface area = " + decimalFormat.format(surfaceArea()) + " cubic units";
}
}
after looking at your code, I noticed the following issues:
In your setter methods you are not using the right variables. You should use the method parameters in all your setters.
example:
public boolean setA(double aIn) {
if(a > 0) { // a should be aIn here
this.a = a; // = a should be = aIn
return true;
}
else {
return false;
}
}
the surfaceArea() method has a small mistake:
(Math.pow((a * b), 1.6) + Math.pow((a * c), 1.6) + Math.pow((b * c), (1 / 1.6)) / 3);
The last one doesn't need the "1/ 1.6" part but just "1.6" like the rest and then you need another bracket for all 3 math.pow before you divide them by 3. (also switch "cubic" and "square" words to match volume and surface correct)
After these fixes, making an object of class Ellipsoid and printing it gives the output you are looking for:
public static void main(String[] args) {
Ellipsoid ex1 = new Ellipsoid ("Ex 1", 1, 2, 3);
System.out.println(ex1);
}
output:
Ellipsoid "Ex 1" with axes a = 1.0, b = 2.0, c = 3.0 units has:
volume = 25.1327 cubic units
surface area = 48.9366 square units
Related
I have a class to calculate with complex numbers, a real part and an imaginary part as double type.
In other part I have a rational class to calculate rational numbers.
Now I want that my complex class can operate when the real part and the imaginary part are rational numbers. I've read some docs about generics but I don't know how to declare real part and imaginary part as generic types and use methods as add 2 complex numbers when the real and imaginary parts are doubles or rationals.
This is my test code:
import java.util.regex.Pattern;
public class Complex {
private double real;
private double imaginary;
private Rational qreal;
private Rational qimaginary;
public Complex(double real, double imaginary) {
super();
this.real = real;
this.imaginary = imaginary;
}
public Complex(Rational real, Rational imaginary) {
this.qreal = real;
this.qimaginary = imaginary;
}
public Complex(String z) {
z = z.replaceAll(" ","");
if(z.contains("i") || z.contains("j")){
if(z.contains("+")) {
String[] z1 = z.split(Pattern.quote("+"));
this.real = Double.parseDouble(z1[0]);
this.imaginary = Double.parseDouble(z1[1].substring(0, z1.length-1));
}
else if(z.contains("-")) {
String[] z1 = z.split(Pattern.quote("-"));
this.real = Double.parseDouble(z1[0]);
this.imaginary = -Double.parseDouble(z1[1].substring(0, z1.length-1));
}
else System.out.println("Syntax Error");
}
else System.out.println("The complex must only contains i or j as imaginary unit");
}
public double getReal() {
return real;
}
public void setReal(double real) {
this.real = real;
}
public double getImaginary() {
return imaginary;
}
public Rational getQreal() {
return qreal;
}
public void setQreal(Rational qreal) {
this.qreal = qreal;
}
public Rational getQimaginary() {
return qimaginary;
}
public void setQimaginary(Rational qimaginary) {
this.qimaginary = qimaginary;
}
public void setImaginary(double imaginary) {
this.imaginary = imaginary;
}
Complex opposite(Complex z) {return new Complex(-z.real, -z.imaginary);}
double abs() {return Math.hypot(this.real, this.imaginary);}
Complex conjugate() {return new Complex(real, -imaginary);}
Complex inverse() {
if(this.real == 0 && this.imaginary == 0) return new Complex(Double.NaN, Double.NaN);
else {
Complex c = this.conjugate();
double abs_square = Math.pow(this.abs(), 2.);
return new Complex(c.real / abs_square, c.imaginary / abs_square);
}
}
Complex add2(Complex z) {
System.out.println("Suma " + this.qreal.add(z.qreal) + " " + this.qimaginary.add(z.qimaginary) + "i");
return new Complex(this.qreal.add(z.qreal), this.qimaginary.add(z.qimaginary));
}
Complex add(Complex z) {return new Complex(this.real + z.real, this.imaginary + z.imaginary);}
Complex subtract(Complex z) {return add(z.opposite(z));}
Complex product(Complex z) {
double r, i;
r = this.real * z.real - this.imaginary * z.imaginary;
i = this.real * z.imaginary + this.imaginary * z.real;
return new Complex(r, i);
}
Complex div(Complex z) {
Complex num = this.product(z.conjugate());
double den = Math.pow(Math.hypot(z.real, z.imaginary), 2.);
return new Complex(num.real / den, num.imaginary / den);
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
return "Complex [real=" + real + ", imaginary=" + imaginary + ", qreal=" + qreal + ", qimaginary=" + qimaginary
+ "]";
}
/*#Override
public String toString() {
if(imaginary > 0.) {
if (imaginary == 1.)
return real + " + " + "i";
return real + " + " + imaginary + "i";
}
else if(imaginary < 0.) {
if (imaginary == -1.)
return real + " - " + "i";
return real + " " + imaginary + "i";
}
else if(imaginary == 0.)
return "" + real;
else if(real == 0.)
return imaginary + "i";
else
return "0";
}*/
}
If you see the code I've implemented 2 add methods but i want only one,and so that for the other methods, toString() too.
Generics are useful when you want to preserve type information. But the generic type still needs to have some known interface in order to use it. Since double and Rational don't share common interface, it will not be possible to directly create a generic implementation that works for both types.
What you could do is create an interface Complex with 2 implementations, DoubleComplex and RationalComplex:
public interface Complex<T> {
T getReal();
T getImaginary();
Complex<T> opposite(Complex<T> z);
double abs();
Complex<T> conjugate();
Complex<T> inverse();
Complex<T> add(Complex<T> z);
Complex<T> subtract(Complex<T> z);
Complex<T> product(Complex<T> z);
Complex<T> div(Complex<T> z);
}
public class DoubleComplex implements Complex<Double> {
private final double real;
private final double imaginary;
...
#Override
public Complex<Double> add(Complex<Double> z) {
return new DoubleComplex(this.real + z.getReal(), this.imaginary + z.getImaginary());
}
...
}
public class RationalComplex implements Complex<Rational> {
private final Rational real;
private final Rational imaginary;
...
#Override
public Complex<Rational> add(Complex<Rational> z) {
return new RationalComplex(this.real.add(z.getReal()), this.imaginary.add(z.getImaginary()));
}
...
}
All of the program's templates. This was a past assignment but at this point, I'm just trying to understand what's going on.
Under the Apartment class, I'm confused on how to correctly return an array of window orders for one unit, all units, and then the #Override method under ThreeBedroom.
Just for reference of what I've done so far (probably not all correct):
public class Window {
private final int width, height;
public Window(int width, int height) {
this.width = width;
this.height = height;
}
// print text like: 4 X 6 window
public String toString() {
String s = "";
s = width + " x " + height + " window";
return s;
}
// compare window objects by their dimensions
public boolean equals(Object that) {
if (that instanceof Window) {
Window w = (Window) that;
return this.width == w.width && this.height == w.height;
}
else { return false; }
}
}
class WindowOrder {
final Window window; // window description (its width and height)
int num; // number of windows for this order
WindowOrder(Window window, int num) {
this.window = window;
this.num = num;
}
// add the num field of the parameter to the num field of this object
//
// BUT
//
// do the merging only of two windows have the same size
// do nothing if the size does not match
//
// return the current object
WindowOrder add(WindowOrder order) {
if (order.equals(window)) {
this.num -= num;
return order;
}
else {
return order;
}
}
// update the num field of this object by multiplying it with the parameter
// and then return the current object
WindowOrder times(int number) {
WindowOrder window = new WindowOrder(this.window, this.num);
this.num *= number;
return window;
}
// print text like: 20 4 X 6 window
#Override
public String toString() {
String s = "";
s = num + " " + window.toString();
return s;
}
// Two orders are equal if they contain the same number of windows of the same size.
#Override
public boolean equals(Object that) {
if (that instanceof WindowOrder) {
WindowOrder order = (WindowOrder) that;
return this.num == order.num && this.window == order.window;
}
else { return false; }
}
}
public class Room {
Window window;
int numOfWindows;
Room(Window window, int numOfWindows) {
this.window = window;
this.numOfWindows = numOfWindows;
}
WindowOrder order() {
return new WindowOrder(window, numOfWindows);
}
// Print text like: 5 (6 X 8 window)
#Override
public String toString() {
String s = "";
s = numOfWindows + " (" + window.toString() + ")";
return s;
}
// Two rooms are equal if they contain the same number of windows of the same size
#Override
public boolean equals(Object that) {
if (that instanceof Room) {
Room room = (Room) that;
return this.window == room.window && this.numOfWindows == room.numOfWindows;
}
else { return false; }
}
}
class MasterBedroom extends Room {
MasterBedroom() {
super(new Window(4, 6), 3);
}
// Call parent's toString method
//
// return text like: Master bedroom: 3 (4 X 6 window)
#Override
public String toString() {
String s = "";
s = "Master bedroom: " + numOfWindows + " " + window.toString();
return s;
}
}
class GuestRoom extends Room {
GuestRoom() {
super(new Window(5, 6), 2);
}
// Call parent's toString method
//
// return text like: Guest room: 2 (5 X 6 window)
#Override
public String toString() {
String s = "";
s = "Guest room: " + numOfWindows + " " + window.toString();
return s;
}
}
class LivingRoom extends Room {
LivingRoom() {
super(new Window(6, 8), 5);
}
// Call parent's toString method
//
// return text like: Living room: 5 (6 X 8 window)
#Override
public String toString() {
String s = "";
s = "Living room: " + numOfWindows + " " + window.toString();
return s;
}
}
For Apartment's orderForOneUnit() method, I wrote this, but it seems to simplistic and I feel like I should be using a for loop..
WindowOrder[] orderForOneUnit() {
WindowOrder[] order = new WindowOrder[rooms.length];
return order;
}
Am I even close to correctly understanding this? What should be under the Apartment methods?
Didn't looks at the templates but from what you've provided, you're close. All you've done so far is create a WindowOrder[] array of length rooms. You need to add new WindowOrder(desc, num) to these arrays before return order;
/**
* All apartment rooms have the same number of windows, with the
* same size window for each of those.
*/
public class Apartment
{
private int numRooms_;
private int windowsPerRoom_;
private Window window_;
/**
* Constructor
*/
public Apartment(numRooms, windowsPerRoom, desiredWindowHeight, desiredWindowLength)
{
numRooms_ = numRooms;
windowsPerRoom_ = windowsPerRoom;
window_ = new Window(desiredWindowHeight, desiredWindowLenght);
}
/**
* Orders for one room in apartment
*/
public WindowOrder orderForOneUnit()
{
WindowOrder order = new WindowOrder(window_, 1);
return order;
}
/**
* Orders for all rooms in apartment
*/
public List<WindowOrder> orderForAllUnits()
{
List<WindowOrder> orders = new ArrayList<WindowOrder>();
WindowOrder order;
for(i=0; i<numRooms_; i++)
{
orders.add(new WindowOrder(window_, windowsPerRoom_);
}
return orders;
}
}
Now when you're in your code and you're ready for a new Apartment(x, x, x, x) you can do the following (I'll assume you're just in main())
public class ApartmentComplex
{
public static void main(String[] args)
{
int numWindowsPerRoom = 3;
int desiredWindowHeight = 10;
int desiredWindowWidth = 10;
int numRooms = 5;
Apartment aptWithFiveRooms = new Apartment(numRooms, numWindowsPerRoom, desiredWindowHeight, desiredWindowWidth);
WindowOrder singleSingleOrder = apt.orderForOneUnit();
List<WindowOrder> allRoomsOrder = apt.orderForAllUnits();
numRooms = 3;
Apartment aptWithThreeRooms = new Apartment(numRooms, numWindowsPerRoom, desiredWindowHeight, desiredWindowWidth);
List<WindowOrder> threeRoomsOrder = apt.orderForAllUnits();
}
}
You do need a for loop. At the moment you are returning an Array where each entry in the array is null.
Here is an example of filling an array:
for (int i = 0; i < array.length; i++) { // iterate over an array
array[i] = getValueFor(i); // put value in the array
}
I'm trying to print out locations of center dots. Compared dots must be in radius of 16. Printing out only if there is more than 5 dots in one place calculating from center.
Center dot is, which is nearest to all nearby dots
My code is giving me false positives and duplicates. Methods:
HashMap<Location, HashSet<Location>> map = new HashMap<Location, HashSet<Location>>();
for (LocationCopy loc : locs) {
HashSet<LocationCopy> locsCopy = new HashSet<LocationCopy>(locs);
locsCopy.remove(loc);
for (LocationCopy loc2 : locsCopy) {
if (distance(loc2.getX(),loc.getX(),loc2.getZ(),loc.getZ()) <= 16) {
if (!map.containsKey(loc.getLoc())) {
HashSet<Location> hs = new HashSet<Location>();
hs.add(loc2.getLoc());
map.put(loc2.getLoc(), hs);
} else {
HashSet<Location> hs = map.get(loc.getLoc());
hs.add(loc2.getLoc());
map.put(loc2.getLoc(), hs);
}
}
}
}
for (Location loc : map.keySet()) {
if (map.get(loc).size() > 5) {
write("More than " + map.get(loc).size() + locToString(loc) + ": " + getLocs(map.get(loc)) + "<br>", fileName, beta);
}
}
private double distance(double x1, double x2, double z1, double z2){
return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(z2-z1,2));
}
Class:
public class LocationCopy {
private int x, y, z;
private String world;
public LocationCopy(int x, int y, int z, String world) {
this.x = x;
this.y = y;
this.z = z;
this.world = world;
}
public LocationCopy(Location spawner) {
this.x = spawner.getBlockX();
this.y = spawner.getBlockY();
this.z = spawner.getBlockZ();
this.world = spawner.getWorld().getName();
}
public int getX(){
return x;
}
public int getZ(){
return z;
}
public Location getLoc() {
return new Location(Bukkit.getWorld(world), x, y, z);
}
}
There are serval small problems in your code:
map.put(loc2.getLoc(), hs); should be map.put(loc.getLoc(), hs); instead
You need to add a hashCode method to your classes, because otherwhise the HashSets you use will not be able to identify objects that represent the same location
You only search for groups of points, not for their centers
A solution could look like this (implemented your method in the class LocationCopy, because no class was shown in your question):
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class LocationCopy {
private int x, y, z;
//private String world;
public LocationCopy(int x/*, int y*/, int z/*, String world*/) {
this.x = x;
//this.y = y;
this.z = z;
//this.world = world;
}
public LocationCopy(Location spawner) {
this.x = spawner.getBlockX();
this.y = spawner.getBlockY();
this.z = spawner.getBlockZ();
//this.world = spawner.getWorld().getName();
}
//EDIT added toString method (just for better printing and debugging)
#Override
public String toString() {
return "LocationCopy [x=" + x + ", y=" + y + ", z=" + z + "]";
}
//EDIT: added hashCode method that is needed for the HashSets to identify objects that represent the same location
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
result = prime * result + z;
return result;
}
//EDIT: added equals method (not really needed, but better to have one...)
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LocationCopy other = (LocationCopy) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
if (z != other.z)
return false;
return true;
}
public int getX() {
return x;
}
public int getZ() {
return z;
}
public Location getLoc() {
return new Location(x, y, z);
}
public static void main(String[] args) {
List<LocationCopy> locs = createLocs();
HashMap<Location, HashSet<Location>> map = new HashMap<Location, HashSet<Location>>();
for (LocationCopy loc : locs) {
HashSet<LocationCopy> locsCopy = new HashSet<LocationCopy>(locs);
locsCopy.remove(loc);
for (LocationCopy loc2 : locsCopy) {
if (distance(loc2.getX(), loc.getX(), loc2.getZ(), loc.getZ()) <= 16) {
if (!map.containsKey(loc.getLoc())) {
HashSet<Location> hs = new HashSet<Location>();
hs.add(loc2.getLoc());
map.put(loc.getLoc(), hs);//EDIT: changed loc2 to loc
}
else {
HashSet<Location> hs = map.get(loc.getLoc());
hs.add(loc2.getLoc());
map.put(loc.getLoc(), hs);//EDIT: changed loc2 to loc
}
}
}
}
//EDIT: selecting groups for finding the center
Set<Set<Location>> groups = new HashSet<Set<Location>>();
for (Location loc : map.keySet()) {
if (map.get(loc).size() > 5) {
//EDIT: don't know what write does -> using System.out.println instead
//write("More than " + map.get(loc).size() + locToString(loc) + ": " + getLocs(map.get(loc)) + "<br>", fileName, beta);
System.out.println("More than " + map.get(loc).size() + " " + locToString(loc) + ": " + /*getLocs(map.get(loc)) + */"<br>");
//EDIT: create groups to find the center points
Set<Location> group = new HashSet<Location>();
group.addAll(map.get(loc));
group.add(loc);
groups.add(group);
}
}
//EDIT: find the center of the group
for (Set<Location> group : groups) {
Location center = findCenter(group);
System.out.println("center found: " + center);
}
}
/**
* Find the center of each group by calculating the summed distance from each point to every other point.
*
* The point that has the minimum summed distance to every other point is the center.
*/
private static Location findCenter(Set<Location> group) {
if (group.isEmpty()) {
throw new IllegalArgumentException("The group mussn't be empty");
}
List<LocationDistance> summedDistances = new ArrayList<LocationDistance>(group.size());
for (Location loc : group) {
LocationDistance dist = new LocationDistance(loc, 0);
//sum up the distance to each location in the group
for (Location loc2 : group) {
double distance = distance(loc.getBlockX(), loc2.getBlockX(), loc.getBlockZ(), loc2.getBlockZ());
dist.setDistance(dist.getDistance() + distance);
}
summedDistances.add(dist);
}
//sort the list (LocationDistance implements Comparable to do this)
Collections.sort(summedDistances);
//the first item in the list is the center
return summedDistances.get(0).getLocation();
}
private static List<LocationCopy> createLocs() {
List<LocationCopy> locs = new ArrayList<LocationCopy>();
//trying to create the example from the image in your question
locs.add(new LocationCopy(0, 0));
locs.add(new LocationCopy(2, 0));
locs.add(new LocationCopy(5, 0));
locs.add(new LocationCopy(1, 2));
locs.add(new LocationCopy(2, 1));//center
locs.add(new LocationCopy(4, 1));
locs.add(new LocationCopy(3, 2));//adding a new point because otherwhise it will never be enough for a group greater than 5
locs.add(new LocationCopy(10, 30));
locs.add(new LocationCopy(12, 31));
locs.add(new LocationCopy(15, 31));
locs.add(new LocationCopy(8, 36));
locs.add(new LocationCopy(13, 33));//center
locs.add(new LocationCopy(18, 34));
locs.add(new LocationCopy(15, 36));//adding a new point because otherwhise it will never be enough for a group greater than 5
return locs;
}
private static String locToString(Location loc) {
return loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ();
}
private static double distance(double x1, double x2, double z1, double z2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(z2 - z1, 2));
}
}
The class Location (the important part is the hashCode method):
public class Location {
public int x, y, z;
public Location(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getBlockX() {
return x;
}
public int getBlockY() {
return y;
}
public int getBlockZ() {
return z;
}
#Override
public String toString() {
return "Location [x=" + x + ", y=" + y + ", z=" + z + "]";
}
//EDIT here the hashCode is also important for the HashSets you use in your code
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
result = prime * result + z;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Location other = (Location) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
if (z != other.z)
return false;
return true;
}
}
and a new class LocationDistance for comparing distances:
/**
* A class for comparing the distances for locations
*/
public class LocationDistance implements Comparable<LocationDistance> {
private Location location;
private double distance;
public LocationDistance(Location location, double distance) {
this.location = location;
this.distance = distance;
}
#Override
public String toString() {
return "LocationDistance [location=" + location + ", distance=" + distance + "]";
}
#Override
public int compareTo(LocationDistance other) {
return Double.compare(distance, other.getDistance());
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public double getDistance() {
return distance;
}
public void setDistance(double distance) {
this.distance = distance;
}
}
The output is:
More than 6 2 0 0: <br>
More than 6 1 0 2: <br>
More than 6 2 0 1: <br>
More than 6 5 0 0: <br>
More than 6 4 0 1: <br>
More than 6 3 0 2: <br>
More than 6 10 0 30: <br>
More than 6 12 0 31: <br>
More than 6 8 0 36: <br>
More than 6 15 0 31: <br>
More than 6 13 0 33: <br>
More than 6 15 0 36: <br>
More than 6 18 0 34: <br>
More than 6 0 0 0: <br>
center found: Location [x=2, y=0, z=1]
center found: Location [x=13, y=0, z=33]
Here the last two lines are the centers you were searching for.
I am working on a boat program that has a super class (Boat) and two subclasses (SailBoat, Powerboat) and I must print out all of the boats information and price as well as the most expensive boat and it's information alone. This is the part I am having trouble with since I am not entirely sure how to go about it. Here is what I have so far...
Boat Class:
public class Boat {
String color;
int length;
public Boat() {
color = "white";
length = 20;
}
public Boat(String col, int leng) {
color = col;
length = leng;
}
public boolean setColor(String col) {
if ("white".equals(col) || "red".equals(col) || "blue".equals(col) || "yellow".equals(col)) {
col = color;
return true;
} else {
System.out.println("Error: can only be white, red, blue or yellow");
return false;
}
}
public String getColor() {
return color;
}
public boolean setLength(int leng) {
if (leng < 20 || leng > 50) {
leng = length;
System.out.println("Sail Boats can only be between 20 and 50 feet, inclusively.");
return false;
} else {
return true;
}
}
public int getLength() {
return length;
}
public String toString() {
String string;
string = String.format("Color = " + color + " Length = " + length);
return string;
}
public int calcPrice() {
int price;
price = 5000 + length;
return price;
}
}
PowerBoat Subclass
import java.text.NumberFormat;
public class PowerBoat extends Boat {
int engineSize;
public PowerBoat() {
super();
engineSize = 5;
}
public PowerBoat(String col, int len, int esize) {
this.color = col;
this.length = len;
engineSize = esize;
}
public boolean setEngineSize(int esize) {
if (esize < 5 || esize > 350) {
System.out.println(
"Error: That engine is too powerful. The engine size must be between 1 and 350, inclusively");
esize = engineSize;
return false;
} else {
return true;
}
}
public int calcPrice() {
int price;
price = 5000 + length * 300 + engineSize * 20;
return price;
}
public String toString() {
NumberFormat nf = NumberFormat.getCurrencyInstance();
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
return super.toString() + " Engine Size = " + engineSize + " Price = " + nf.format(calcPrice());
}
}
SailBoat subclass
import java.text.NumberFormat;
public class SailBoat extends Boat {
int numSails;
public SailBoat() {
numSails = 0;
}
public SailBoat(String col, int leng, int numsail) {
color = col;
length = leng;
numSails = numsail;
}
public boolean setNumSails(int nsails) {
if (nsails < 1 || nsails > 4) {
nsails = numSails;
return false;
} else {
return true;
}
} // end setNumSails
public int getNumSails() {
return numSails;
}
public int calcPrice() {
int price;
price = length * 1000 + numSails * 2000;
return price;
}
public String toString() {
NumberFormat nf = NumberFormat.getCurrencyInstance();
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
return super.toString() + "Color: " + color + " Length: " + length + " Number Sails = " + numSails + " Cost = "
+ nf.format(calcPrice());
}
public int getTotalCost() {
int totalCost = 0;
totalCost += calcPrice();
return totalCost;
}
}
Inventory class (tester)
import java.util.ArrayList;
public class Inventory {
public static void main(String[] args) {
// boat objects
Boat pb1 = new PowerBoat("blue", 22, 60);
Boat sb1 = new SailBoat("white", 20, 1);
Boat sb2 = new SailBoat("red", 42, 3);
Boat pb2 = new PowerBoat("yellow", 35, 80);
Boat pb3 = new PowerBoat("red", 50, 120);
Boat sb3 = new SailBoat("blue", 33, 2);
Boat pb4 = new PowerBoat("white", 20, 10);
ArrayList<Boat> AL = new ArrayList<Boat>();
// add boat objects to arraylist
AL.add(pb1);
AL.add(sb1);
AL.add(sb2);
AL.add(pb2);
AL.add(pb3);
AL.add(sb3);
AL.add(pb4);
// print all boat objects
System.out.println("Print all boats");
for (Boat anyBoat : AL) {
System.out.println(anyBoat.toString());
}
int max = 0;
int totalcost = 0;
Boat mostExpensiveBoat = null;
for (Boat anyBoat : AL) {
if (anyBoat instanceof SailBoat) {
totalcost += anyBoat.calcPrice();
if (anyBoat.calcPrice() > max) {
max = anyBoat.calcPrice();
mostExpensiveBoat = anyBoat;
}
}
}
}
}
I am really confused on how to finish up this program, the results I am supposed to get after all the boat information is printed is this..
Total price of all boats is $ 170,500.00
Most Expensive Boat: Color = red Length = 42 Number Sails = 3 Cost = $ 48,000.00
Any help will be greatly appreciated. Thank you.
There are a few design flaws you should correct:
Your Boat class should be an interface or abstract. You can't have a boat that isn't a power boat or sail boat so you should not be able to instantiate one.
Your instance variables should be private.
Make methods abstract that need to be defined by subclasses of Boat (e.g. calcPrice).
If you are able to use Java 8 then there's a nice way of getting the most expensive boat. The following code will print the most expensive boat (using Boat.toString) if one is present.
allBoats.stream()
.max(Comparator.comparingInt(Boat::calcPrince))
.ifPresent(System.out::println);
That avoids having to write the code that manually iterates through your list comparing prices. It also copes with the situation of an empty list (which means there is no maximum). Otherwise you need to initialise to null and compare to null before printing.
Your for loop should look like this:
for (Boat anyBoat : AL) {
totalcost += anyBoat.calcPrice();
if (anyBoat.calcPrice() > max) {
max = anyBoat.calcPrice();
mostExpensiveBoat = anyBoat;
}
}
It doesn't matter if it's a sailBoat or not, you just wanna print the information of the most expensive one, so you can remove the instanceof condition. After that:
NumberFormat nf = NumberFormat.getCurrencyInstance();
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
System.out.println("Total price of all boats is " + nf.format(totalcost));
System.out.println("Most expensive boat: " + mostExpensiveBoat.toString());
Should work, since you have already overriden the toString() methods.
one more thing: In your SailBoat toString() method, you are doing:
return super.toString() + "Color: " + color + " Length: " + length + " Number Sails = " + numSails + " Cost = "
+ nf.format(calcPrice());
When you call the super.toString() you are printing the color and the length twice; just call
return super.toString() + " Number Sails = " + numSails + " Cost = " + nf.format(calcPrice());
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
I am trying to create a program where you can change a fans speed, color, radius, and whether you can turn the fan on or off, I have the fan class working fine, except for the toString() method, for some reason when I set some values in the test program, it just defaults to the regular values, any help is accepted.
Thank you.
public class Fan {
final int SLOW = 1;
final int MEDIUM = 2;
final int FAST = 3;
public int speed = SLOW;
public boolean on = false;
public double radius = 5;
public String color = new String("blue");
//fan on
boolean fanOn() {
on = true;
return on;
}
//fan off
boolean fanOff() {
on = false;
return on;
}
//sets fan speed
String setSpeed(String speed) {
if (speed == "SLOW"){
speed = String.valueOf(SLOW);
} else if (speed == "MEDIUM") {
speed = String.valueOf(MEDIUM);
} else if (speed == "FAST") {
speed = String.valueOf(FAST);
} else {
speed = "Please enter 'SLOW', 'MEDIUM' or 'FAST' to change the speed of the fan.";
}
return speed;
}
//sets custom radius
double setRadius(double rad) {
rad = radius;
return rad;
}
//sets custom color
String setColor(String colorType) {
return colorType;
}
//toString() method
public String toString() {
return ("Speed: " + speed + "\nRadius: " + radius + "\nColor: " + "\nOn: " + on);
}
}
//test program
public class TestFan {
public static void main(String[] args) {
Fan fan1 = new Fan();
fan1.setColor("green");
fan1.setSpeed("FAST");
fan1.setRadius(3.5);
fan1.fanOff();
System.out.println(fan1.toString());
}
}
This just outputs:
Speed: 1
Radius: 5.0
Color:
On: false
public class Fan {
final int SLOW = 1;
final int MEDIUM = 2;
final int FAST = 3;
public int speed = SLOW;
public boolean on = false;
public double radius = 5;
public String color = new String("blue");
//fan on
void fanOn() {
on = true;
return on;
}
//fan off
void fanOff() {
on = false;
return on;
}
//sets fan speed
void setSpeed(String speed) {
this.speed=speed;
}
//sets custom radius
double setRadius(double rad) {
rad = radius;
return rad;
}
//sets custom color
void setColor(String colorType) {
color = colorType;
}
//toString() method
public String toString() {
return ("Speed: " + speed + "\nRadius: " + radius + "\nColor: " + "\nOn: " + on);
}
}
//test program
public class TestFan {
public static void main(String[] args) {
Fan fan1 = new Fan();
fan1.setColor("green");
fan1.setSpeed("FAST");
fan1.setRadius(3.5);
fan1.fanOff();
System.out.println(fan1.toString());
}
}