Sorting with abstract class - java

I had some difficulties in sorting in decreasing order the elements of the following abstract class and its extensions.
package BankServices;
public abstract class Operation {
public Operation (int date, double value){
}
public abstract double getValue();
public abstract int getDate();
public abstract String toString();
}
package BankServices;
public class Deposit extends Operation {
private int date;
private int value;
public Deposit(int date, double value) {
super(date, value);
// TODO Auto-generated constructor stub
}
#Override
public String toString() {
// TODO Auto-generated method stub
return date + "," + value + "+";
}
#Override
public double getValue() {
// TODO Auto-generated method stub
return value;
}
#Override
public int getDate() {
// TODO Auto-generated method stub
return date;
}
}
package BankServices;
public class Withdrawal extends Operation{
private int date;
private double value;
public Withdrawal(int date, double value) {
super(date, value);
// TODO Auto-generated constructor stub
}
#Override
public String toString() {
// TODO Auto-generated method stub
return date + "," + value + "-";
}
#Override
public double getValue() {
// TODO Auto-generated method stub
return value;
}
#Override
public int getDate() {
// TODO Auto-generated method stub
return date;
}
}
I had to implement these methods of the main class returning sorted lists in descending order:
public List<Operation> getMovements() {
Collections.sort(operations, new Comparator<Operation>(){
public int compare(Operation a, Operation b){
return (int) (b.getDate() - a.getDate());
}
});
return operations;
}
public List<Deposit> getDeposits() {
Collections.sort(deposits, new Comparator<Operation>(){
public int compare(Operation a, Operation b){
return (int) (b.getValue() - a.getValue());
}
});
return deposits;
}
public List<Withdrawal> getWithdrawals() {
Collections.sort(withdrawals, new Comparator<Operation>(){
public int compare (Operation a, Operation b){
return (int) (b.getValue() - a.getValue());
}
});
return withdrawals;
}
the first one returns a List ordered by date, while getDeposits() and getWithdrawals() return List and List ordered by value..
Could you please suggest how to make it work without mistakes and failures?
Thank you very much in advance.

Instead of this - use compareTo(...) method which is both on Double and Date, so for example:
Collections.sort(withdrawals, new Comparator<Operation>(){
public int compare (Operation a, Operation b){
return Double.valueOf(b.getValue()).compareTo(Double.valueOf(a.getValue()));
}
});
Still, your code should work, except for some weird data you can have there... But not for real life data I think
EDIT: I was wrong, your code would only work if difference between doubles would be over 1.

Related

Junit5 how to count employees in UnitTest

