I've implemented the interface comparable and the method compareTo(). I have a list named randomHumans that contains 10 objects. 5 objects with three fields: name, age and year they started studying, and 5 objects with two fields: name and age. I would like to sort my list, and tried using:
Collections.sort(randomHumans);
This gave me the following error message:
The method sort(List<T>) in the type Collections is not applicable for the arguments (ArrayList<Object>)
I then tried this code:
Collections.sort((List<T>) randomObjects);
But it just gives me two new error messages. Maybe I need to specify what field it should sort after, but I can't find how to implement this. Any help would be greatly appreciated.
main method:
public static void main (String[] args) {
ArrayList<Object> randomObjects = new ArrayList<Object>();
for (int j=0; j<5; j++) {
Fysiker randomFysiker = new Fysiker();
randomObjects.add(randomFysiker);
Human randomHuman = new Human();
randomObjects.add(randomHuman);
}
System.out.println(randomObjects.toString());
//Collections.sort(randomObjects);
}
Human class:
class Human implements Comparable<Human> {
int age;
String name;
public Human (int myAge, String myName) {
name = myName;
age = myAge;
}
public Human() {
this(randomAge(),randomName());
}
public int compareTo(Human o) {
return this.age - o.age;
}
protected static int randomAge() {
Random randomGenerator = new Random();
return randomGenerator.nextInt(100);
}
protected static String randomName() {
Random randomGenerator = new Random();
return "Name"+randomGenerator.nextInt(15);
}
public int getAge(){
return age;
}
public String getName() {
return name;
}
public String toString() {
return "\nName: " + name + "\nAge: " + age + " yrs old\n";
}
}
Fysiker class:
public class Fysiker extends Human {
int year;
public Fysiker(int myAge2, String myName2, int myYear) {
name = myName2;
year = myYear+1932;
if (myAge2 >= 15+(2017-myYear)) {
age = myAge2;
} else {
age = 15+(2017-year);
}
}
public Fysiker() {
this(randomAge(),randomName(), randomYear());
}
protected static int randomYear() {
Random randomGenerator = new Random();
return randomGenerator.nextInt(83);
}
public int getYear(){
return year;
}
public String toString() {
return "\nName: " + name + "\nAge: " + age + " yrs old" + "\nStarted Physics: " + year+"\n";
}
}
Just change the generic parameter from Object to Human
public static void main (String[] args) {
List<Human> randomObjects = new ArrayList<>();
for (int j = 0; j < 5; j++) {
Fysiker randomFysiker = new Fysiker();
randomObjects.add(randomFysiker);
Human randomHuman = new Human();
randomObjects.add(randomHuman);
}
System.out.println(randomObjects);
Collections.sort(randomObjects);
}
When you write Collections.sort(randomHumans); randomHumans must be a List of Comparable. If you are 'forced' to use a List of Object, you must give a Comparator to explain how to compare each object :
Collections.sort(randomHumans, humanComparator);
It's all explained in the offcial documentation :
sort(java.util.List)
sort(java.util.List, java.util.Comparator)
Related
I am trying to make a new method that tells the user what the country with the highest point out of my array is. What I have currently done is inputted 2 country names followed by their highest point name and the number of the highest point, but now I am trying to output the one country that has the indefinite highest point, in my case from what i've added, its Argentina with Aconcagua as its highest point as 6960.
Code:
Main file:
public class continentTest
{
public static void main(String[] args) {
Continent southAmerica = new Continent();
Country southAmericanRepublic = new Country("Argentina", new HighestPoint("Aconcagua", 6960));
southAmerica.addCountry(southAmericanRepublic);
Country anotherSouthAmericanRepublic = new Country("Columbia", new HighestPoint("Pico Cristóbal Colón",5730));
southAmerica.addCountry(anotherSouthAmericanRepublic);
System.out.println (southAmerica.toString());
}
}
Other files:
class Country {
String name;
HighestPoint hp;
public Country (String nm, HighestPoint pt) {
name = nm;
hp = pt;
}
public String toString () {
return name + ": " + hp.toString() + "\n";
}
}
class HighestPoint {
String name;
int height;
public HighestPoint (String nm, int ht) {
name = nm;
height = ht;
}
public String toString () {
return name + " " + String.valueOf (height);
}
}
import java.util.*;
class Continent {
ArrayList<Country> countries;
public Continent () {
countries = new ArrayList<Country>();
}
public void addCountry (Country c) {
countries.add (c);
}
public String toString () {
String s = "";
for (Country c : countries)
s += c.toString();
return s;
}
}
I am not quite sure how to take the largest value from an array and display it along with the country name. Any help would be appreciated, thanks!
The following method in the continent class may help:
public Country getHighestPoint() {
int highest = 0;
Country temp;
for(int index = 0; index < countries.size(); index++) {
if(countries.get(index).hp.height > highest) {
highest = countries.get(index).hp.height
temp = countries.get(index)
}
}
return temp;
}
This exercise is a good opportunity to learn about the Comparable and Comparator
Starting with Comparable, you should apply this to your HighestPoint
class HighestPoint implements Comparable<HighestPoint> {
String name;
int height;
public HighestPoint (String nm, int ht) {
name = nm;
height = ht;
}
public String toString () {
return name + " " + String.valueOf (height);
}
public int compareTo(HighestPoint hp) {
return height - hp.height;
}
}
Now that's done, you can compare two HighestPoints and determine which is bigger.
Next: Comparator. We can use this with Continent, as you have a Collection (ArrayList) of all the Countries in a Content.
class Continent {
//... keep what is already in Continent
Comparator countryComparator = new Comparator<Country> () {
public int compare(Country a, Country b) {
return a.highestPoint.compareTo(b.highestPoint);
}
}
}
Now we can compare Countries and sort the array list by their HighestPoint
The reason it makes sense to use Comparable with HighestPoint and Comparator with your Countries array is that HighestPoint is a class defined with two data points: A name and a height. Whereas a Country could have many data points, and you could have many Comparators to sort Countries based on different criteria
You can solve it with Collections.
Country countryWithHighestPoint = Collections.max(southAmerica.countries, Comparator.comparing(s -> s.hp.height));
continentTest
import java.util.Collections;
import java.util.Comparator;
public class continentTest {
public static void main(String[] args) {
Continent southAmerica = new Continent();
Country southAmericanRepublic = new Country("Argentina", new HighestPoint("Aconcagua", 6960));
southAmerica.addCountry(southAmericanRepublic);
Country anotherSouthAmericanRepublic = new Country("Columbia", new HighestPoint("Pico Cristóbal Colón", 5730));
southAmerica.addCountry(anotherSouthAmericanRepublic);
Country countryWithHighestPoint = Collections.max(southAmerica.countries, Comparator.comparing(s -> s.getHighestPoint().getHeight()));
System.out.println(countryWithHighestPoint.toString());
System.out.println(southAmerica.toString());
}
}
Country
class Country {
private String name;
private HighestPoint hp;
public Country (String nm, HighestPoint pt) {
name = nm;
hp = pt;
}
public String toString () {
return name + ": " + hp.toString() + "\n";
}
public HighestPoint getHighestPoint()
{
return hp;
}
}
HighestPoint
class HighestPoint {
private String name;
private int height;
public HighestPoint (String nm, int ht) {
name = nm;
height = ht;
}
public String toString () {
return name + " " + String.valueOf (height);
}
public int getHeight()
{
return height;
}
}
I'm writing a simple code to show various details about a person. I've used arrays to create name.
When I try to run my code the location/ directory for name comes out as [Ljava.lang.String;#1f32e575.
My code runs results are:
Name
ii
jj
[Ljava.lang.String;#1f32e575 // code to remove
My code:
public static String[] name() {
System.out.println("Name");
n = new String[]{ "ii", "jj" };
for (int i = 0; i < n2.length; i++) {
System.out.println(n[i]);
}
}
Here, is your fixed code:
import java.util.ArrayList;
class Detail {
private String name;
private String nationality;
private static String[] hobby2;
public Detail() {
}
public String getName() {
return name = "A";
}
public String getNationality() {
return nationality = "abc";
}
public void setInfo(String name, String nationality) {
this.name = name;
this.nationality = nationality;
}
public static void setHobbies() {
hobby2 = new String[] { "ii", "jj" };
System.out.println("Hobbies");
for (int i = 0; i < hobby2.length; i++) {
System.out.println("\t" + hobby2[i]);
}
}
public static void setWishes() {
System.out.println("Wishes");
ArrayList<String> allWishes = new ArrayList<String>();
allWishes.add("aa");
allWishes.add("bb");
allWishes.add("cc");
allWishes.add("dd");
for (String i : allWishes) {
System.out.println("\t" + i);
}
}
public void displayDetail() {
DOB d = new DOB();
System.out.println("Name: " + getName());
System.out.println("Nationality: " + getNationality());
System.out.println("Date of birth: " + d.dateString(1, "Jan", 1000));
setHobbies();
setWishes();
}
}
class DOB {
public String dateString(int day, String month, int year) {
String dob = (day + " " + month + ", " + year);
return (dob);
}
}
class Test {
public static void main(String[] args) {
MyInfo my = new MyInfo();
my.displayDetail();
}
}
The very first value you don't want was the object ID, you simply can't return the values of an object. If you want to see the values then you have to override the toString() method.
The second value was visible just because you returned the list. If you were using print() inside your method then there was no need to return it.
Tips: You need to get a better understanding of getter and setter methods because you have messed up the entire concept in your code. Your blank constructor is not needed. Rather, you should initialize all the fields (class variables of Detail class) in the constructor.
Remove System.out.println in displayDetail() method as below,
setHobbies();
setWishes();
import java.util.ArrayList;
class BryanList{
public static void main (String [] args)
{
ArrayList<String> alist=new ArrayList<String>();
alist.add("Bryan");
alist.add("18");
alist.add("Chicken Rice");
for (int i = 0; i <= alist.size(); i++) {
System.out.println ("My Name: "+alist.get(i));
System.out.println ("Age: "+alist.get(i));
System.out.println ("Favourite food: "+alist.get(i));
}
}
}
How come its not just displaying just one output instead there's 3 of the same output? Does anyone have any solution for this? Thanks.
If you want one time output then use generics class structure.
Create one class which you want to save records.
class Menu {
public int age;
public String name;
public String favFood;
}
You can create getter/setter method if you need. Otherwise just declare variables with public keyword.
Create one ArrayList which will store object of Menu class.
ArrayList<Menu> alist = new ArrayList<Menu>();
Menu menu = new Menu();
menu.name = "Bryan";
menu.age = 18;
menu.favFood = "Chicken Rice";
alist.add(menu);
Print output
for (int i = 0; i <= alist.size(); i++) {
Menu menu = alist.get(i);
System.out.println("My Name: " + menu.name);
System.out.println("Age: " + menu.age);
System.out.println("Favourite food: " + menu.favFood);
}
I updated your class with your requirement, please check.
class BryanList {
public static void main(String[] args) {
ArrayList<Menu> alist = new ArrayList<Menu>();
Menu menu = new Menu();
menu.name = "Bryan";
menu.age = 18;
menu.favFood = "Chicken Rice";
alist.add(menu);
for (int i = 0; i <= alist.size(); i++) {
Menu menu = alist.get(i);
System.out.println("My Name: " + menu.name);
System.out.println("Age: " + menu.age);
System.out.println("Favourite food: " + menu.favFood);
}
}
}
class Menu {
public int age;
public String name;
public String favFood;
}
Happy coding :)
Your loop check is happening on alist.size() which is in your case 3.
Now, in each iteration, it's printing alist.get(i) 3 times.
Suggestion:
Use POJO and add it to your list.
public class Person{
String name;
int age;
String favFood;
public getName(){
return name;
}
public getAge(){
return age;
}
public getFavFood(){
return favFood;
}
public setName(String name){
this.name = name;
}
public setName(int age){
this.age = age;
}
public setName(String favFood){
this.favFood = favFood;
}
}
And now, your code will work with simple modification.
public static void main (String [] args){
ArrayList<String> alist=new ArrayList<String>();
Person person = new Person();
person.setName("Bryan");
person.setAge(18);
person.setFavFood("Chicken Rice");
// If you want multiple person to add, you need to use loops, and that way you can keep creating person objects and add them to list.
// Suggesting, use separate method for that logic.
alist.add(person);
for (int i = 0; i <= alist.size(); i++) {
Person p = alist.get(i);
System.out.println ("My Name: "+ p.getName());
System.out.println ("Age: "+ p.getAge());
System.out.println ("Favourite food: "+ p.getFavFood());
}
}
Because your printing codes in a For loop. And loop is running 3 three times
alist.size()
means 3, you have 3 item in that list.
This can be your object class:
public class Table {
int age;
String name;
String food;
public Table(int age, String name, String food) {
this.age = age;
this.name = name;
this.food = food;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFood() {
return food;
}
public void setFood(String food) {
this.food = food;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And fill arraylist with your object:
public static void main(String[] args) {
ArrayList<Table> alist = new ArrayList<>();
// this is how you fill
alist.add(new Table(18, "Bryan", "Rice");
for (int i = 0; i <= alist.size(); i++) {
System.out.println("AGE: " + alist.get(i).age);
//other stuff
}
}
import java.util.ArrayList;
public class HelloWorld {
public static void main(String []args) {
ArrayList<String> alist_name=new ArrayList<String>();
ArrayList<String> alist_value=new ArrayList<String>();
alist_name.add("My Name: ");
alist_name.add("Age: ");
alist_name.add("Favourite food: ");
alist_value.add("Bryan");
alist_value.add("18");
alist_value.add("Chicken Rice");
for (int i = 0; i < alist_name.size(); i++) {
System.out.println (alist_name.get(i)+alist_value.get(i));
}
}
}
here is my code. i keep getting a nullpointerexception in my sort and print method, it starts on the line with the for loop with allAnimals.length. I think the array allAnimal in the class, isnt filled in getData as it should. allAnimal in getData method isnt being treated as allAnimal in the class. Basically all other methods still think allAnimal is null. I am no master in java so if someone could please tell me how to fix this error, or give me tips on how to avoid it I would greatly appreciate it.
public class Animal {
//data fields
private String name;
private int birthYear;
private String species;
private float balance;
private String ownersName;
static Animal[] allAnimal;
public Animal(){
//no-arg constructor
}
public Animal(String name, int birthYear, String species, float balance, String ownersName){
// constructor builds animal template
this.name = name;
this.birthYear = birthYear;
this.species = species;
this.balance = balance;
this.ownersName = ownersName;
}
//set and get for name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//set and get for birth year
public int getBirthYear() {
return birthYear;
}
public void setBirthYear(int birthYear) {
this.birthYear = birthYear;
}
//set and get for species
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
//set and get for balance
public float getBalance() {
return balance;
}
public void setBalance(float balance) {
this.balance = balance;
}
//set and get for owner
public String getOwnersName() {
return ownersName;
}
public void setOwnersName(String ownersName) {
this.ownersName = ownersName;
}
public static void getData(){
System.out.println("How many animals are in this report? ");
Scanner kb = new Scanner(System.in);
int length = kb.nextInt();
Animal[] allAnimal = new Animal[length];
System.out.println("input: animal name, birth year, species, bill balance and owner's name.");
//fill array of objects with data
int i;
for(i = 0; i < allAnimal.length; i++){
allAnimal[i] = new Animal(kb.next(), kb.nextInt(), kb.next(), kb.nextFloat(), kb.next());
}
}//end getData
public static void sortData(Animal[] allAnimal){
Animal temp;
int i,j;
for(i = 0; i < allAnimal.length; i++){
for(j = i + 1; j < allAnimal.length; j++){
if(allAnimal[i].getBalance() > allAnimal[j].getBalance() ){ //swap big with small
temp = allAnimal[j];
allAnimal[j] = allAnimal[i];
allAnimal[i] = temp;
}
}
}
}//end sortData
public static void printData(Animal[] allAnimal){
int i;
for(i = 0; i < allAnimal.length; i++){
System.out.println("Pet Name: " + allAnimal[i].getName() + " Birth year: " +
allAnimal[i].getBirthYear() + " Species: " + allAnimal[i].getSpecies() +
" Balance due: " + allAnimal[i].getBalance() + " Owner: " + allAnimal[i].getOwnersName());
}
}
public static void main(String[] args){
getData();
sortData(allAnimal);
printData(allAnimal);
}//end main
}//end class
You have two variables named allAnimal:
static Animal[] allAnimal;
Animal[] allAnimal = new Animal[length];
You initialize one and then use the other (which is still null).
In getData(), change
Animal[] allAnimal = new Animal[length];
to
allAnimal = new Animal[length];
There could be other problems, I didn't look too closely.
You are creating local variable Animal[] allAnimal within getData() method that caused the problem.
Problem here
public static void getData(){
Animal[] allAnimal = new Animal[length]; //here is the problem
}
fix it like below.
public static void getData(){
allAnimal = new Animal[length]; //here is the fix
}
You have only declared AllAnimal at the class level :
static Animal[] allAnimal;
Now, in your method getData() you have declared and initialized a local variable allAnimal. Note that it has nothing to do with the one at class level.
Animal[] allAnimal = new Animal[length];
In other methods you are trying to use class level allAnimal which will throw a null pointer inless it is initiatlized.
for(i = 0; i < allAnimal.length; i++){
I have to order Appointments by date and time. I have an ArrayList of Appointments and have tried to create a comparator to compare their dates and times. I am trying to use the Collections.sort method, passing it the ArrayList of Appointments and the AppointmentComparator I have created. When compiling I get a "No suitable method for sort." Here's a link to the full error message generated by the compiler : http://prntscr.com/7y4qb
Comparator:
public class AppointmentComparator implements Comparator<Appointment>
{
public int compare(Appointment a, Appointment b)
{
if (a.getDay() < b.getDay())
return -1;
if (a.getDay() == b.getDay())
{
if (a.getStart() < b.getStart())
return -1;
if (a.getStart() > b.getStart())
return 1;
return 0;
}
return 1;
}
Line with syntax error:
Collections.sort(book, new AppointmentComparator());
variable book is an ArrayList of Appointments. ArrayList<Appointment>
AppointmentBook class:
import java.util.ArrayList;
import java.util.Collections;
public class AppointmentBook
{
private ArrayList<Appointment> book;
public AppointmentBook()
{
book = new ArrayList<Appointment>();
}
public void addAppointment(Appointment appt)
{
book.add(appt);
Collections.sort(book, new AppointmentComparator());
}
public String printAppointments(int day)
{
String list = "";
for (int i = 0; i < book.size(); i++)
{
if (book.get(i).getDay() == day)
{
list = list + "Appointment description: " + book.get(i).getDescription() + "\n" + "Date of Appointment: " +
book.get(i).getDay() + "\n" + "Time: " + book.get(i).getStart() + " - " + book.get(i).getEnd() + "\n" + "\n";
}
}
return list;
}
Appointment class:
public class Appointment
{
private String desc;
private int day; //in format mmddyyyy
private int start; //in format hhmm
private int end; //in format hhmm
public Appointment(String description, int aptDay, int startTime, int endTime)
{
desc = description;
day = aptDay;
start = startTime;
end = endTime;
}
public String getDescription()
{
return desc;
}
public int getDay()
{
return day;
}
public int getStart()
{
return start;
}
public int getEnd()
{
return end;
}
}
From the error message it looks like you forgot to declare your comparator as implementing the interface:
public class AppointmentComparator implements Comparator<Appointment> {}
It needs to have the implements part, not just contain the method.
You need to cast your new AppointmentComparator
Collections.sort(book, new (Comparator)AppointmentComparator());
Also we can use inner class for some cases:
public int indexOfLargest(ArrayList<QuakeEntry> Data) {
Comparator<QuakeEntry> cmtr = new Comparator<QuakeEntry>() {
#Override
public int compare(QuakeEntry t, QuakeEntry t1) {
if (t.getMagnitude() < t1.getMagnitude())
return -1;
if (t.getMagnitude() == t1.getMagnitude())
return 1;
if (t1.getMagnitude() > t1.getMagnitude())
return 0;
return 1;
}
};
QuakeEntry max = Collections.max(Data, cmtr);
int maxIndex = Data.indexOf(max);
//----------------------------------------------------------------------
System.out.println("//---------------------------------------------------");
System.out.println("ArrayList sorted by Magnitude using inner class with Comparator");
System.out.println("//---------------------------------------------------");
Collections.sort(Data, cmtr);
for (QuakeEntry qe : Data) {
System.out.println(qe);
}
return maxIndex;
}
code for all classes:
https://github.com/Evegen55/Java_DukeEdu_Coursera_2/blob/master/Earthquakes_Programming%20and%20Interfaces/src/earthquakes_programming_and_interfaces/QuakeEntry.java
Seems you have not implemented The comparator interface for your AppointmentComparator