Java interfaces and objects - java

Over here i'm trying to make use of an interface called "Measurable" with one method called getMeasure. The problem is, I'm trying to get the average height of all the people in my program, by accessing the method in my interface. One of the problems I can't access the getMeasure method for some reason, and at last get the average height of all the people in the array. How can I solve this problem?
class Main {
public static void main(String args[]) {
Person[] people = new Person[4];
people[0] = new Person("Larry", 65);
people[1] = new Person("Susan", 45);
people[2] = new Person("Joe", -45);
people[3] = new Person("", 0);
double averageHeight = average(people);
}
public static double average(Person[] objects)
{
if (objects.length == 0) { return 0; }
double sum = 0;
for (Person obj : objects)
{
double measure = obj.getMeasure();
sum = sum + measure;
}
double result = sum / objects.length;
return result;
}
}
interface Measurable {
double getMeasure();
}
public class Person {
private String name;
private Integer height;
public Person(String name, Integer height)
{
this.name = name;
this.height = height;
}
public double getMeasure() {
return height;
}
}

The Person class should implement Measurable:
public class Person implements Measurable {
...
}
Then if you want to make your average function reusable (I guess this is your desired outcome), you should replace the Person instance with Measurable:
public static double average(Measurable[] objects) {
...
for (Measurable obj : objects){
...
}
}
This way you could have different Measurable implementations to calculate the average.