So I have 3 packages, Implementation, interfaces and test. I want to write the functionality into EmployeeImp so my unit test passes without error when I run it on TestEmployeeImp. However I'm not sure how getEmployeeCount is written as it fails in the unit test. I tried to solve it by creating the int count but it doesn't work. I know I need to use the array list to count the number of employees but I cannot come up with a solution and I can't find any samples of code that are like my unit test. If anyone can help it would be very appreciated.
//EmployeeImp
import java.util.ArrayList;
import java.util.List;
import interfaces.Employer;
import interfaces.Person;
public class EmployerImpl implements Employer {
private String name;
private List<Person> employees;
private int count;
public EmployerImpl(String n) {
//gets name
this.name = n;
//Array List
employees = new ArrayList<Person>();
// TODO Auto-generated constructor stub
}
#Override
public void hire(Person p, String title, double salary) {
p.setJob(null);
employees.add(p);
}
#Override
public List<Person> getEmployees() {
//Returns Employees in a List
return employees;
}
#Override
public int getEmployeeCount() {
return this.count;
//Returns employees size
}
#Override
public boolean fire(Person p) {
// TODO Auto-generated method stub
return false;
}
#Override
public String getName() {
//returns name
return name;
}
#Override
public boolean isEmployed(Person p) {
// TODO Auto-generated method stub
return false;
}
#Override
public Person getHighestPaid() {
// TODO Auto-generated method stub
return null;
}
#Override
public Person getLowestPaid() {
// TODO Auto-generated method stub
return null;
}
#Override
public double getStaffCost() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getCountOf(String title) {
// TODO Auto-generated method stub
return 0;
}
#Override
public List<Person> getAll(String title) {
// TODO Auto-generated method stub
return null;
}
}
//Employer.java
import java.util.List;
public interface Employer {
void hire(Person p, String title, double salary);
List<Person> getEmployees();
int getEmployeeCount();
boolean fire(Person p);
String getName();
boolean isEmployed(Person p);
Person getHighestPaid();
Person getLowestPaid();
double getStaffCost();
int getCountOf(String title);
List<Person> getAll(String title);
}
//TestEmployeeImp
import static org.junit.jupiter.api.Assertions.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import implementation.EmployerImpl;
import implementation.PersonImpl;
import interfaces.Employer;
import interfaces.Person;
class TestEmployerImpl {
private Employer e;
private Person highest;
private Person lowest;
#BeforeEach
void setUp() throws Exception {
e = new EmployerImpl("NCCO");
lowest = new PersonImpl("John", 18);
e.hire(lowest, "Lab Assistant", 20000);
highest = new PersonImpl("Anu", 50);
e.hire(highest, "Best Teacher", 80000);
e.hire(new PersonImpl("Damien", 18), "Teacher", 41000);
e.hire(new PersonImpl("Malachy", 45), "Teacher", 50000);
}
#Test
void testGetEmployees() {
List<Person> l = e.getEmployees();
assertNotNull(l);
assertEquals(4, l.size());
}
#Test
void testGetEmployeeCount() {
assertEquals(4, e.getEmployeeCount());
Person p = new PersonImpl("Paul H", 50);
e.hire(p, "teacher", 1000);
assertEquals(5, e.getEmployeeCount());
e.fire(p);
assertEquals(4, e.getEmployeeCount());
}
#Test
void testFire() {
Person p = new PersonImpl("Damien", 18);
boolean f= e.fire(p);
assertTrue(f);
assertEquals(3, e.getEmployeeCount());
p = new PersonImpl("Danika", 23);
f = e.fire(p);
assertFalse(f);
}
#Test
void testGetName() {
assertEquals("NCCO", e.getName());
}
#Test
void testIsEmployed() {
Person p = new PersonImpl("Damien", 18);
assertTrue(e.isEmployed(p));
p = new PersonImpl("Danika", 23);
assertFalse(e.isEmployed(p));
}
#Test
public void testGetHighestPaid() {
assertEquals(highest, e.getHighestPaid());
}
#Test
void getLowestPaid() {
assertEquals(lowest, e.getLowestPaid());
}
#Test
void getStaffCost() {
assertEquals(191000, e.getStaffCost());
}
#Test
void testGetCountOf() {
assertEquals(2, e.getCountOf("Teacher"));
assertEquals(0, e.getCountOf("Awesome Teacher"));
}
#Test
void testGetAll(){
assertEquals(2, e.getAll("Teacher").size());
assertNotNull(e.getAll("Dean"));
assertTrue(e.getAll("Dean").isEmpty());
}
}
I can't see any code which initialize or increment int count variable. But as you said, you don't need count variable and just use size() method in employees List
#Override
public int getEmployeeCount() {
return this.employees.size();
}
In #BeforeEach you're test by creating 4 employees.
Your hire method does 'employees.add(p);' , so it expands your list.
Your fire method does not do anything, just returning false.
Yet you expect in test testFire and testGetEmployeeCount that the number of employees has decreased. That does not happen and will fail.
You need the following fix:
IMPORTANT - Implement an equals and hash code on your PersonImpl class (so you can compare equal objects content instead of object-hash value). You can use guava or apache commmons or lombok or any other way to do that.
Then implement in 'fire' method:
#Override
public boolean fire(Person p) {
return employees.remove(p);
}
In this case I assume you will implement limitations in the 'hire' method on your class to have duplicate employees, so you need only to remove it once. If employees can be duplicate, then do to remove the employee including duplicates:
return employees.removeAll(Collections.singletonList(p));

