Getting max value from an arraylist of objects - java

I have an arraylist called cities with objects City from another class, and this object contains both the name of said city but also population. In one method I wanna sum all city populations, aka get the population of the country, however I'm getting an exception in .parseLong method the way I'm doing it. In another one, I wanna check what city has the largest population, but I'm not getting anything when I print and don't know how to fix it. Basically I don't know how to get the value of the objects inside the arraylist. Commented where I have issues for better understanding. Help's appreciated!
public class Country {
private String name;
private City capital;
private int pop;
private ArrayList<City> cities;
public Country(String name, Cidade capital, int pop) {
this.name = name;
this.capital = capital;
this.pop = pop;
cities = new ArrayList<>();
cities.add(capital);
}
public long getTotalPop(){
String c = null;
Iterator<City> iter = cities.iterator();
while(iter.hasNext()){
c += iter.next();
long s = Long.parseLong(c); //giving exception here
System.out.println(s);
return s;
}
return 0;
}
public City getLargest(){
for(City city: cities){
if(city.getPop()>city.getPop()){ //method is fine but if is very wrong since am not sure what to compare to
return city;
}
}
return null;
}
}
public class City {
private String name;
private int pop;
public City(String name) {
this.name = name;
}
public City(String name, int pop) {
this.name = nome;
this.pop = pop;
}
public String getName() {
return name;
}
public int getPop() {
return pop;
}
public void setName(String name) {
this.name = name;
}
public void setPop(int pop) {
this.pop = pop;
}
}

About your Methode getTotalPop()
c should be a long variable and in initialized to 0 because now you are trying to increment a string which is impossible.
you are iterating about a list of cities so iter.next() will give you a city but you want the population of this city so call c += iter.next().getPop();
You don't have to use an iterator. It is okay but you won't get a benefit in this case. My recommendation use a enhanced for/foreach loop.
So use this(iterator):
public long getTotalPop(){
long result = 0;
Iterator<City> iter = cities.iterator();
while(iter.hasNext()){
result += iter.next().getPop();
}
return result;
}
or this(enhanced for/foreach loop):
public long getTotalPop(){
long result = 0;
for (City city : cities) {
result += city.getPop();
}
return result;
}
About your Methode getLargest()
There are some ways to do the job you could use an variable largest pop initialized to 0 and compare each City population with this variable and set it to the pop if it is greater. Or set your pop of the first City as the value to be compared.
With first City:
public City getLargest() {
if (!cities.isEmpty()) {
City largest = cities.get(0);
for (int i = 1; i < cities.size(); i++) {
City city = cities.get(i);
if (largest.getPop() < city.getPop()) {
largest = city;
}
}
return largest;
}
return null;
}
Furthermore because you don't initialize cities in the construtor other than to the new ArrayList don't do that in the constructor but like this:
private List<City> cities = new ArrayList<>();
public Country(String name, City capital, int pop) {
this.name = name;
this.capital = capital;
this.pop = pop;
this.cities.add(capital);
}
At last why is the pop of the country not the same as the pop of all of the cities it has? It would make totaly sense to initialize pop to the result of getTotalPop()

Related

How to display all information in toString

I have two classes: Position and Order. In Position class, fields like: name, price. In Order class field: quantity. My problem is how to display: name, price and quantity together in Order class. I thought about delete arraylist and make another one with position and quantity but I doubt it would help me.
package programming.com.pl;
public class Position {
private String name;
private double price = 0;
public Position(String name, double price){
this.name = name;
this.price = price;
}
public double getPrice() {
return price;
}
public String toString(){
String str = String.format("%4s,%4s", name,price);
return str;
}
}
public class Order {
private int quantity;
final private ArrayList<Position> positions = new ArrayList<Position>();
private int addedPosition;
public Order(int quantity) {
this.quantity = quantity;
}
private double calculateProduct() {
double sum = 0;
for (int i = 0; i < positions.size(); i++) {
sum = positions.get(i).getPrice();
}
return sum;
}
double sumOrder() {
double sum = 0;
for (Position x : positions) {
sum += calculateProduct();
}
return sum;
}
void addPosition(Position p) {
if (!positions.contains(p)) {
positions.add(p);
} else {
quantity++;
}
}
void deletePosition(int index) {
positions.remove(index);
}
public String toString() {
System.out.println("Order is: ");
for (Position p : positions) {
System.out.println(positions.toString());
}
return "Order sum is: " + sumOrder();
}
}
You already are overriding toString method in Position class so you just need to call that toString method on the position object when iterating the position objects from inside your Order class' toString() method.
And as #Federico points out in the comments you shouldn't System.out.println from toString methods. Just append to a string the details you require displaying and return that string.
You can achieve your desired result like so:
public class Position {
.
.
#Override
public String toString() {
return String.format("%4s,%4s\n", name, price);
}
}
public class Order {
.
.
#Override
public String toString() {
StringBuilder sb = new StringBuilder("Order details: \n");
sb.append("Quantity: ").append(quantity).append("\n");
for (Position p : positions) {
sb.append(p);
}
sb.append("Order sum is: ").append(sumOrder());
return sb.toString();
}
}