public class Person implements Measurable {
private String name;
private Integer height;
public Person(String name, Integer height)
{
this.name = name;
this.height = height;
}
#Override
public double getMeasure() {
return height;
}
You have to implement the to use it. If the Interface also implements the method, you have to add the #Override modifier.

Related

How to create a value object for a class with arrays Java

I have this class over here, and I was wondering how would one go about creating a value object for it. Please note I want to be able to compare two reports, so that two reports are only equal if and only if all the contents inside the arrays, name and commission are also equal.
So my value object would need to override the equals method.
Concrete Class
public class ReportImpl implements Report {
private String name;
private double commissionPerEmployee;
private double[] legalData;
private double[] cashFlowData;
private double[] mergesData;
private double[] tallyingData;
private double[] deductionsData;
public ReportImpl(String name,
double commissionPerEmployee,
double[] legalData,
double[] cashFlowData,
double[] mergesData,
double[] tallyingData,
double[] deductionsData) {
this.name = name;
this.commissionPerEmployee = commissionPerEmployee;
this.legalData = legalData;
this.cashFlowData = cashFlowData;
this.mergesData = mergesData;
this.tallyingData = tallyingData;
this.deductionsData = deductionsData;
}
#Override
public String getReportName() {
return name;
}
#Override
public double getCommission() {
return commissionPerEmployee;
}
#Override
public double[] getLegalData() {
return legalData;
}
#Override
public double[] getCashFlowData() {
return cashFlowData;
}
#Override
public double[] getMergesData() {
return mergesData;
}
#Override
public double[] getTallyingData() {
return tallyingData;
}
#Override
public double[] getDeductionsData() {
return deductionsData;
}
#Override
public String toString() {
return String.format("%s", name);
}
}
public interface Report {
/*
* Note from Tim: You would think you could use reportName as an id, but there's more than
* 1700 cases of duplicate name in the database where the marketing guys decided to call
* literally the same accounting work 10 different things (with different prices)
*/
String getReportName();
double getCommission();
double[] getLegalData();
double[] getCashFlowData();
double[] getMergesData();
double[] getTallyingData();
double[] getDeductionsData();
}

Static methods in an interface

I'm trying to add static methods largest and smallest to the Measurable interface.
The methods should return the object with the largest or smallest measure (double) from an array of Measurable Country objects. I tried doing so in the interface, but someone recommended me using the Comparator interface. How can this be done by using the Measurable interface instead?
class Main {
public static void main(String args[]) {
Measurable[] countries = new Measurable[3];
countries[0] = new Country("Uruguay", 176220);
countries[1] = new Country("Thailand", 514000);
countries[2] = new Country("Belgium", 30510);
Measurable maximum = Measurable.largest(countries);
Measurable smallest = Measurable.smallest(countries);
}
}
class Country implements Measurable {
private String name;
private double area;
public Country(String name, double area) {
this.name = name;
this.area = area;
}
}
interface Measurable {
static Measurable largest(Measurable[] countries) {
public static Measurable largest(Measurable[]objects){
if (objects == null || objects.length == 0) {
return new Country("", 0);
}
Measurable max = new Country("", 0);
for (Measurable obj : objects) {
if (obj.getMeasure() > max.getMeasure()) {
max = obj;
}
}
return max;
}
}
static Measurable smallest(Measurable[] objects) {
if (objects == null || objects.length == 0) {
return new Country("", 0);
}
Measurable max = new Country("", 0);
for (Measurable obj : objects) {
if (obj.getMeasure() < min.getMeasure()) {
min = obj;
}
}
return min;
}
}
double getMeasure();
}
You don't need to create the Measurable interface if you want to use Comparator/Comparable.
Just implement Comparable in Country and then loop through the array to find min and max.
class Main {
public static void main(String args[]) {
Country[] countries = new Country[3];
countries[0] = new Country("Uruguay", 176220);
countries[1] = new Country("Thailand", 514000);
countries[2] = new Country("Belgium", 30510);
Country max = null;
Country min = null;
for (Country c : countries) {
if (max == null || max.compareTo(c) < 0) {
max = c;
}
if (min == null || min.compareTo(c) > 0) {
min = c;
}
}
System.out.printf("max: %s (%s)%n", max.name, max.area);
System.out.printf("min: %s (%s)%n", min.name, min.area);
}
}
class Country implements Comparable<Country> {
String name;
double area;
public Country(String name, double area) {
this.name = name;
this.area = area;
}
#Override
public int compareTo(Country other) {
// Returns int <0 if this is smaller than other
// 0 if they are equal
// int >0 if this is greater than other
return Double.compare(this.area, other.area);
}
}
If you put your countries in a collection you can use the Collections.min() and Collections.max() functions together with the Comparable interface. Your main method would then look like this:
public static void main(String args[]) {
List<Country> countries = new ArrayList<>();
countries.add(new Country("Uruguay", 176220));
countries.add(new Country("Thailand", 514000));
countries.add(new Country("Belgium", 30510));
Country max = Collections.max(countries);
Country min = Collections.min(countries);
System.out.printf("max: %s (%s)%n", max.name, max.area);
System.out.printf("min: %s (%s)%n", min.name, min.area);
}
If you still want to use the Measurable interface you can extend ArrayList and have that class implement it like this:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Main {
public static void main(String args[]) {
CountryList countries = new CountryList();
countries.add(new Country("Uruguay", 176220));
countries.add(new Country("Thailand", 514000));
countries.add(new Country("Belgium", 30510));
Country max = countries.getLargest();
Country min = countries.getSmallest();
System.out.printf("max: %s (%s)%n", max.name, max.area);
System.out.printf("min: %s (%s)%n", min.name, min.area);
}
}
class CountryList extends ArrayList<Country> implements Measurable{
#Override
public Country getSmallest() {
return Collections.min(this);
}
#Override
public Country getLargest() {
return Collections.max(this);
}
}
interface Measurable{
Country getSmallest();
Country getLargest();
}
class Country implements Comparable<Country> {
String name;
double area;
public Country(String name, double area) {
this.name = name;
this.area = area;
}
#Override
public int compareTo(Country o) {
return Double.compare(this.area, o.area);
}
}

Hello i am struggling to understand why it say constructor undefined java