Looking for an implementation of an abstract method

I need to make a programm which is like a rally, theres 2 types of vehicles, motorcycle and cars, two types of motorcycle, with and without sidecar, the thing is that I need to verify if there is just a motorcycle in an array list, I mean, two wheels vehicle. That verification should be done in a method called esDe2Ruedas(), which is called by an abstract overrided method called check() that should be the one that verifies if a group of vehicles from an array are able to run in the rally, if its true all the elements of the array must be from the same type.
Here is the code
this is how the program arrays the vehicles
GrandPrix gp1 = new GrandPrix();
gp1.agregar(v1);
//gp1.mostrar(v1);
gp1.agregar(v2);
System.out.println(gp1.check());
GrandPrix gp2 = new GrandPrix();
gp2.agregar(vt1);
gp2.agregar(vt2);
gp2.agregar(m2);
System.out.println(gp2.check());
GrandPrix gp3 = new GrandPrix();
gp3.agregar(vt1);
gp3.agregar(vt2);
gp3.agregar(m1);
System.out.println(gp3.check());
GrandPrix gp4 = new GrandPrix();
gp4.agregar(m1);
gp4.agregar(m2);
System.out.println(gp4.check());
This is the class that is using
import java.util.ArrayList;
public class GrandPrix extends Rally{
ArrayList<Vehiculo> ve = new ArrayList<Vehiculo>();
public void agregar(Vehiculo v) {
ve.add(v);
}
public void agregar(Carro c) {
ve.add(c);
}
public void agregar(Moto m) {
ve.add(m);
}
#Override
boolean check() {// HERE I VERIFY IF THE VEHICLES ARE COMPATIBLE
return false;
}
}
This is the class where everything goes on
public class Vehiculo {
private String Nombre;
private double velocidad_max;
private int peso;
private int comb;
public Vehiculo() {
setNombre("Anónimo");
setVel(130);
setPeso(1000);
setComb(0);
}
public Vehiculo(String string, double d, int i, int j) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
}
double rendimiento() {
return velocidad_max/peso;
}
public boolean mejor(Vehiculo otroVehiculo) {
return rendimiento()>otroVehiculo.rendimiento();
}
public String toString() {
return getNombre()+"-> Velocidad máxima = "+getVel()+" km/h, Peso = "+getPeso()+" kg";
}
/**************************************
---------SET And GET Nombre------------
***************************************/
public String getNombre() {
return Nombre;
}
public void setNombre(String nuevoNombre) {
this.Nombre=nuevoNombre;
}
/**************************************
---------SET And GET velocidad_max------------
***************************************/
public double getVel() {
return velocidad_max;
}
public void setVel(double nuevaVel) {
this.velocidad_max=nuevaVel;
}
/**************************************
---------SET And GET peso------------
***************************************/
public double getPeso() {
return peso;
}
public void setPeso(int nuevoPeso) {
this.peso=nuevoPeso;
}
/**************************************
---------SET And GET comb------------
***************************************/
public int getComb() {
return comb;
}
public void setComb(int comb) {
this.comb = comb;
}
boolean esDe2Ruedas() {
return false;
}
}
This is the class of motorcycles, which is in theory the same as the car's class, without sidecar thing
public class Moto extends Vehiculo{
private boolean sidecar;
public Moto(String string, double d, int i, int j) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
setSidecar(false);
}
public Moto(String string, double d, int i, int j, boolean b) {
setNombre(string);
setVel(d);
setPeso(i);
setComb(j);
setSidecar(b);
esDe2Ruedas(false);
}
public String toString() {
String str = null;
if(isSidecar())
str =super.toString()+", Moto, con sidecar";
else
str =super.toString()+", Moto";
return str;
}
public boolean isSidecar() {
return sidecar;
}
public void setSidecar(boolean sidecar) {
this.sidecar = sidecar;
}
I guess what you presented is what is given. If you came up with the design it is ok, but I believe it could be improved. Anyway, I try to respond to what I believe was your question straight away.
Vehiculo is the super type of Moto (which can have a side car and becomes 3 wheeler).
Vehiculo has a method esDe2Ruedas, which returns false.
Moto inherits that method <-- this is wrong, it should override it and, depending on side car, return the expected boolean value.
In the check method you can now distinguish between Moto and "Moto with sidecar" by using that method.

