I have a question regarding the for-loop and ArrayList. I have a HashMap with String and Integers, where the String represents a class, and the Integer represents the grade. They I have a collection of students in an ArrayList. So what I am trying to do is find the average of the grades of the students in the ArrayList. This is the code of that class:
import java.util.ArrayList;
public class BachelorStudenter {
private ArrayList<BachelorStudent> bs;
public Bachelorstudenter() {
bs = new ArrayList<>();
}
public int bsGjennomsnitt() {
int sum = 0;
int gjennomsnitt = 0;
if(!bs.isEmpty()){
for(BachelorStudent b : bs.values){
sum += b.finnGjennomsnitt();
}
return gjennomsnitt;
}else {
return 6;
}
}
}
I know that the bs.values in the for-loop within the if-statement is wrong, but I've tried googling what I should use instead, and neither .contains or .size works.
Oh, and I also have another class called BachelorStudent, where I can create an object of the BachelorStudent and it will be put in the ArrayList in Bachelorstudenter.
Does anyone know what I need to put there instead?
If what you want to to is to return the average of the average grade over all the students you could do the following:
import java.util.ArrayList;
public class Bachelorstudenter {
private ArrayList<Bachelorstudent> bs;
public Bachelorstudenter() {
bs = new ArrayList<>();
}
public double bsGjennomsnitt() {
double sum = 0.0;
double gjennomsnitt = 6.0;
if(!bs.isEmpty()){
for(Bachelorstudent b : bs){
sum += b.finnGjennomsnitt();
}
gjennomsnitt = sum/bs.size()
}
return gjennomsnitt;
}
}
please note that I changed the return value, sum and gjennomsnitt to double as an average may also be a non-integer value.
The answer also assumes that the b.finnGjennomsnitt() returns the average over all classes a student attends and returns this. If you only want to return the average for all students in ONE class the answer will not give you this. Please specify in your question and also include the code for finnGjennomsnitt() if this is part of the question.
The method in the answer will return 6.0 as average if there are no students, as in the code in the question. Perhaps this should be reconsidered as it makes the case of an exceptional group of students with straight 6.0 grades equal to the case of no students. Perhaps you can return -1 when there are no students?
What you a doing is recursively ending in an exception....
You have to do::
for(Bachelorstudent b : bs){
sum += b.getSomething();
}
and define getSomething as a getter for a field in the classs Bachelorstudent
Related
I have two classes: Student and University.
public class University {
private String name;
private List<Student> students;
public University(String name) {
this.name = name;
this.students = new ArrayList<Student>();
}
and there is a function to calculate the average score:
public double average() {
double average = 0;
for(Student st: students) {
average += st.getKnowledge();
}
try {
return average/students.size();
}
catch(ArithmeticException e) {
System.out.println("Oops, there is no student studying");
return 0.0;
}
}
So if there is no students in the list, i get division by zero which i tried to handle with a try\catch block.
And I wonder if there is any way to simplify this checking in order to avoid the try catch block? Of course, I could implement it like this:
public double average() {
double average = 0;
for(Student st: students) {
average += st.getKnowledge();
}
if (students.size() == 0)
throw new IllegalArgumentException("Oops, there is no student studying");
return average/students.size();
}
either
if (students.size() == 0)
System.out.println(""Oops, there is no student studying"");
Or probably there is no point in checking it because if students list is empty then it simply wont enter the loop?
I know the question is easy but I am only styudying so I'd like to know in the future which way is better to pick.
And also perhaps there is a hidden problem or something? with boundaris values or whatever?
thanks in advance.
That's why if statements are there. Don't restrain yourselves from using them :) And the best would be to check in the beginning of the method. Something like:
public double average() {
if(students.isEmpty())
return 0.0;
double average = 0;
for(Student st: students) {
average += st.getKnowledge();
}
return average/students.size();
}
And if you want a fancier way to do it with streams you can do:
private double average(List<Student> students) {
return students.stream()
.mapToDouble(Student::getKnowledge)
.average()
.orElse(0.0);
}
Another solution is to use summary statistics. https://docs.oracle.com/javase/8/docs/api/java/util/DoubleSummaryStatistics.html
Additionally to average, it contains information about min, max, total values, their sum.
It is widely used, if you need several summary values, but you don't want to make several streams of your collection:
public static double average() {
return students.stream()
.mapToDouble(Student::getKnowledge)
.summaryStatistics()
.getAverage();
}
It will return 0.0 by default, if your collection is empty.
It is faster if you need several summary values, but slower if you need only one.
The assignment for my class asks me to create a program that tells a supermarket which customer, on a daily basis, has spent the most money in the store. The program must find this customer and display their name.
Goals of assignment - To work with multiple classes, work with ArrayLists and apply the knowledge gained.
My question:
How should I loop my two output statements in my main class? Is that right in my main method? I need it to loop until the sentinel is used.
How is this going to affect my sentinel?
What type of questions should I be asking myself when dealing with loops? I'd like to think I'm overthinking this portion.
I really want to understand what I am doing here, so any help in the right direction would be appreciated! Thanks, in advance, for taking the time to help me out!
import java.util.Scanner;
public class main {
public static void main(String[] args) {
System.out.println("* * * * * THE SUPERMARKET * * * * *");
System.out.println(" Written by Nate Irwin");
System.out.println();
double finalTotal = -1;
String anAccountName;
Scanner input = new Scanner(System.in);
Store store = new Store();
do {
System.out.println("Enter the customer name: ");
if(input.hasNextLine()){
anAccountName = input.nextLine();
System.out.println("Enter customer total price, hit 0 to QUIT: ");
finalTotal = input.nextDouble();
store.addAccount(anAccountName, finalTotal);
System.out.println();
}
} while (finalTotal != 0);
System.out.println(store.getHighestCustomerTotal() + " has spent the most with us today!");
}
}
Store class:
import java.util.ArrayList;
public class Store {
// Creates an ArrayList.
private ArrayList<CustomerAccount> accounts = new ArrayList<CustomerAccount>();
//
public void addAccount(String anAccountName, double finalTotal) {
accounts.add(new CustomerAccount(anAccountName, finalTotal));
}
// Gets the HIGHEST customer total.
public String getHighestCustomerTotal() {
CustomerAccount highest = accounts.get(0);
for (int i = 1; i < accounts.size(); i++) {
if (accounts.get(i).getTotal() > highest.getTotal())
{
highest = accounts.get(i);
}
}
return highest.getAccountName();
}
}
CustomerAccount class:
public class CustomerAccount {
// Variables defined to this class.
private String accountName;
private double total;
// Constructor.
public CustomerAccount(String anAccountName, double finalTotal) {
accountName = anAccountName;
total = finalTotal;
}
// Gets total from each customer.
public double getTotal() {
return total;
}
// Gets a customer's name.
public String getAccountName() {
return accountName;
}
}
I think your approach is fine, it gets the job done.
I'm not too sure what you're asking by saying how should you loop the two output statements, followed by if it should be in the main method. From what I understand, and by looking at your code, running this input loop is perfectly fine from the main class. The do-while is fine although I'd move the first 'introductory' output outside the loop so you don't see it every time the loop reiterates.
Also, I notice you're not actually calling/instantiating the Store class in your main method, there's no data being added to the Store class for when it iterates through the accounts ArrayList.
As far as the answer that stated a more "modern" approach, I think the for loop you used is fine. I think the person was referring to the for-each loop. It doesn't really matter how you loop through it with the little amount of data you have.
There's some error in the logic for that loop. The getHighestCustomerTotal() is referencing an empty accounts ArrayList. You declared an ArrayList within the Store class and tried to loop through it but it's empty unless you called the addAccount() method from your main method at some point, so you'd need some error checking on that.
Your loop in main:
Doesn't really use the data you type in... One would expect this data to be used to create CustomerAccount instances
Has a completely unnecessary while(Condition) test at the end. This kind of loop is normally done with a While True and some test in the loop breaks out of the loop.
In getHighestCustomerTotal()
you can use a more "modern" form of the for() where you iterate elements of the list directly instead of iterating the index.
Okay I have tried to write a simple Java code in BlueJ, that finds and prints the product of all the entries in data such as if data is {1,2,3,4} then the result will be 24.
And my code is below:
public class Product {
public static int[] product(int[] a) {
int [] s = new int[a.length];
for (int i =0; i< a.length; i++)
s[i] = a[i]*a[i];
return s; //the definition of your method...
}
public static void main(String[] args) {
//calling the method to seek if compiles
int[] results = Product.product(new int[] { 1,2,3,4 });
//printing the results
System.out.println(java.util.Arrays.toString(results));
}
}
The above code is giving me the square of each number, which is not what I want to have, somehow I have modify the code that the result will be 24 but I couldn't figure it out, anyone knows how to do it?
First of all, if you are first writing Java it is important to know that variable, function and class names are quite important. Please note that having Product.product() is not a good idea, since the function name is almost the same as the class name. Anyway, regarding your code. Your code is indeed returning the square of your input, what you would want is the following:
public class Product {
public static int getProduct(int[] input) {
int total = 1;
for (int v : input) {
total *= v;
}
return total;
}
}
This will return an integer value with the product of your input array. This also uses a for-each loop instead of a regular for-loop for readability. Also you don't need the index in this case. Good luck with it!
First, your product method needs to return an int rather than an int [].
You need to maintain the product as a variable. You can set it to 1 initially, and then multiply it by each element of the a array in turn; then you just return this value.
I'm having a difficult time figuring how to display the shared personArray with the appropriate course object. For example, I need to display a list of a course and the people that are in that course, and again for the next course. I feel that there's something wrong with my nested for loop or the personCount variable because not every course has the same amount of people so how do I deal with this?
Hopefully you all can get a clear picture of the stripped down code below.
Note* I must use aggregation and toStrings, and not allowed to use lists, arraylists, or scanner.
Thanks!
public class School {
private static Course[] courseArray = new Course[5];
public static void printList(){
String print = "";
for (int x = 0; x < courseCount; x++) {
print += courseArray[x].getCourseName() + "\n";
for (int y = 0; y < personCount; y++){
print += courseArray[y].personArray[y].getPersonName()+ "\n";
//^ I thought I could use the 1st forloop index to stay in the 1 course and print out all the people for that course(like the hardcode example below) but I get a nullpointer
}
}
JOptionPane.showMessageDialog(null,print);
/*
If I hardcode the print String like below I get the correct output.
So I know my objects are being stored properly, but I can't figure out how to get the correct display with a loop
print += courseArray[0].personArray[0].getPersonName(); //tim (bio)
print += courseArray[0].peopleArray[1].getPersonName(); //bob (bio)
print += courseArray[1].peopleArray[2].getPersonName(); //john (art)
*/
}
}
------------------------
public class Course {
private Person[] personArray = new Person[50];
//constructor for course
// get/set courseName methods
public String toString(){
// not sure how to use this the right way
}
}
-----------------------------------
public class Person extends Course {
//constructor for person
// get/set personName methods
public String toString(){
return getPersonName();
}
}
Make sure that all 50 of the people in your personArray are initialized first; check to see if they are by printing out the entire array like so (you will need to import java.util.Arrays):
System.out.println(Arrays.toString(course[x].personArray));
If that gives back any "null" values then you know that not every single Person in the PersonArray was initialized first.
You should change courseCount to courseArray.length and personCount to courseArray.getPersonArraySize() and implement getPersonArraySize() in Course class to return length of personArray.
replace your loops with these below..
for (Course c : courseArray) {
print += c.getCourseName() + "\n";
for (Person p : c.personArray){
print += p.getPersonName()+ "\n";
}
}
Beforehand: This is a homework assignment so I need answers with explanations.
I am a first year student and my teacher is extremely vague while teaching so
I need some help understanding how to use the ArrayList in his instructions.
**I just need help understanding how this all works. I'm writing the code but I don't know how any of it works.
The Textual User Interface is supposed to be written in another class that I haven't done yet.**
My instructions were:
GradeManager Class
Start by developing a class to describe a GradeManager. Because this exercise is far more about writing an interactive application, we'll keep this class SIMPLE. Our GradeManager will just keep track of an ArrayList of scores and define the following methods:
A single constructor that accepts no parameters, but sets up the ArrayList so that it is
capable of holding some scores
A method called addScore that will accept a score and add it to the ArrayList
A method called getAverage that will return the average of all scores in the ArrayList
GradeTUI Class
This class will keep track of a GradeManager object as an instance variable. You will need to write a
constructor that accepts the GradeManager object that it will be using.
This class will also contain a method named run. This method will give the user the ability to either (1)
enter a score to be stored (in the GradeManager object) or (2) display the average of all scores entered
so far. Allow the user to continue this program by choosing one of these options until they are finished.
Driver Class
Once you are satisfied that these classes are defined and working properly, develop a driver class
containing a main method that will create an instance of GradeManager, pass this object to the
GradeTUI constructor, and then use the GradeTUI object to call run.
This is what I wrote:
public class GradeManager {
private ArrayList<Integer> gradeList;
public GradeManager() {
ArrayList<Integer> gradeList = new ArrayList<Integer>();
this.gradeList = gradeList;
}
public void addScore(int score) {
this.gradeList.add(score);
}
public double getAverage(ArrayList<Integer> gradeList) {
Integer aScore = 0;
if (!gradeList.isEmpty()) {
for (Integer grade : gradeList) {
aScore += grade;
}
return aScore.doubleValue() / gradeList.size();
}
return aScore;
}
}
First: I think the getAverage Method should use the internal ArrayList instead of a parameter.
Otherwise you don't have any read access to that lists contents.
You can use your GradeManager in the following way:
GradeManager manager = new GradeManager();
while(condition) {
int score = readScoreFromInput();
manager.addScore(score);
}
double averageScore = manager.getAverage();
print(averageScore);
So you get the average of all the scores you have just input.
The concrete implementation of the loop (and the exit condition) is up to you - it could be a predefined number of iterations or a special input like -1 for example.