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) + "]";
}
Related
I have a problem with method override checks. I can detect simple override relations, but if the parent class has generics and the abstract method uses type parameters (return value/args), my code breaks down because the method description is not equal to the checked method.
Example:
public interface ISetting<T> {
public T method();
}
public class Setting implements ISetting<Integer> {
public Integer method() {
//Something
}
}
In ISetting, the method description is ()Ljava/lang/Object;
and in Setting, the method description is ()Ljava/lang/Integer;
How I can check this Override ?
On my head no thoughts come, how I can make this >~< All ideas which come to my head are bad (example: ignore check on desc, but overload method just break this idea)
Note that your issue does not only apply to generic supertype. You can also override a method with a more specific return type, with no Generics involved, e.g.
interface SomeInterface {
Object method();
}
class SomeImplementation implements SomeInterface {
#Override
public Integer method() {
return null;
}
}
You have to understand the concept of bridge methods.
A bridge method performs the task of overriding a method on the byte code level, having exactly the same parameter types and return type as the overridden method, and delegates to the actual implementation method.
Since the bridge method only consists of this invocation instruction, some type casts if required, and the return instruction, it is easy to parse such a method to find the actual method it belongs to, without dealing with the complex rules of the Generic type system.
Using, the following helper classes
record MethodSignature(String name, String desc) {}
record MethodInfo(int access, String owner, String name, String desc) {
MethodSignature signature() {
return new MethodSignature(name, desc);
}
}
final class MethodAndBridges {
MethodInfo actual;
final List<MethodInfo> bridges = new ArrayList<>();
MethodAndBridges(MethodSignature sig) {}
void set(MethodInfo mi) {
if(actual != null) throw new IllegalStateException();
actual = mi;
}
void addBridge(MethodInfo mi) {
bridges.add(mi);
}
}
We can gather the information in a form ready for checking override relations with the ASM library as follows:
class MethodCollector extends ClassVisitor {
static Map<MethodSignature, MethodAndBridges> getMethods(ClassReader cr) {
MethodCollector mc = new MethodCollector();
cr.accept(mc, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
return mc.found;
}
final Map<MethodSignature, MethodAndBridges> found = new HashMap<>();
String owner, superClass;
List<String> interfaces;
protected MethodCollector() {
super(Opcodes.ASM9);
}
#Override
public void visit(int version, int acc,
String name, String sig, String superName, String[] ifNames) {
owner = name;
superClass = superName;
this.interfaces = ifNames == null? List.of(): List.of(ifNames);
}
#Override
public MethodVisitor visitMethod(
int acc, String name, String desc, String sig, String[] exceptions) {
MethodInfo mi = new MethodInfo(acc, owner, name, desc);
if((acc & Opcodes.ACC_BRIDGE) == 0) {
found.computeIfAbsent(mi.signature(), MethodAndBridges::new).set(mi);
return null;
}
return new MethodVisitor(Opcodes.ASM9) {
#Override public void visitMethodInsn(
int op, String owner, String name, String tDesc, boolean i) {
found.computeIfAbsent(new MethodSignature(name, tDesc),
MethodAndBridges::new).addBridge(mi);
}
};
}
}
To demonstrate how this work, let’s enhance your example, to address more cases
interface SupplierOfSerializable {
Serializable get();
}
interface ISetting<T extends CharSequence> extends Supplier<T>, Consumer<T> {
T get();
#Override void accept(T t);
Number method(int i);
static void method(Object o) {}
private void method(Number n) {}
}
class Setting implements ISetting<String>, SupplierOfSerializable {
public String get() {
return "";
}
#Override
public void accept(String t) {}
public Integer method(int i) {
return i;
}
static void method(Object o) {}
void method(Number n) {}
}
and check the override relations (only considering the direct interfaces, without recursion)
public class CheckOverride {
public static void main(String[] args) throws IOException {
MethodCollector mc = new MethodCollector();
new ClassReader(Setting.class.getName())
.accept(mc, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
Map<MethodSignature, MethodAndBridges> implMethods = mc.found;
Map<MethodInfo, Set<MethodInfo>> overrides = new HashMap<>();
for(String ifType: mc.interfaces) {
Map<MethodSignature, MethodAndBridges> ifMethods
= MethodCollector.getMethods(new ClassReader(ifType));
System.out.println("interface " + ifType.replace('/', '.'));
printMethods(ifMethods);
System.out.println();
ifMethods.values().removeIf(CheckOverride::nonOverridable);
implMethods.forEach((sig, method) -> {
if(nonOverridable(method)) {
overrides.putIfAbsent(method.actual, Set.of());
return;
}
var overridden = ifMethods.get(sig);
if(overridden == null && method.bridges.isEmpty()) {
overrides.putIfAbsent(method.actual, Set.of());
return;
}
Set<MethodInfo> set = overrides.compute(method.actual,
(k, s) -> s == null || s.isEmpty()? new HashSet<>(): s);
if(overridden != null) set.add(overridden.actual);
for(var mi: method.bridges) {
overridden = ifMethods.get(mi.signature());
if(overridden != null) set.add(overridden.actual);
}
});
}
System.out.println("class " + mc.owner.replace('/', '.'));
printMethods(implMethods);
System.out.println();
System.out.println("Final result");
System.out.println("class " + mc.owner.replace('/', '.'));
overrides.forEach((m,overridden) -> {
System.out.println(" " + toDeclaration(m, false));
if(!overridden.isEmpty()) {
System.out.println(" overrides");
overridden.forEach(o ->
System.out.println(" " + toDeclaration(o, true)));
}
});
}
static boolean nonOverridable(MethodAndBridges m) {
return (m.actual.access() & (Opcodes.ACC_PRIVATE|Opcodes.ACC_STATIC)) != 0
|| m.actual.name().startsWith("<");
}
static void printMethods(Map<MethodSignature, MethodAndBridges> methods) {
methods.forEach((sig, methodAndBridges) -> {
System.out.println(" "+toDeclaration(methodAndBridges.actual,false));
if(!methodAndBridges.bridges.isEmpty()) {
System.out.println(" bridges");
for(MethodInfo mi: methodAndBridges.bridges) {
System.out.println(" " + toDeclaration(mi, false));
}
};
});
}
private static String toDeclaration(MethodInfo mi, boolean withType) {
StringBuilder sb = new StringBuilder();
sb.append(Modifier.toString(mi.access() & Modifier.methodModifiers()));
if(sb.length() > 0) sb.append(' ');
String clName = mi.owner();
var mt = MethodTypeDesc.ofDescriptor(mi.desc());
if(mi.name().equals("<init>"))
sb.append(clName, clName.lastIndexOf('/') + 1, clName.length());
else {
sb.append(mt.returnType().displayName()).append(' ');
if(withType) sb.append(clName.replace('/', '.')).append('.');
sb.append(mi.name());
}
if(mt.parameterCount() == 0) sb.append("()");
else {
String sep = "(";
for(ClassDesc cd: mt.parameterList()) {
sb.append(sep).append(cd.displayName());
sep = ", ";
}
sb.append(')');
}
return sb.toString();
}
}
interface ISetting
public static void method(Object)
public abstract void accept(CharSequence)
bridges
public void accept(Object)
public abstract Number method(int)
private void method(Number)
public abstract CharSequence get()
bridges
public Object get()
interface SupplierOfSerializable
public abstract Serializable get()
class Setting
Setting()
public Integer method(int)
bridges
public Number method(int)
public void accept(String)
bridges
public void accept(Object)
public void accept(CharSequence)
static void method(Object)
public String get()
bridges
public Object get()
public CharSequence get()
public Serializable get()
void method(Number)
Final result
class Setting
public String get()
overrides
public abstract Serializable SupplierOfSerializable.get()
public abstract CharSequence ISetting.get()
Setting()
public Integer method(int)
overrides
public abstract Number ISetting.method(int)
public void accept(String)
overrides
public abstract void ISetting.accept(CharSequence)
void method(Number)
static void method(Object)
The code uses newer Java features, like var, record, and the constant API, but I think, the result is straight-forward enough for converting it to older Java versions, if really required.
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));
I have just completed the following program -
//interface IFile
package zad;
public interface IFile {
void readFromFile();
}
//class Student
package zad;
public class Student implements Comparable {
private String studentName;
private int facNum, studentPoints;
public Student(int facNum, String studentName, int studentPoints) {
this.facNum = facNum;
this.studentName = studentName;
this.studentPoints = studentPoints;
}
public void setFacNum(int facNum) {
this.facNum = facNum;
}
public int getFacNum() {
return facNum;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getStudentName() {
return studentName;
}
public void setStudentPoints(int studentPoints) {
this.studentPoints = studentPoints;
}
public int getStudentPoints() {
return studentPoints;
}
public boolean equals(Object o) {
if(o instanceof Student && ((Student) o).getFacNum() == this.facNum) {
return true;
} else {
return false;
}
}
public String toString() {
return ("FacNum = " + facNum + ", name = " + studentName
+ ", points = " + studentPoints );
}
public int compareTo(Object o) {
return Integer.compare(this.facNum, ((Student)o).getFacNum());
}
}
//class StudentsGroup
package zad;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class StudentsGroup implements IFile, Comparable {
private String groupName;
private List<Student> studentsList = new ArrayList<Student>();
public StudentsGroup(String groupName) {
this.groupName = groupName;
}
public void printArrayList() {
for(Student o : studentsList)
System.out.println(o);
}
public int compareTo(Object o) {
if(getTotalPoints(studentsList) > getTotalPoints(((StudentsGroup)o).studentsList))
return 1;
else if(getTotalPoints(studentsList) < getTotalPoints(((StudentsGroup)o).studentsList))
return -1;
else
return 0;
}
public List getList() {
return studentsList;
}
public static int getTotalPoints(List<Student> studentsList1) {
int totalPoints = 0;
for(Student o : studentsList1) {
totalPoints += o.getStudentPoints();
}
return totalPoints;
}
public void sortByPoints() {
Collections.sort(studentsList);
}
public void readFromFile() {
Scanner sc;
try {
sc = new Scanner(new File(groupName));
while(sc.hasNext()) {
int facNum = sc.nextInt();
String studentName = sc.next();
int studentPoints = sc.nextInt();
Student object = new Student(facNum, studentName, studentPoints);
studentsList.add(object);
}
sc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#Override
public String toString() {
return "StudentsGroup [groupName=" + groupName + ", studentsList=" + studentsList + "]";
}
}
//class main
package zad;
import java.io.FileNotFoundException;
public class demo {
public static void main(String[] args) throws FileNotFoundException {
StudentsGroup studentsGroup1 = new StudentsGroup("D://test.txt");
StudentsGroup studentsGroup2 = new StudentsGroup("D://test2.txt");
studentsGroup1.readFromFile();
studentsGroup2.readFromFile();
studentsGroup1.printArrayList();
studentsGroup1.sortByPoints();
studentsGroup1.printArrayList();
int compareResult = studentsGroup1.compareTo(studentsGroup2);
switch(compareResult) {
case 0: System.out.println("The two lists are equal by points.");
break;
case 1: System.out.println("The first list is larger than the second.");
break;
case -1: System.out.println("The first list is smaller than the second.");
break;
}
}
}
In general, it makes an object from class StudentsGroup, reads from a file and adds to an ArrayList field, as objects of another class - Student.
How should I implement a method to write that data to a new file? Any thoughts on that?
Note: also, if possible, I would like some tips on my coding to help me write better code. Am I doing something completely wrong or unnecessary in my program? The method getTotalPoints needs to be declared as static, so that is not discussed.
UPDATE:
When I try to write the data to a file with the following code:
FileOutputStream out = new FileOutputStream("D://test3.txt");
ObjectOutputStream oout = new ObjectOutputStream(out);
for(Student o : studentsList)
oout.writeObject(o);
out.close();
oout.close();
I get an error:
Exception in thread "main" java.io.NotSerializableException: zad.Student
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at zad.StudentsGroup.writeToFile(StudentsGroup.java:80)
at zad.demo.main(demo.java:27)
Am I doing something wrong?
According to the documentation for ObjectOutputStream, the writeObject method throws a NotSerializableException because Students does not implement Serializable.
NotSerializableException - Some object to be serialized does not implement the java.io.Serializable interface.
Update your class signature to the following and implement any methods required by Serializable.
public class Student implements Comparable, Serializable
By using the ObjectOutputStream.writeObject method you have no control over the output. If you want to control how the content is actually output to the file you'll want to look into an alternative writer. Look into examples of using BufferedWriter. You could then pass Student.toString() to the writer and control the way in which the data shows up. For instance, your toString() method in Student could output field1 + "\t" + field2 + "\t" + field3 + "\t" + field4 - and you'd essentially have a tab-delimited file that you could then, for instance, import into Excel.
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.
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.