DualHashBidiMap and getKey method

I have an issue with the DualHashBidiMap and getKey method.
I'm using Commons Collections 4.1
The containsKey method returns true for specific key insterted, but getKey method returns null for the same key;
Key Class have a SuperClass with equals and hashcode method overrided to match by id property.
Main Class
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
DualHashBidiMap<Observed, Object> map=new DualHashBidiMap<Observed,Object>();
Task t66=new Task();
t66.setId(66);
map.put(t66, "Task66");
Task tFetch=new Task();
tFetch.setId(66);
System.out.println("tFetch present:"+map.containsKey(tFetch));
System.out.println("tFetch Object:"+map.getKey(tFetch));
}
}
this is the output
tFetch present:true
tFetch Object:null
Key Class
public class Task extends Observed{
public void m1(){
System.out.println("Method called !!");
}
}
Key SuperClass
public class Observed extends Observable{
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Override
public boolean equals(Object obj) {
boolean retValue=false;
Observed t=(Observed) obj;
if(t.getId().equals(this.getId())) retValue=true;
return retValue;
}
#Override
public int hashCode() {
int hash = 3;
hash = 53 * hash + (this.getId() != null ? this.getId().hashCode() : 0);
hash = 53 * hash + this.getId();
return hash;
}
}
Tnks to all..
You are trying to get key for a value that doesn't exist in the map. May be you want to do as below
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
DualHashBidiMap<Observed, Object> map=new DualHashBidiMap<Observed,Object>();
Task t66=new Task();
t66.setId(66);
map.put(t66, "Task66");
Task tFetch=new Task();
tFetch.setId(66);
System.out.println("tFetch present:"+map.containsKey(tFetch));
// to get the key related to an object
System.out.println("tFetch Object:"+map.getKey("Task66"));
// to get a value related to a key
System.out.println("tFetch Object:"+map.get(tFetch));
}
}

toString method in self-defined class using ArrayLists