I wrote three classes to be used in main, but when I call the constructor of Calculator with two parameter, it tells me that the constructor is undefined. When I checked the code it looked like everything was done correctly, and I still can't find the error. Is this because am calling two instance objects in another class parameter?
I get the below error:
Unresolved compilation problem: The constructor Calculator(Floor, Carpet) is undefined.
My main code is below:
Carpet carpet = new Carpet(3.5);
Floor floor = new Floor(2.75, 4.0);
Calculator calculator = new Calculator(floor,carpet); // this line gives me the error
Calculator.java:
public class Calculator {
private double floor;
private double carpet;
Calculator(double floor, double carpet) {
this.carpet = carpet;
this.floor = floor;
}
Calculator() {
floor = 0.00;
carpet = 0.00;
}
public double getTotalCost() {
return (this.floor * this.carpet);
}
}
Floor.java:
public class Floor {
private double width;
private double length;
Floor() {}
Floor(double width, double length) {
this.length = length;
this.width = width;
}
public void setWidth(double width) {
if (this.width < 0) {
this.width = 0;
} else {
this.width = width;
}
}
public void setLength(double length) {
if (this.length < 0) {
this.length = 0;
} else {
this.length = length;
}
}
public double getArea() {
return (this.length * this.width);
}
}
Carpet.java:
public class Carpet {
private double cost;
Carpet() {}
Carpet(double cost) {
this.cost = cost;
}
public void setCost(double cost) {
if (cost < 0) {
this.cost = 0;
} else {
this.cost = cost;
}
}
public double getCost() {
return this.cost;
}
}
The constructor for Calculator calls for two double values. You passed objects of type Carpet and Floor. instead. Try editing your Calculator class to accept those types, rather than double values.
private Floor floor;
private Carpet carpet;
Calculator(Floor floor, Carpet carpet) {
// TODO Auto-generated constructor stub
this.carpet = carpet;
this.floor = floor;
}
You should also revise getTotalCost() to the below method:
public double getTotalCost() {
return this.carpet.getCost() * this.floor.getArea();
}
Your constructors are not public, they are defined as a package private. That might be the problem.

Add objects with random variables using a loop

