Getting incompatible error for parent child classes java - java

I have a HashMap defined:
HashMap<String,ArrayList<Thing>> hashmap = new HashMap<>();
I do need an ArrayList since I want one key to have multiple values. This was the best solution I found for that problem.
The Thing class is a parent class for a bunch of other classes. Problem is when I try to add I get an error.
hashmap.put(b, world.ports);
This is the error:
no suitable method found for put(String,ArrayList<SeaPort>)
method Map.put(String,ArrayList<Thing>) is not applicable
(argument mismatch; ArrayList<SeaPort> cannot be converted to ArrayList<Thing>)
method AbstractMap.put(String,ArrayList<Thing>) is not applicable
(argument mismatch; ArrayList<SeaPort> cannot be converted to ArrayList<Thing>)
method HashMap.put(String,ArrayList<Thing>) is not applicable
(argument mismatch; ArrayList<SeaPort> cannot be converted to ArrayList<Thing>)
`
I dont understand this since SeaPort extends Thing isn't it supposed to be compatible? I have read a bunch of upcasting and downcasting threads but I don't see how they apply here.
Here is the Thing class:
package seaportprogram;
import java.util.Scanner;
public class Thing implements Comparable<Thing>{
String name;
int index;
int parent;
World world;
public Thing(){
name = null;
index = 0;
parent =0;
}
//Thing Scanner Constructor
public Thing (Scanner sc){
if(sc != null){
name = sc.next();
index = sc.nextInt();
parent = sc.nextInt();
}
}
// Get Index
public int getIndex(){
return index;
}
//Get Name
public String getName(){
return name;
}
//Get Parent
public int getParent(){
return parent;
}
//Thing To String
public String toString(){
return name + " " + index;
}
//Auto-Gen Compare Method
#Override
public int compareTo(Thing o) {
// TODO Auto-generated method stub
return 0;
}
}//End - Class Thing
Here is the SeaPort class:
package seaportprogram;
import java.util.ArrayList;
import java.util.Scanner;
class SeaPort extends Thing {
ArrayList<Dock> docks;
ArrayList<Ship> que;
ArrayList<Ship> ships;
ArrayList<Person> persons;
//Sea Port Scanner Constructor
public SeaPort(Scanner sc){
super(sc);
docks = new ArrayList<>();
que = new ArrayList<>();
ships = new ArrayList<>();
persons = new ArrayList<>();
}
//Set Docks
public void setDocks(ArrayList<Dock> docks){
this.docks = docks;
}
//Get Docks
public ArrayList<Dock> getDocks(){
return docks;
}
//Set Ships
public void setShips(ArrayList<Ship> ships){
this.ships = ships;
}
//Get Ships
public ArrayList<Ship> getShips(){
return ships;
}
//Set Que
public void setQue(ArrayList<Ship> que){
this.que = que;
}
//Get Que
public ArrayList<Ship> getQue(){
return que;
}
//Sea Port To String
public String toString(){
String string = "\n\n Sea Port: " + super.toString() + "\n";
for(Dock md: docks){
string += "\n" + md + "\n";
}
string += "\n\n --- List of all ships in Que: ";
for(Ship ms: que){
string += "\n > " + ms;
}
string += "\n\n --- List of all Ships:";
for(Ship ms: ships){
string += "\n > " + ms;
}
string += "\n\n --- List of all Persons:";
for(Person mp: persons){
string += "\n > " + mp;
}
return string;
}//End
}// End Sea Port Class
This is World class:
package seaportprogram;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
public class World extends Thing{
ArrayList<SeaPort> ports;
PortTime time;
//World Scanner Constructor
public World(Scanner sc){
super (sc);
ports = new ArrayList<>();
}
//Set Ports
}
Any way to make this happen?
TIA!
update:
I am trying to print the map and I get an null pointer exception. I think this is because the list is being initialized both in seaport and in the MyHashMap class. I cant seem to find a way to get around this and I'm not even sure this is the reason for the error. Here is the toString():
public String toString(){
if(map.isEmpty())
{
System.out.println("The hashMap is empty");
return "empty";
}
String display=" ";
Iterator<String> itr = map.keySet().iterator();
while (itr.hasNext()) {
display =display + itr.next();
Iterator<ArrayList<T>> itr2 = map.values().iterator();
while (itr2.hasNext()) {
display +=itr2.next();
}
}
return display;
}
and this is the call to it from the gui:
jta.setText(map.toString());

ArrayList<Derived_Class> does not extend ArrayList<Base_Class>.
If you want to use an HashMap like this, one solution could be to write your own wrapper class using templates:
import java.util.ArrayList;
import java.util.HashMap;
public class MyHashMap<T extends Thing> {
private HashMap<String, ArrayList<T>> map;
public MyHashMap() {
map = new HashMap<>();
}
public void add(String s, T element) {
ArrayList<T> list = null;
if ((list = map.get(s)) == null)
map.put(s, list = new ArrayList<T>());
list.add(element);
}
public ArrayList<T> get(String s) {
return map.get(s);
}
}
if you want an HashMap of SeaPorts, you can create a new HashMap like this,
MyHashMap<SeaPort> map = new MyHashMap<SeaPort>();
and use custom setters and getters to access the arraylists

Seaport may extend Thing, but ArrayList<SeaPort> does not extend ArrayList<Thing>.
If you just want to store a map of Strings to Things, you don't need ArrayList. If you really want to map Strings to Lists of Things, then you can't do it like this.

Related

update object in hashmap by java 8 lambda

I created an item named player as follows:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
public class player implements Comparable <player> {
int PlayerId ;
String name ;
double salary;
public player(int PlayerId) {
this.PlayerId = PlayerId;
}
public void setPlayerId(int PlayerId) {
this.PlayerId = PlayerId;
}
public void setName(String name) {
this.name = name;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getID() {
return PlayerId;
}
public String getName() {
return name;
}
public double getSalary() {
return salary;
}
#Override
public int hashCode() {
int key = 2;
return key=2*key+PlayerId;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final player other = (player) obj;
if (this.PlayerId != other.PlayerId) {
return false;
}
return true;
}
#Override
public String toString(){
return hashCode()+" "+getID() +" "+getName()+" "+getSalary();
}
// generic method StoreplayerDetails
public <T> void StoreplayerDetails( HashMap<Integer,T> inputMap ) {
// save elements into text file
PrintWriter pw = null;
try {
pw = new PrintWriter(new FileOutputStream("OutPut.txt"));
for(T element : inputMap.values())
pw.println(element);
pw.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(MainProgram.class.getName()).log(Level.SEVERE, null, ex);
} finally {
pw.close();
}
}
#Override
public int compareTo(player other) {
if(this.salary>other.salary)
return 1;
else
if(this.salary<other.salary)
return -1;
return 0;
}
public interface Update {
public <T> void updateSalaries( HashMap<Integer,player> inputMap);
}
}
create an interface named update in the player class ,create a generic method named updateSalaries in the interface that takes a HashMap as input and returns a Queue of player objects after updating the salaries of players by adding 500 to each one's salary .
in the mainprogram class implement the method updatesalaries as a lamdba expression .in the mainprogram class,print the elements in the returned queue .
I tried it as follows but it did not work out:
#Override
public <T> void updateSalaries(HashMap<Integer, player> map) {
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
System.out.println("new map"+map);
}
This is the full code in the main class
import java.util.HashMap;
import player.player.Update;
public class MainProgram implements Update{
public static void main(String[] args) {
HashMap< Integer,player> Keys = new HashMap<>();
player p1 =new player(1);
p1.setName("Ali");
p1.setSalary(5000);
player p2 =new player(2);
p2.setName("Sayed");
p2.setSalary(7000);
player p3 =new player(3);
p3.setName("soha");
p3.setSalary(3000);
Keys.put(1, p1);
Keys.put(2, p2);
Keys.put(3, p3);
// p1.StoreplayerDetails(Keys);
MainProgram m = new MainProgram();
m.updateSalaries(Keys);
}
#Override
public <T> void updateSalaries(HashMap<Integer, player> map) {
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
System.out.println("new map"+map);
}
}
Is there any help in solving this?
In your code snippet you have the following line of code:
map.replaceAll((k,player.getSalary()) -> player.getSalary()+500;
Let's take this apart piece by piece:
map.replaceAll This method lets you replace all the values in a map. I believe you want to manipulate the values that are already there, instead.
(k,player.getSalary()) This is where you name the variables that the lambda will dump values into. You aren't supposed to supply numbers here, you are supposed to be receiving numbers. You likely want (k, p), where k will be set to the key (an Integer) and p will be set to the value (a player).
player.getSalary()+500 This returns an int. The replaceAll method requires that you return the value type, which in this case is player.
You forgot to include a close parenthesis at the end.
I believe you want to use this line of code instead, which mitigates all of the above errors:
map.forEach((k, p) -> p.setSalary(p.getSalary() + 500));

Do I need multiple ArrayLists for this program?

I have to make a program that reads in a file of favorites, such as favorite animals. So say it reads in a file that says "Dog, Cat, Fox", 1 on each line. Those are then put into an Arraylist. After the user is prompted to either add or remove any, they are then asked to rank them. Heres where I'm confused- To reorder/rank the lines of the arraylist, would I need a second ArrayList to put the ranking into? Also, after they are ranked, they are asked to add a comment for each one, such as for cats-"I'm allergic to cats" or something like that. Would I need a 3rd Array list for these comments? Heres a sample output-
‘Favorite’ | Rank | Comments from this round (plus all previous comments)
Heres my code right now if you kind of wanna see where I'm going- it doesnt all work but you'll get the gist of it
Scanner input = new Scanner(System.in);
ArrayList <String> favoriteAnimals = new ArrayList <String>();
boolean repeat = true;
while (repeat) {
System.out.println("Enter the name of the file which contains your favorite animals ");
String fileName = input.nextLine().trim();
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
System.out.println("Here are your favorite animals according to the file:");
while ((line = reader.readLine()) != null) {
System.out.println(line);
favoriteAnimals.add((line));
}
System.out.println("Add more? (y/n)");
if (input.next().startsWith("y")) {
System.out.println("Enter : ");
favoriteAnimals.add(input.next());
} else {
break;
}
for (int i = 0; i < favoriteAnimals.size(); i++) {
System.out.println(favoriteAnimals);
}
System.out.println("Remove an animal?");
if (input.next().startsWith("y")) {
System.out.println("Which animal would you like to remove");
String removeAnimal = input.nextLine();
int index = favoriteAnimal.indexOf(removeAnimal);
favoriteAnimals.remove(index);
System.out.println(favoriteAnimals);
}
else {
break;
}
ArrayList <String> ranking = new ArrayList <String>();
int size = favoriteAnimals.size();
String first = favoriteAnimals.get(0);
System.out.println("What is your ranking of " + first + " out of " + size +"?");
}
catch (IOException ex) {
System.err.println("Your file does not exist!: " + ex.getLocalizedMessage());
repeat = true;
}
}
}
}
In all likelihood, you are supposed to write a small class Animal with fields like String name, String comment, etc. and then have an ArrayList<Animal>.
If you are familiar with Object Oriented OO, Then it is recommended to use classes to encapsulate the data structure you have, I wrote a simple example and I hope it will help you to solve the problem:
Animal class
package com.stackoverflow.q1;
import java.util.ArrayList;
import java.util.List;
public class Animal {
private String name;
private Integer rank;
private List<String> comments=new ArrayList<String>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getRank() {
return rank;
}
public void setRank(Integer rank) {
this.rank = rank;
}
public List<String> getComments() {
return comments;
}
public void setComments(List<String> comments) {
this.comments = comments;
}
#Override
public String toString() {
return "Animal [name=" + name + ", rank=" + rank + ", comments="
+ comments + "]";
}
}
Main class
package com.stackoverflow.q1;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Animal> animals= new ArrayList<Animal>();
Animal dog=new Animal();
dog.setName("dog");
dog.setRank(1);
dog.getComments().add("Comment 1");
Animal horse=new Animal();
horse.setName("horse");
horse.setRank(2);
horse.getComments().add("Comment 1");
Animal cow=new Animal();
cow.setName("cow");
cow.setRank(1);
cow.getComments().add("Comment 1");
animals.add(dog);
animals.add(horse);
animals.add(cow);
for(Animal animal:animals){
System.out.println(animal);
}
}
}

Writing data from a List field to a .txt file in Java

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.

Sorting a list of constructed objects alphabetically using collections.sort

I need to take a collection of objects using the CompareTo() command, and then have these stored in a list, and then use the collections.sort() command to sort them alphabetically by last name, then by first name if the last name isn't strong enough, and then print off the entire list at the end.
This is the code I have so far:
package sortlab;
import java.io.*;
import java.util.*;
public class SortLab {
public static void main(String[] args) throws Exception {
File youSaidUseOurRelativeFileNameForStudentData =
new File("C:/My192/SortLabProj/src/sortlab/student.data");
Scanner sc = new Scanner(youSaidUseOurRelativeFileNameForStudentData);
ArrayList<Student> StudentList = new ArrayList<Student>();
while (sc.hasNextLine()) {
Student testStudent = new Student(sc.next(), sc.next(), sc.next());
sc.nextLine();
StudentList.add(testStudent);
}
}
}
And the next class:
package sortlab;
import java.util.*;
class Student implements Comparable<Student> {
private String first;
private String last;
private String address;
public Student(String f, String l, String a) {
first = f;
last = l;
address = a;
}
#Override
public int compareTo(Student other) {
if (last.hashCode() > other.last.hashCode()) return 1;
if (last.hashCode() < other.last.hashCode()) return -1;
if (first.hashCode() > other.first.hashCode()) return 1;
if (first.hashCode() < other.first.hashCode()) return -1;
return 0;
}
}
If you want to compare them ASCIIbetically use the String.compareTo method. It would never occur to me to compare hashCodes.
If you want to ignore case, you can use String.compareToIgnoreCase
First of all I would add getters for first and last name. Then try this code:
#Override
public int compareTo(Student other) {
int result = l.compareTo(other.getLastName());
if (result == 0) {
return f.compareTo(other.getFirstName());
} else {
return result;
}
}
Then add a toString() method to your Student class:
#Override
public String toString() {
return f+" "+l+", "+a;
}

Sort a List of objects by multiple fields [duplicate]

This question already has answers here:
Using Comparable for multiple dynamic fields of VO in java
(7 answers)
Closed 8 years ago.
I have a List of Java objects that I want to sort according to more than one field.
public class graduationCeremony {
String campus;
String faculty;
String building;
}
Is it possible to use a Comparator or the Comparable interface to sort the list according to multiple fields? All the examples I have seen sort according to only one field. In other words, one can sort by 'campus' OR 'faculty' OR 'building'. I want to sort by 'campus', then 'faculty', then 'building' (as it exists in SQL: ORDER BY campus, faculty, building)
I think this question has been asked before, but I don't understand the accepted answer. Can someone expand or illustrate this answer?
Your Comparator would look like this:
public class GraduationCeremonyComparator implements Comparator<GraduationCeremony> {
public int compare(GraduationCeremony o1, GraduationCeremony o2) {
int value1 = o1.campus.compareTo(o2.campus);
if (value1 == 0) {
int value2 = o1.faculty.compareTo(o2.faculty);
if (value2 == 0) {
return o1.building.compareTo(o2.building);
} else {
return value2;
}
}
return value1;
}
}
Basically it continues comparing each successive attribute of your class whenever the compared attributes so far are equal (== 0).
Yes, you absolutely can do this. For example:
public class PersonComparator implements Comparator<Person>
{
public int compare(Person p1, Person p2)
{
// Assume no nulls, and simple ordinal comparisons
// First by campus - stop if this gives a result.
int campusResult = p1.getCampus().compareTo(p2.getCampus());
if (campusResult != 0)
{
return campusResult;
}
// Next by faculty
int facultyResult = p1.getFaculty().compareTo(p2.getFaculty());
if (facultyResult != 0)
{
return facultyResult;
}
// Finally by building
return p1.getBuilding().compareTo(p2.getBuilding());
}
}
Basically you're saying, "If I can tell which one comes first just by looking at the campus (before they come from different campuses, and the campus is the most important field) then I'll just return that result. Otherwise, I'll continue on to compare faculties. Again, stop if that's enough to tell them apart. Otherwise, (if the campus and faculty are the same for both people) just use the result of comparing them by building."
If you know in advance which fields to use to make the comparison, then other people gave right answers.
What you may be interested in is to sort your collection in case you don't know at compile-time which criteria to apply.
Imagine you have a program dealing with cities:
protected Set<City> cities;
(...)
Field temperatureField = City.class.getDeclaredField("temperature");
Field numberOfInhabitantsField = City.class.getDeclaredField("numberOfInhabitants");
Field rainfallField = City.class.getDeclaredField("rainfall");
program.showCitiesSortBy(temperatureField, numberOfInhabitantsField, rainfallField);
(...)
public void showCitiesSortBy(Field... fields) {
List<City> sortedCities = new ArrayList<City>(cities);
Collections.sort(sortedCities, new City.CityMultiComparator(fields));
for (City city : sortedCities) {
System.out.println(city.toString());
}
}
where you can replace hard-coded field names by field names deduced from a user request in your program.
In this example, City.CityMultiComparator<City> is a static nested class of class City implementing Comparator:
public static class CityMultiComparator implements Comparator<City> {
protected List<Field> fields;
public CityMultiComparator(Field... orderedFields) {
fields = new ArrayList<Field>();
for (Field field : orderedFields) {
fields.add(field);
}
}
#Override
public int compare(City cityA, City cityB) {
Integer score = 0;
Boolean continueComparison = true;
Iterator itFields = fields.iterator();
while (itFields.hasNext() && continueComparison) {
Field field = itFields.next();
Integer currentScore = 0;
if (field.getName().equalsIgnoreCase("temperature")) {
currentScore = cityA.getTemperature().compareTo(cityB.getTemperature());
} else if (field.getName().equalsIgnoreCase("numberOfInhabitants")) {
currentScore = cityA.getNumberOfInhabitants().compareTo(cityB.getNumberOfInhabitants());
} else if (field.getName().equalsIgnoreCase("rainfall")) {
currentScore = cityA.getRainfall().compareTo(cityB.getRainfall());
}
if (currentScore != 0) {
continueComparison = false;
}
score = currentScore;
}
return score;
}
}
You may want to add an extra layer of precision, to specify, for each field, whether sorting should be ascendant or descendant. I guess a solution is to replace Field objects by objects of a class you could call SortedField, containing a Field object, plus another field meaning ascendant or descendant.
Hope this Helps:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
class Person implements Comparable {
String firstName, lastName;
public Person(String f, String l) {
this.firstName = f;
this.lastName = l;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String toString() {
return "[ firstname=" + firstName + ",lastname=" + lastName + "]";
}
public int compareTo(Object obj) {
Person emp = (Person) obj;
int deptComp = firstName.compareTo(emp.getFirstName());
return ((deptComp == 0) ? lastName.compareTo(emp.getLastName()) : deptComp);
}
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person emp = (Person) obj;
return firstName.equals(emp.getFirstName()) && lastName.equals(emp.getLastName());
}
}
class PersonComparator implements Comparator<Person> {
public int compare(Person emp1, Person emp2) {
int nameComp = emp1.getLastName().compareTo(emp2.getLastName());
return ((nameComp == 0) ? emp1.getFirstName().compareTo(emp2.getFirstName()) : nameComp);
}
}
public class Main {
public static void main(String args[]) {
ArrayList<Person> names = new ArrayList<Person>();
names.add(new Person("E", "T"));
names.add(new Person("A", "G"));
names.add(new Person("B", "H"));
names.add(new Person("C", "J"));
Iterator iter1 = names.iterator();
while (iter1.hasNext()) {
System.out.println(iter1.next());
}
Collections.sort(names, new PersonComparator());
Iterator iter2 = names.iterator();
while (iter2.hasNext()) {
System.out.println(iter2.next());
}
}
}
You just need to have your class inherit from Comparable.
then implement the compareTo method the way you like.
You have to write your own compareTo() method that has the Java code needed to perform the comparison.
If we wanted for example to compare two public fields, campus, then faculty, we might do something like:
int compareTo(GraduationCeremony gc)
{
int c = this.campus.compareTo(gc.campus);
if( c != 0 )
{
//sort by campus if we can
return c;
}
else
{
//campus equal, so sort by faculty
return this.faculty.compareTo(gc.faculty);
}
}
This is simplified but hopefully gives you an idea. Consult the Comparable and Comparator docs for more info.

Categories