I am using three classes in my program:
Term class with variables coefficient and exponent, toString() method etc.
Polynome class, using an ArrayList to store the different Term objects.
Main class that runs the program.
Can I use the toString method of ArrayList in my Polynome class? I'm trying to, but I can't.
I need my polynome to output like this: [3x^2, 3x^1, 1x^0]
I am really confused, I'm calling the toString method of Term, using a for-loop to access each term separately.
My code:
public class Term {
private int coëfficiënt;
private int exponent;
public Term(int coëfficiënt, int exponent) {
this.coëfficiënt = coëfficiënt;
this.exponent = exponent;
}
public int getCoef() {
return coëfficiënt;
}
public int getExp() {
return exponent;
}
public String toString() {
return coëfficiënt + "x^" + exponent;
}
}
Polynome class:
public class Polynoom {
private ArrayList<Term> polynoom;
public Polynoom() {
polynoom = new ArrayList<Term>();
}
public void add(Term term) {
polynoom.add(term);
}
public Term get(int i) {
return polynoom.get(i);
}
public int size() {
return polynoom.size();
}
public String toString() {
// what should I write here?
}
}
Main class:
public class opgave3 {
public static void main(String[] args) {
Polynoom polynoom1, polynoom2, sompolynoom;
polynoom1 = new Polynoom();
polynoom1.add(new Term(1, 2));
polynoom1.add(new Term(3, 1));
polynoom1.add(new Term(1, 0));
polynoom2 = new Polynoom();
polynoom2.add(new Term(-1, 3));
polynoom2.add(new Term(2, 2));
polynoom2.add(new Term(-5, 0));
System.out.println("Tests: ");
System.out.println(polynoom1.toString());
for (int i = 0; i < polynoom1.size(); i++) {
System.out.println(polynoom1.get(i).toString());
}
System.out.println(polynoom1.get(0).toString());
}
}
You just need to use your ArrayList's toString() method as the results of Polynome's toString() method.
public class Polynome {
public ArrayList<Term> terms;
#Override
public String toString() {
if (terms != null) {
return terms.toString();
} else {
return "";
}
}
}
EDIT: The quick answer, since you put your code up is to put
return polynoom.toString();
where you have indicated. Then in your Main class you can simply write
System.out.println(polynoom1);
to show the contents in the desired format.
As Tenner said, use the toString() method of your ArrayList to get the desired output. But also make sure your Term class has a useful toString method of its own:
public class Term {
private int co, ex;
public Term(int coeff, int exp) {
co = coeff;
ex = exp;
}
#Override
public String toString() {
return co + "x^" + ex;
}
}
Add #Override toString() to your Term & Polynome class. The Term class toString() should return a string in the format of coefficientx^exponent.
Then have the Polynome class toString() return yourArrayList.toString()
public static void main(String[] args) throws Exception {
Polynome polynome = new Polynome();
polynome.addTerm(3, 2);
polynome.addTerm(3, 1);
polynome.addTerm(1, 0);
System.out.println(polynome);
}
public static class Term {
private int coefficient;
private int exponent;
public Term(int c, int e) {
coefficient = c;
exponent = e;
}
#Override
public String toString() {
return coefficient + "x^" + exponent;
}
}
public static class Polynome {
private List<Term> terms = new ArrayList<>();
public void addTerm(int coefficient, int exponent) {
terms.add(new Term(coefficient, exponent));
}
#Override
public String toString() {
return terms.toString();
}
}
Results:
Long story short, you can ALWAYS use toString() on anything, even if it's a user defined class. When you call the method, it calls the closest parent class's toString() method, which is guaranteed to be there as Object has one. If you want to control the output of toString() called on your object, you must override it. As it is, if you have an object with a member of type ArrayList, calling your object's toString() will include a ton of extra information that you probably don't want. In order to get the output you want, you need to have the code given by #Tenner's answer, which is
public class Polynome {
public ArrayList<Term> terms;
#Override
public String toString() {
if (terms != null) {
return terms.toString();
} else {
return "";
}
}
}
But you also need to override toString() in the Term class, so that each term outputs in the form desired. The reason this is required is that when you call toString() on an ArrayList, or any other container for that matter, it iterates through the container, calling each object's toString() in turn, adding whatever formatting the container class defines. Ultimately, Term's toString() will be called, and you can control that output by overriding it in the Term class.
As for the last part of the question, you need not call Term's toString() directly, as calling the toString() method of the ArrayList will do this on its own.