I am trying to write a program where I ask to the user how many persons he wants to implement in this world. Afterwards, I would like as many person objects as the user answered. I defined a person class with a person constructor containing all person variables ( + getters/setters). After this, I tried to create a loop to assign values to my variables (most of them happen random). Currently, I set the number of instances I want to create to 20 (arbitrary).
This is my person class
public class Person implements Item {
public static final int MAX_AGE = 70;
public static final int MAX_SEX_APPEAL = 10;
public static final int MAX_AGRESSION_LEVEL = 10;
public static final int MAX_STRENGTH = 10;
private int id;
private int age;
private boolean gender;
private int sexAppeal;
private int agressionLevel;
private int strength;
private boolean isAlive;
public Person (int id, int age, boolean gender, int sexAppeal, int agressionLevel, int strength, boolean isAlive){
this.setId(id);
this.setAge(age);
this.setGender(gender);
this.setSexAppeal(sexAppeal);
this.setAgressionLevel(agressionLevel);
this.setStrength(strength);
this.setAlive(isAlive);
}
void getBorn () {
isAlive = true;
age = 0;
// a new people is born
// age = 0
// other variables: random
}
void die () {
isAlive = false;
// people die when they reach the max age
// people die when being on the same cell as vulcanos
// people can be murdered
// setAlive = false
}
void murder () {
// when 2 people with min agression level on the same land ==> weakest one dies
}
void move () {
// method to make people move
// random (only to adjucant fields)
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isGender() {
return gender;
}
public void setGender(boolean gender) {
this.gender = gender;
}
public int getSexAppeal() {
return sexAppeal;
}
public void setSexAppeal(int sexAppeal) {
this.sexAppeal = sexAppeal;
}
public int getAgressionLevel() {
return agressionLevel;
}
public void setAgressionLevel(int agressionLevel) {
this.agressionLevel = agressionLevel;
}
public int getStrength() {
return strength;
}
public void setStrength(int strength) {
this.strength = strength;
}
public boolean isAlive() {
return isAlive;
}
public void setAlive(boolean isAlive) {
this.isAlive = isAlive;
}
}
And this is my "test class" where I try to create 20 instances :
import java.util.concurrent.ThreadLocalRandom;
public class test {
public static void main(String[] args) {
for (int i = 0; i < 20; i ++) {
Person person(i) = new Person();
person.setId(i);
person.setAge(ThreadLocalRandom.current().nextInt(0, Person.MAX_AGE + 1));
person.setGender((Math.random() < 0.5));
person.setSexAppeal(ThreadLocalRandom.current().nextInt(0, Person.MAX_SEX_APPEAL + 1));
person.setAgressionLevel(ThreadLocalRandom.current().nextInt(0, Person.MAX_SEX_APPEAL + 1));
person.setStrength(ThreadLocalRandom.current().nextInt(0, Person.MAX_SEX_APPEAL + 1));
person.setAlive(true);
}
}
}
However, I am getting the following error at this line
Person person(i) = new Person();
The constructor Person () is undefined
Type mismatch: cannot convert from Person to int
I understand those errors but I don't know another way to become to the result I want to achieve
You should make a list and just add the created persons to it.
public class test {
public static void main(String[] args) {
List<Person> persons = new ArrayList<>(); // create a list to store the generated persons
for (int i = 0; i < 20; i++) {
Person person = new Person(); // generate a person
person.setId(i);
person.setAge(ThreadLocalRandom.current().nextInt(0, Person.MAX_AGE + 1));
person.setGender((Math.random() < 0.5));
person.setSexAppeal(ThreadLocalRandom.current().nextInt(0, Person.MAX_SEX_APPEAL + 1));
person.setAgressionLevel(ThreadLocalRandom.current().nextInt(0, Person.MAX_SEX_APPEAL + 1));
person.setStrength(ThreadLocalRandom.current().nextInt(0, Person.MAX_SEX_APPEAL + 1));
person.setAlive(true);
persons.add(person); /// add the generated person to the list
}
}
}
Also if you want to call the Person constructor without parameters the class must have a constructor that takes no parameters.
public Person() {}

Accessing objects in 2D arrays?

I want to print out the "weight" of an item in my game.
Class, "Item":
public class Item {
private String name;
private double weight;
public Item(String n, double w)
{
this.name = n;
this.weight = w;
}
}
In the main class I have this bit of code:
public static Item[][] items = {{new Item("Dagger", 1), new Item("Sword", 5), new Item("Bullet(s)", 0), new Item("Pistol", 15)},
{new Item("Torch", 2), new Item("Shovel", 5), new Item("Pickaxe", 10)},
{new Item("Gold", 0), new Item("Potion(s)", 1)}};
How could I print the weight of dagger, for example?
Unless I'm missing something,
System.out.println(items[0][0].getWeight());
Of course, your Item class will need to be modified to include accessors since the fields are private (which is the recommended approach). I suggest you also make your fields final so the class instances are immutable. I would also override toString() like
public class Item {
private final String name;
private final double weight;
public Item(String n, double w) {
this.name = n;
this.weight = w;
}
public String getName() {
return name;
}
public double getWeight() {
return weight;
}
#Override
public String toString() {
return String.format("%s %.3f", name, weight);
}
}
The advantage of overriding toString() is you could also use Arrays.deepToString(Object[]) like
System.out.println(Arrays.deepToString(items));
and get meaningful results printing the entire array.
First of all you need a getter in your Item class for weight since weight is declared private. So if you added the following method to Item:
Public Double GetWeight()
{
return this.weight;
}
Then you could access Daggar like the following:
Double weight = items[0][0].GetWeight();
system.out.println(weight);

Categories