Constructor with an Array

Tody i have tried to code a program, with administrate virtual Footballplayers. Now i have the problem, that i dont know how to initialize an Array of another Class in the Constructer.
This are my declarations for my "Teams"
Manager managerOfBayern = new Manager("Manager1",55,125);
Manager managerOfBvb = new Manager("Manager2",60,122);
Team fcBayern = new Team(managerOfBayern,playerArrFcB,"FcBayern");
Team bvb = new Team(managerOfBvb,playerArrBvb,"Bvb");
Now i want to initialize my Team.
public class Team {
Manager theManager;
Player[] thePlayer;
String name;
public Team(Manager theManager, Player[] thePlayer, String name) {
this.theManager = theManager;
for (int i = 0; i < thePlayer.length; i++) {
thePlayer[i] = thePlayer[i];
}
this.name = name;
}
But how can i correctly initialize an Array (thePlayer)
i hope you guys can help me with this problem.....
What you are doing is almost correct!
just in the the part of array initialization that is the for loop that you are running in the constructor for copying the array, just replace left hand side of the operator '=' with 'this.thePlayer[i]' and you also need to specify the size of the array beforehand to initialize and use it in the for loop i.e the resultant constructor code should be like this
public Team(Manager theManager, Player[] thePlayer, String name) {
this.theManager = theManager;
this.thePlayer = new Player[thePlayer.length];
for (int i = 0; i < thePlayer.length; i++) {
this.thePlayer[i] = thePlayer[i];
//or this.thePlayer[i] = new Player(thePlayer[i]); in case you want true deep copy, then in Player class you make a constructor of this signature(also known as copy constructor) and copy all the properties of Object passed as an argument
}
this.name = name;
}
I don't have the right solution for your problem but I can think for another way if it's good for you. check it out :
For Player class :
private String name;
private int age;
private int height;
public Player(String name, int Age , int height){
this.name=name;
this.age= Age;
this.height = height;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public int getHeight(){
return this.height;
}
#Override
public String toString(){
return this.name +" , "+ this.age +" , "+ this.height;
}
For Manager class :
private String name;
public Manager(String name){
this.name = name;
}
public String getManager(){
return this.name;
}
For Manager class :
Manager theManager;
Player[] thePlayer;
String name;
public Team(Manager theManager, Player[] thePlayer , String name){
this.theManager = theManager;
this.thePlayer = thePlayer;
this.name = name;
}
#Override
public String toString(){
String list = null ;
for (int i = 0;i<thePlayer.length;i++){
list += thePlayer[i].toString()+"\n";
}
return "Team name : " + this.name + "\n Team manager : " + this.theManager.getManager() + "\n Team players : \n" + list;
}
For team class :
Manager theManager;
Player[] thePlayer;
String name;
public Team(Manager theManager, Player[] thePlayer , String name){
this.theManager = theManager;
this.thePlayer = thePlayer;
this.name = name;
}
#Override
public String toString(){
String list = null ;
for (int i = 0;i<thePlayer.length;i++){
list += thePlayer[i].toString()+"\n";
}
return "Team name : " + this.name + "\n Team manager : " + this.theManager.getManager() + "\n Team players : \n" + list;
}
and finally the test class , so if you noticed you don't really need to put that loop inside the team constructor for player :
For test class(main) :
Manager A = new Manager("Flic");
Player P1 = new Player("Robert Levandowski",32,182);
Player P2 = new Player("David Alaba",32,179);
Player P3 = new Player("Joshoa Kimmich",23,175);
Player[] Aplayers = {P1,P2,P3};
Team B = new Team(A , Aplayers ,"FcBayern");
System.out.println(B.toString());
}
And I'm a barcelona fan by the way hahaha still want the revenge for that 8-2 have a great day !

Filling array with next empty space?

Here are my two classes Country and Countries. I am doing questions from online as extra practice.
I need to:
-Add a method to Countries - addCountry(String name, String capital, int population - Which fills in the element by nextFreeCountry and increments nextFreeCountry
Can somebody provide some help? I am struggling to understand how to fill in the element by nextFreeCountry.
Country:
public class Country {
private String name;
private String capital;
private int population;
Constructor to add the name capital and population
public Country(String name, String capital, int population) {
this.name = name;
this.capital = capital;
this.population = population;
}
Get name method
public String getName() {
return name;
}
public String getCapital() {
return capital;
}
public int getPopulation() {
return population;
}
public String toString() {
return "Name = " + getName() + " Capital = " + getCapital() + " Population = " + getPopulation();
}
}
Countries:
class Countries {
Creating an array of Country called countries
private Country[] countries;
private int nextFreeCountry = 0;
Setting the size for the array
public Countries(int size) {
countries = new Country[size];
}
addCountry method
public void addCountry(String name, String capital, int population) {
countries[nextFreeCountry] =
nextFreeCountry++;
}
}
As countries array hold Country objects, so create a new object and put it in array. Something like this:
public void addCountry(String name, String capital, int population) {
countries[nextFreeCountry] = new Country(name,capital,population);
nextFreeCountry++;
}
You have to add a new country to the array which you are not doing at the moment. Like so:
public void addCountry(String name, String capital, int population) {
countries[nextFreeCountry] = new Country(name, capital, population);
nextFreeCountry++;
}
Alternatively just pass a Country to the method like this:
public void addCountry(Country country) {
countries[nextFreeCountry] = country;
nextFreeCountry++;
}
You may also be better off using an ArrayList rather than an array so you dont have to worry about the array index being out of bounds etc.

how do I compare a input string “BBBB” with the schools in the above ArrayList?

Let say I have an ArrayList<Student> contains 4 Students(name , city, school).
For example:
1. John Nevada BBBB
2. Mary Ander AAAA
3. Winn Arcata CCCC
4. Ty Artes BBBB
If user enter “BBBB” then it displays: :
1. John Nevada BBBB
2. Ty Artes BBBB
My question is that how do I compare a input string “BBBB” with the schools in the above ArrayList?
Thank you for any help that you guys would provide!
public class Student
{
private String name;
private String city;
private String school;
/**
* Constructor for objects of class Student
*/
public Student(String name, String city, String school)
{
this.name = name;
this.city = city;
this.school = school;
}
public String getSchool(String school)
{
return this.school = school;
}
public String toString()
{
return "Name: " + name + "\tCity: " +city+ "\tSchool: "+school;
}
}
public class AllStudent
{
// instance variables - replace the example below with your own
private ArrayList<Student> listStudent = new ArrayList<Student>();
/**
* Constructor for objects of class AllStudent
*/
public AllStudent() throws IOException
{
//variables
// read an input file and save it as an Arraylist
fileScan = new Scanner (new File("students.txt");
while(fileScan.hasNext())
{
//.......
listStudent.add(new Student(name,city,school);
}
//now let user enter a school, the display name, city, school of that student.
//i am expecting something like below...
public void displayStudentBasedOnSchool(String school)
{
for (i = 0; i < listStudent.size(); i++)
{
//what should i put i here to comapre in input School with school in the listStudent>
}
}
}
Assuming your student is modelled like this (AAAA, BBBB values are stored in blah field):
public class Student {
private String name;
private String state;
private String blah;
//getters & setters..
}
The simplest (not most efficient way) is just to loop the array list and compare the query string with value of blah field
for(Student s : studentList) {
if(s.getBlah().equals(queryString)) {
// match!..
}
}
I believe Student is class and you are creating list of Student
The ArrayList uses the equals method implemented in the class (your case Student class) to do the equals comparison.
You can call contains methods of list to get matching object
Like,
public class Student {
private String name;
private String city;
private String school;
....
public Student(String name, String city, String school) {
this.name = name;
this.city = city;
this.school = school;
}
//getters & setters..
public String setSchool(String school) {
this.school = school;
}
public String getSchool() {
return this.school;
}
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof Student)) return false;
Student s = (Student)other;
if (s.getSchool().equals(this.getSchool())) {
return true; // here you compare school name
}
return false;
}
public String toString() {
return "Name: " + this.name + "\tCity: " + this.city + "\tSchool: "+ this.school;
}
}
Your array list would be like this
ArrayList<Student> studentList = new ArrayList<Student>();
Student s1 = new Student(x, y, z);
Student s2 = new Student(a, b, c);
studentList.add(s1);
studentList.add(s2);
Student s3 = new Student(x, y, z); //object to search
if(studentList.contains(s3)) {
System.out.println(s3.toString()); //print object if object exists;
} // check if `studentList` contains `student3` with city `y`.It will internally call your equals method to compare items in list.
Or,
You can simply iterate object in studentList and compare items
for(Student s : studentList) {
if(s.getSchool().equals(schoolToSearch)) {
// print object here!..
}
}
Or, as you commented ,
public void displayStudentBasedOnSchool(String school){
for(int i = 0; i < studentList.size(); ++i) {
if(studentList.get(i).getSchool().equals(school)) {
System.out.println(studentList.get(i).toString()); // here studentList.get(i) returns Student Object.
}
}
}
Or,
ListIterator<Student> listIterator = studentList.listIterator(); //use list Iterator
while(listIterator.hasNext()) {
if(iterator.next().getSchool().equals(school)) {
System.out.println(listIterator.next());
break;
}
}
or even,
int j = 0;
while (studentList.size() > j) {
if(studentList.get(j).getSchool().equals(school)){
System.out.println(studentList.get(j));
break;
}
j++;
}
So now you have set of options
for-loop
for-each loop
while loop
iterator
I would probably use Guava library from Google.
Take a look at this question: What is the best way to filter a Java Collection? It provides many excelent solutions for your problem.

Deleting content and displaying all the content in JAVA

I'm here with my classes, my software is almost done after finishing last two things I will continue to GUI development. Anyway, here is my code:
public class Team
{
private String clubName;
private String preName;
private ArrayList<Branch> branches;
public Team(String clubName, String preName)
{
this.clubName = clubName;
this.preName = preName;
branches = new ArrayList<Branch>();
}
public Team() {
// TODO Auto-generated constructor stub
}
public String getClubName() { return clubName; }
public String getPreName() { return preName; }
public ArrayList<Branch> getBranches() { branches = new ArrayList<Branch>(branches);return branches; }
public void setClubName(String clubName) { this.clubName = clubName; }
public void setPreName(String preName) { this.preName = preName; }
public void setBranches(ArrayList<Branch> branches) { this.branches = new ArrayList<Branch>(branches); }
}
public class Branch
{
public ArrayList<Player> players = new ArrayList<Player>();
String brName;
public Branch() {}
public void setBr(String brName){this.brName = brName;}
public String getBr(){return brName;}
public ArrayList<Player> getPlayers() {players =new ArrayList<Player>(players); return players; }
public void setPlayers(ArrayList<Player> players) { this.players =new ArrayList<Player>(players); }
public String toString() {
return "Branches [" + brName + "]";}
}
public class Player
{
private String name;
private String pos;
private Integer salary;
private Integer number;
public Player(String name, String pos, Integer salary, Integer number)
{
this.name = name;
this.pos = pos;
this.salary = salary;
this.number = number;
}
public Player(){}
public String getName() { return name; }
public String getPos() { return pos; }
public Integer getSalary() { return salary; }
public Integer getNumber() { return number; }
public void setName(String name) { this.name = name; }
public void setPos(String pos) { this.pos = pos; }
public void setSalary(Integer salary) { this.salary = salary; }
public void setNumber(Integer number) { this.number = number; }
public String toString() {
return "Player [name=" + name + ", number=" + number + ", pos=" + pos
+ ", salary=" + salary + "]";
}
}
//TEST
String p1,p2;
int a1,a2;
String t, br;
System.out.print("Enter player name : ");
p1 = input.readLine();
System.out.print("Enter player position : ");
p2 = input.readLine();
System.out.print("Enter player salary : ");
a1 = Integer.parseInt(input.readLine());
System.out.print("Enter player number : ");
a2 = Integer.parseInt(input.readLine());
players[pCount].setName(p1);
players[pCount].setPos(p2);
players[pCount].setSalary(a1);
players[pCount].setNumber(a2);
ptmp.add(players[pCount]);
pCount++;
System.out.print("Enter the branch of player : ");
br = input.readLine();
int fff=0;
for(int i = 0; i<brCount;i++)
{
if(br.equals(myBranch[i].brName)==true){
myBranch[i].setPlayers(ptmp);fff=i;}
}
MY FIRST QUESTION : I'm trying to add a player to my system. When a player added I can easily add it to Branch class too and connect them. But I can't do it for Players' club. I mean I want to display which player plays in which club. But I can't do it.
MY SECOND QUESTION : Deleting a player is problem too. When I delete player it should be deleted everywhere. But couldn't figured that out.
In the test, you can see the display function I tried. It works fine for Branch-Player. And I wanna add Team connection too. Team-Branch-Player should be connected.
Q1: It depends how efficiently you want to do your searches.. for now, since you don't store back references you have to first search in which branch is your player and then search which is the club that contains your branch.
With good equals method for your Branch and Player class this is trivial:
for (Team t : teamList)
{
if (t.branches.contains(player))
return true;
}
return false;
But this won't be efficient since you'll have a O(n*m) complexity where n is the team size and m is the average branch size.
If you want something more efficient I'd suggest you to store backreferences inside your classes, you can have your Player class with two attributes
Branch currentBranch
Team currentTeam
and you can set them while you add the player to a branch/team.
Otherwise you can keep a separate HashMap that maps every player to his branch/team. Less memory efficient but quite straightforward.
Q2: to remove the Player from his branch/team you just have to know in which one he stays.. (using the answer to Q1), then before removing from players you just remove it from the corresponding branch/team:
Branch b = findWhichBranch(player);
Team t = findWhichTeam(player);
b.remove(player);
t.remove(player);
players[index] = null;
Of course if branch is implied by team you will just remove it from the branch, since there's no direct association between a player and a team.

Categories