When printing list it is gibberish [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java Object default toString
Why is it when I print my List from filereader it is [myServiceOrder#3bc1cac, myServiceOrder#32fe621e, myServiceOrder#5adbb9b9, myServiceOrder#f7e4f49, myServiceOrder#2d874991, myServiceOrder#ceee5f1, myServiceOrder#183a37d9]
public class myServiceOrder implements ServiceOrder, Comparable<myServiceOrder>{
private int number=0;
private String ownerName="";
private String make="";
private String model="";
private int year=0;
public myServiceOrder(int number, String ownerName, String make, String model, int year) {
this.number=number;
this.ownerName=ownerName;
this.make=make;
this.model=model;
this.year=year;
}
public myServiceOrder() {
// TODO Auto-generated constructor stub
}
#Override
public void setOrderNum(int orderNumber) {
number=orderNumber;
}
#Override
public void setYear(int year) {
this.year=year;
}
#Override
public void setOwner(String ownerName) {
this.ownerName=ownerName;
}
#Override
public void setMake(String make) {
this.make=make;
}
#Override
public void setModel(String model) {
this.model=model;
}
#Override
public String getOwner() {
return ownerName;
}
#Override
public String getMake() {
return make;
}
#Override
public String getModel() {
// TODO Auto-generated method stub
return model;
}
#Override
public int getOrderNum() {
// TODO Auto-generated method stub
return number;
}
#Override
public int getYear() {
// TODO Auto-generated method stub
return year;
}
#Override
public String getMakeModelYear() {
// TODO Auto-generated method stub
return make+ " "+ model+ " "+ year+ " ";
}
#Override
public boolean equals(ServiceOrder otherServiceOrder) {
if (getOrderNum()==otherServiceOrder.getOrderNum())
return true;
else
return false;
}
#Override
public int compareTo(ServiceOrder otherServiceOrder, int key) {
int comparisonResult=0;
if(key==1)
{
if(getOrderNum()< otherServiceOrder.getOrderNum())
comparisonResult= -1;
if(getOrderNum()== otherServiceOrder.getOrderNum())
comparisonResult= 0;
if(getOrderNum()> otherServiceOrder.getOrderNum())
comparisonResult= 1;
}
else if(key==2)
{
comparisonResult = getOwner().compareTo(otherServiceOrder.getOwner());
}
else if(key==3)
{
comparisonResult = getOwner().compareTo(otherServiceOrder.getOwner());
}
return comparisonResult;
}
#Override
public int compareTo(myServiceOrder arg0) {
// TODO Auto-generated method stub
return 0;
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class List extends LinkedList<myServiceOrder> {
private static LinkedList<myServiceOrder> newList = new LinkedList();
public void Print() throws Exception
{
System.out.println(newList);
}
public LinkedList<myServiceOrder> createServiceOrder(File inFile) throws Exception {
int number=0;
String ownerName="";
String make="";
String model="";
int year=0;
myServiceOrder serviceList = new myServiceOrder();
Scanner fileScan=new Scanner(inFile);
while (fileScan.hasNext())
{
String ignore;
number = fileScan.nextInt();
//System.out.println(number);
ignore = fileScan.nextLine(); // ignore the newline
ownerName = fileScan.nextLine();
// System.out.println(ownerName);
make = fileScan.nextLine();
// System.out.println(make);
model = fileScan.nextLine();
// System.out.println(model);
year = fileScan.nextInt();
// System.out.println(year);
ignore = fileScan.nextLine(); // ignore the newline
serviceList = new myServiceOrder( number, ownerName, make, model, year);
newList.add(serviceList);
}
fileScan.close();
// System.out.println(newList.viewAll());
return newList;
}
}
Ok I see, my was I dense. I also have a second question: I have to sort the list three different ways depending in my GUI what option I select, I assume that I implement Comparable, but in my compareTo interface it is compareTo(Object o, int key). How can I use that key if the sort method is just Object o. Should I try using a Comparator? if my key=1 how can I tell it to sort that way in my List class?
Classic case of a missing override of the toString() method in your myServiceOrder class.
Take a look here for examples in implementation. This page and Rohit's answer give explanations as to why you need to override toString().
Argh didn't see your second question until now when it's very late:
See this question and this question on the differences between using the Comparable interface vs using the Comparator interface.
How would Java know how you want myService objects to be printed? You can tell it by overriding toString:
#Override
public String toString() {
return "myServiceObject#" + number + "[" + ownername + ", " + make + ", " + model + ", " + year + "]";
}
System.out.println(newList);
This automatically calls the toString() method of the LinkedList class which in turn calls toString() on each of the references in the list (your ServiceOrder objects, in this case). Since you have not provided your own toString() method, the default one in Object is used. This gives the funny output myServiceOrder#3bc1cac which is Java's default way of printing a reference variable. If you wish to see something else, you need to tell Java how to do this by implementing toString() in your ServiceOrder class.
What gets printed is actually the hashcode of the object you print without overriding toString method.. Now since you're printing LinkedList, you can't do that.. Rather you can iterate over the list and print individual element: -
public void Print() throws Exception
{
for (myServiceOrder so: newList) {
System.out.println(so)
}
}
Now, since serviceOrder is itself an object.. You would need to override your toString() in that class..
#Override
public String toString() {
return this.ownerName + this.make + "[" + this.model + " - " + String.valueOf(this.year) + "]";
}

Categories