Let's assume I have got a List of Flight Objects
public class Flight {
private int passengers;
private int price
...
//getters and Setters
}
List<Flight> flightList = new ArrayList<Flight>();
Now i need to accumulate price per passenger and the Price, because I have to be able to proceed both informations later on. so I would create two methods:
public int calculatePrice(List<Flight> flightList) {
int price = 0;
for (Flight flight : flightList) {
price = price + flight.getPrice();
}
return price;
}
public int calculatePricePerPassengers(List<Flight> flightList) {
int pricePerPassenger = 0;
for (Flight flight : flightList) {
pricePerPassenger = (pricePerPassenger) + (flight.getPrice() / flight.getPassgers());
}
return pricePerPassenger;
}
I have got like 4-5 methods of the same type. I am not sure whether there is too much redundancy, because I call the for loop 4-5 Times and I could easily do all the operations in one for loop, but that would have the effect of multiple return values. So is this the appropriate way ?
(just a dummy example)
You can use map for that or also you can warp all the fields you want to return in a class. Here I am giving the example using Map.
public static Map<String, Integer> calculatePrice(List<Flight> flightList) {
Map<String, Integer> priceMap = new HashMap<>();
int price = 0;
int pricePerPassenger = 0;
for (Flight flight : flightList) {
price = price + flight.getPrice();
pricePerPassenger = (pricePerPassenger) + (flight.getPrice() / flight.getPassgers());
}
priceMap.put("price", price);
priceMap.put("pricePerPassenger", pricePerPassenger);
return priceMap;
}
EDIT:
Example using a wrapper class (DTO).
public static FligtPriceDTO calculatePrice(List<Flight> flightList) {
FligtPriceDTO dto = new FligtPriceDTO();
int price = 0;
int pricePerPassenger = 0;
for (Flight flight : flightList) {
price = price + flight.getPrice();
pricePerPassenger = (pricePerPassenger) + (flight.getPrice() / flight.getPassgers());
}
dto.setPrice(price);
dto.setPricePerPassenger(pricePerPassenger);
return dto;
}
}
class FligtPriceDTO {
private int price;
private int pricePerPassenger;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getPricePerPassenger() {
return pricePerPassenger;
}
public void setPricePerPassenger(int pricePerPassenger) {
this.pricePerPassenger = pricePerPassenger;
}
}
You could wrap those two values into a new array:
public int[] calculatePrices(List<Flight> flightList) {
int totalPrice = 0;
int pricePerCustomer = 0;
for (Flight flight : flightList) {
totalPrice += flight.getPrice();
pricePerCustomer += (flight.getPrice() / flight.getPassgers());
}
return new int[] { totalPrice, pricePerCustomer };
}
It all comes down to what are the functionalities that you want to provide to the user. So if the user expects to be able to calculate both prices individually then I do not see any other way around what you have. But if you can present both prices at once, then you can eliminate one of the methods and loop only once trough your Flight list and return a composition of both prices. ex:
public static Pair[] calculatePrices(List<Flight> flightList)
{
int pricePerFlight= 0;
int pricePerPassenger = 0;
for(Flight flight : flightList)
{
pricePerFlight = pricePerFlight + flight.getPrice();
pricePerPassenger = pricePerPassenger +(flight.getPrice()/flight.getPassgers());
}
return new Pair[] {new Pair<>("pricePerFlight", pricePerFlight), new Pair<>("pricePerPassenger", pricePerPassenger )};
}
Related
I have a ScenarioGenerator class to generate the Scenario. And in the Audit class, I set the function to decide how many scenarios to be generated and wanted to print out the occurrence of each enum type (Gender in this case).
I've referred to Counting an Occurrence in an Array (Java)
I used the frequency method to count the occurrence, but when there are many scenarios generated, I don't know how to aggregate the data. What I've tried was:
Generate the scenarios and add each scenario in the ArrayList
For each scenario, I get the passenger ArrayList, and save their attributes in different collections.
For each collection, print out its value and the count.
I can simply do like this:
int maleCount = Collections.frequency(genderCollection, Gender.MALE);
System.out.println(Gender.MALE.toString().toLowerCase() + ":" +maleCount);
However, if I have more enums and attributes, this method becomes lengthy and inefficient. Is there any way to deal with this?
Here is part of my Audit class:
public class Audit {
private Scenario scenario = new Scenario();
private ScenarioGenerator scenarioGenerator = new ScenarioGenerator();
private Person person = new Person();
private String auditType;
private int nubmerOfSimulation;
public enum Gender {
MALE, FEMALE, UNKNOWN;
}
public Audit() {
}
// create a specific number of random scenarios
// the concept similar to gamePlayed and gameWon in the last project
public void run(int runs) {
this.nubmerOfSimulation = runs;
ArrayList<Scenario> scenarios = new ArrayList<Scenario>();//create a arrayList to store each scenario
for (int i = 0; i < runs; i++) {
Scenario singleScenario = scenarioGenerator.generate();
scenarios.add(singleScenario); // save each scenario into a scenario arrayList
}
survialCalculator(scenarios);
}
public int survialCalculator(ArrayList<Scenario> scenarios) {
//person attribute arrayList
ArrayList<Gender> genderCollection = new ArrayList<Gender>();
for (Scenario scenario : scenarios) { // for each scenario, getting its passengers and pedestrians
ArrayList<Character> passengers = scenario.getPassengers();
for (Character passenger : passengers) {
if (passenger instanceof Person) {
Gender gender = ((Person) passenger).getGender();
//System.out.println(gender);
genderCollection.add(gender);
}
}
//try to print out the elements in the collection and its frequency, but failed
for(Gender genderElement : genderCollection) {
int genderCount = Collections.frequency(genderCollection, genderElement);
System.out.println(genderElement.toString().toLowerCase()+ ":" + genderCount);
}
return 1;
}
Here is part of my ScenarioGenerator:
public class ScenarioGenerator {
private Person person = new Person();
private Random random = new Random();
private int passengerCountMinimum;
private int passengerCountMaximum;
private int pedestrianCountMininum;
private int pedestrianCountMaximum;
private ArrayList<Character> passengers = new ArrayList<Character>();
private ArrayList<Character> pedestrians = new ArrayList<Character>();
public Person getRandomPerson() {
//need age, gender, bodyType, profession, pregnancy
int age = random.nextInt(100);
int profession = random.nextInt(person.getProfessionEnumLength());
int gender = random.nextInt(person.getGenderEnumLength());
int bodyType = random.nextInt(person.getBodyTypeEnumLength());
int pregnancy = random.nextInt(2);
Person people = new Person(age,
Profession.values()[profession],
Gender.values()[gender],
BodyType.values()[bodyType],
pregnancy == 1 ? true : false);
return people;
}
public Animal getRandomAnimal() {
//species, isPet
int age = random.nextInt(100);
int gender = random.nextInt(person.getGenderEnumLength());
int bodyType = random.nextInt(person.getBodyTypeEnumLength());
boolean isPet = random.nextBoolean();
String [] species = {"cat", "dog"};
int idx = random.nextInt(species.length);
String pickSpecies = species[idx];
Animal creature = new Animal(age, Gender.values()[gender], BodyType.values()[bodyType] , pickSpecies);
creature.setIsPet(isPet);
return creature;
}
//getters and setter of min and max numbers of passengers and pedestrians
public Scenario generate() {
//random number of passengers and pedestrians with random characteristics
//randomly red light or green light
//random condition "You" in the car
//abide by the minimum and maximum counts from above setters
//get random numbers abide by the setters
int numberOfPassengers = ThreadLocalRandom.current().nextInt(getPassengerCountMin(), getPassengerCountMax()+1);
int numberOfPedestrains =ThreadLocalRandom.current().nextInt(getPedestrianCountMin(), getPedestrianCountMax()+1);
boolean legalCrossing = random.nextBoolean();
//generate the number from the total numbers of passenger and pedestrians
int numberOfPersonPassenger = ThreadLocalRandom.current().nextInt(0, numberOfPassengers+1);
int numberOfAnimalPassenger = numberOfPassengers - numberOfPersonPassenger;
int numberOfPersonPedestrian = ThreadLocalRandom.current().nextInt(0, numberOfPedestrains+1);
int numberOfAnimalPedestrian = numberOfPedestrains - numberOfPersonPedestrian;
//generate the number of person passengers
for (int i = numberOfPersonPassenger; i > 0; i--) {
Person person = getRandomPerson();
passengers.add(person);
}
//remaining of the number of passengers should be animals
//no matter it is pet of not
for (int i = numberOfAnimalPassenger; i > 0; i--) {
Animal animal = getRandomAnimal();
passengers.add(animal);
}
for (int i = numberOfPersonPedestrian; i > 0; i--) {
Person person = getRandomPerson();
pedestrians.add(person);
}
for (int i =numberOfAnimalPedestrian; i > 0; i--) {
Animal animal = getRandomAnimal();
pedestrians.add(animal);
}
Scenario scenario = new Scenario(passengers, pedestrians, legalCrossing);
return scenario;
}
Here is part of my Scenario class:
public class Scenario {
private Random random;
private ArrayList<Character> passenagers = new ArrayList<Character>();
private ArrayList<Character> pedestrians = new ArrayList<Character>();
private boolean legalCrossing;
public Scenario() {
}
public Scenario(ArrayList<Character> passengers, ArrayList<Character> pedestrians, boolean isLegalCrossing) {
this.passenagers = passengers;
this.pedestrians = pedestrians;
this.legalCrossing = isLegalCrossing;
}
//getters and setters
The main class is to call the method:
public static void main(String[] args) throws Exception {
ethicalEngine.generate();
}
public void generate() {
Audit audit = new Audit();
audit.run(5);
}
You can use groupingBy stream operation on List<Gender> to get map of all gender type with count.
Map<Gender, Long> counted = genderCollection.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
And print this way
for (Map.Entry<Gender, Long> item : counted.entrySet()) {
System.out.println(item.getKey().toString()+ ":" + item.getValue());
}
You might consider using the Guava Multiset. As Stated here this data structure is more efficent when you have more attributes to count as the access to the number lies most of the time in O(1).
I am having two LinkedLists : newLinkedList and oldLinkedList, both contain BID class objects. Below is my BID class:
public class Bid {
private int quantity;
private double bidPrice;
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public double getBidprice() {
return bidPrice;
}
public void setBidprice(double bidPrice) {
this.bidPrice = bidPrice;
}
}
Now I have to create a new LinkedListlist that contains sorted elements of newLinkedList and oldLinkedList based on price variable of the BID class.
If I get the same price in both the LinkedList then I have to keep newLinkedList BID class object and remove the old one.
That means new LinkedList must contain Bid class objects sorted on the basis of the price variable.
This is my main function:
public static void main(String[] args) throws InterruptedException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter size of linkedlist 1 ");
int size1 = Integer.parseInt(br.readLine());
System.out.println("Enter size of linkedlist 2 ");
int size2 = Integer.parseInt(br.readLine());
LinkedList<Bid> oldLinkedList= addElementsToList(size1);
LinkedList<Bid> newLinkedList= addElementsToList(size2);
/*
SORT BOTH THE LINKED LISTS HERE
*/
}
public static LinkedList<Bid> addElementsToList(int size) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
LinkedList<Bid> bidList = new LinkedList<Bid>();
for (int i = 0; i < size; i++) {
Bid bid = new Bid();
System.out.println("Enter bid price of Object " + i);
bid.setBidprice(Double.parseDouble(br.readLine()));
System.out.println("Enter bid quantity of Object " + i);
bid.setQuantity(Integer.parseInt(br.readLine()));
bidList.add(bid);
}
return bidList;
}
Maybe this is what your want, for each Bid in oldList, check if it's price already exists in newList. If exists, do nothing, otherwise add it to newList, and sort the last newList. You can test it.
Note: I'm not sure if you really want to compare two double price.
boolean containsSamePrice(LinkedList<Bid> list, double price) {
for (Bid bid : list) {
if (bid.getBidprice() == price) {
return true;
}
}
return false;
}
LinkedList<Bid> mergeAndSort(LinkedList<Bid> newLinkedList, LinkedList<Bid> oldLinkedList) {
for (Bid oldBid : oldLinkedList) {
if (!containsSamePrice(newLinkedList, oldBid.getBidprice())) {
newLinkedList.add(oldBid);
}
}
Comparator<Bid> comparator = new Comparator<Bid>() {
#Override
public int compare(Bid o1, Bid o2) {
if (o1.getBidprice() < o2.getBidprice())
return -1;
if (o2.getBidprice() == o2.getBidprice())
return 0;
return 1;
}
};
Collections.sort(newLinkedList, comparator);
return newLinkedList;
}
You can implement the Comparator Interface in Bid class and use a Collections.sort() method.
So I need to grab the itemPrice part of the index and add them all together, but i'm not sure how to go about accessing that. Can I somehow use my getCost method from the GroceryItemOrder class and continuously add it to the totalCost in the GroceryList class, or do I need to access the itemPrice and quantity part of each stored object.
public class GroceryList {
public GroceryItemOrder[] groceryList = new GroceryItemOrder[0];
public int manyItems;
public GroceryList() {
final int INITIAL_CAPACITY = 10;
groceryList = new GroceryItemOrder[INITIAL_CAPACITY];
manyItems = 0;
}
//Constructs a new empty grocery list array
public GroceryList(int numItem) {
if (numItem < 0)
throw new IllegalArgumentException
("The amount of items you wanted to add your grocery list is negative: " + numItem);
groceryList = new GroceryItemOrder[numItem];
manyItems = 0;
}
public void add(GroceryItemOrder item) {
if (manyItems <= 10) {
groceryList[manyItems] = item;
}
manyItems++;
}
//
// #return the total sum list of all grocery items in the list
public double getTotalCost() {
double totalCost = 0;
for (int i = 0; i < groceryList.length; i++ ) {
//THIS PART
}
return totalCost;
}
}
And this is GroceryItemOrder
public class GroceryItemOrder {
public String itemName;
public int itemQuantity;
public double itemPrice;
public GroceryItemOrder(String name, int quantity, double pricePerUnit) {
itemName = name;
itemQuantity = quantity;
itemPrice = pricePerUnit;
}
public double getcost() {
return (itemPrice*itemQuantity);
}
public void setQuantity(int quantity) {
itemQuantity = quantity;
}
public String toString() {
return (itemName + " " + itemQuantity);
}
}
Thanks for all the replies! I got it working and understand what's going on here now.
You first need to access an instance of GroceryItemOrder in the array and from there then access its itemPrice field like so,
groceryList[0].itemPrice
would give you the itemPrice of the first groceryListOrder in the groceryList array. If you want to use a method to do this instead, then add a getItemPrice method in your groceryListOrder class,
public getItemPrice() {
return itemPrice;
}
Then you can access each groceryListOrder's itemPrice in the array like so,
groceryList[0].getItemPrice()
would do the same as groceryList[0].itemPrice. If you wanna get the total cost of all the objects in the groceryList array, then use a loop to add all the itemPrice fields multiplied by the itemQuantity field (since it's the totalcost of each object being summed together) by using your getcost method,
double totalCost = 0;
for (int i = 0; i < groceryList.length; i++) {
totalCost += groceryList[i].getcost();
}
First of all you should encapsulate all fields ofGroceryItemOrder class, so all the fields should be private member of the class and then use their setter/getter methods to access them in GroceryList.
Secondly, this implementation has a bug. The second constructor gets numItem as input and initialize array size accordingly. But, add method does not look at the real size and that might cause invalid array index exception. Consider this code:
GroceryList list = new GroceryList(2);
for (int i=0; i<10; i++)
list.add(new GroceryItemOrder("grocery", 5, 10));
The exception will be occurred when i=2
This works for me, you would need to set static GroceryItemOrder[] groceryList = new GroceryItemOrder[0]; as well:
//
// #return the total sum list of all grocery items in the list
public static double getTotalCost() {
double totalCost = 0;
for (int i = 0; i < groceryList.length; i++ )
{
totalCost += groceryList[i].getcost();
}
return totalCost;
}
I am creating a program that handles a car dealership. The user has the opportunity to add a car in the store by creating a random 3 digit number.
Now the question is how I can search/delete cars depending on the 3 digit code?
I'm thinking that I need every code that the cars have to save it on an array so I can search and delete afterwards.
I have created a class and certain methods on it, I have also created 5 objects and I'm trying to see if it works on these 5.
Here is the method of the random number:
I use the metritis variable because I can't achieve to place correctly the values on the array so I have to give parameter of 1,2,3,4,5 so I can place them correctly to the array.
package antiprosopeia;
import java.util.Random;
public class Antiprosopeia {
private String company,colour;
private int model,horsePower,speed,price,specialCode,metritis;
private int[] codes = new int[]{0,0,0,0,0};
public Antiprosopeia(String company, String colour, int model, int horsePower, int speed, int price) {
this.company = company;
this.colour = colour;
this.model = model;
this.horsePower = horsePower;
this.speed = speed;
this.price = price;
}
public Antiprosopeia() {
company = ""; colour = ""; model = 0; horsePower = 0; speed = 0; price = 0;
}
public void setRandomNumber(int metritis) {
Random rand = new Random();
int randNum2 = rand.nextInt(900) + 100;
specialCode = randNum2;
codes[metritis] = specialCode;
}
public void printarray() {
for(int i=0; i<codes.length; i++) {
System.out.println(" " + codes[i]);}
}
public void Info() {
System.out.println("Company : " + company + "\nColour : " + colour + "\nModel : " + model + "\nHorse Power : " + horsePower +
"\nSpeed : " + speed + "\nPrice : " + price );
}
public static void main(String[] args) {
Antiprosopeia car1 = new Antiprosopeia("Toyota","red",333,100,2223,8000);
car1.setRandomNumber(0);
Antiprosopeia car2 = new Antiprosopeia("Mercedes","yellow",233,100,2990,9000);
car2.setRandomNumber(1);
Antiprosopeia car3 = new Antiprosopeia("Volkswagen","green",153,100,2780,6000);
car3.setRandomNumber(2);
Antiprosopeia car4 = new Antiprosopeia("Mitsubisi","white",678,140,2600,7000);
car4.setRandomNumber(3);
Antiprosopeia car5 = new Antiprosopeia("Porsche","black",390,1000,2000,30000);
car5.setRandomNumber(4);
}
}
[EDIT] Now when i call the printarray() method it seems that at my array only one value is hold and all the others are zer0s as i defined the array at start of my program
If I were doing this, I would use a HashMap. This way you know that you have a unique 3 digit number, and if you wanted to, you could also store more data. You could do something like:
HashMap<Integer, Car> cars = new HashMap<Integer, Car>();
This example would allow you to add a car object to the map. You don't have to that, but it's an option. If you didn't want to do that, you could do:
HashMap<Integer, String> cars = new HashMap<Integer, String>();
and then do:
cars.put(123, "Description of car");
Using a HashMap would give you more options when storing the data. This would also prevent you from creating an array with 1000 elements, all of which are 0 until you have a value for them. You could easily print out all your numbers by doing:
for(int number : cars.entrySet()){
System.out.println("My car number: " + number);
}
Searching for keys would extremely easy, as you could do:
String description = cars.getKey(123);
If description was null, you would know that there is no key for it.
Your issue is that each Antiprosopeia object has its own codes array. They are not shared.
If you really want each object to have a Random ID, then assign that within the constructor.
public class Antiprosopeia {
private String company,colour;
private int model,horsePower,speed,price,specialCode,metritis;
private int randID;
public Antiprosopeia(String company, String colour, int model, int horsePower, int speed, int price){
this.company = company;
this.colour = colour;
this.model = model;
this.horsePower = horsePower;
this.speed = speed;
this.price = price;
this.randID = new Random().nextInt(900) + 100;
}
public Antiprosopeia(){
this("", "", 0, 0, 0, 0);
}
public int getID() { return this.randID; }
#Override
public String toString() {
return String.format(
"Company : %s\n" +
"Colour : %s\n" +
"Model : %s\n" +
"Horse Power : %d\n" +
"Speed : %d\n" +
"Price : %d\n",
company, colour, model, horsePower, speed, price
);
}
If you want to print all those objects,
public static void main(String[] args) {
List<Antiprosopeia> cars = new ArrayList<Antiprosopeia>();
cars.add(new Antiprosopeia("Toyota","red",333,100,2223,8000));
cars.add(new Antiprosopeia("Mercedes","yellow",233,100,2990,9000));
for (int i = 0; i < cars.size(); i++) {
Antiprosopeia c = cars.get(i);
System.out.println(c.getID());
System.out.println(c);
}
}
I am studying Java and have been asked to produce methods that can be used in order to gather statistics based off of the student names and marks that are entered. I have worked out how to calculate the top mark but what I need to do is return the name of the student that got the highest mark, how would I do this? I was thinking I could try to return the string before the highest int but I wasn't sure how I would do that.
Edit: Just to make it clear, currently, when END is entered in to the console following the input of data, the top mark is returned - I need to return the mark of the best student.
import java.util.*;
public class Course {
private ArrayList<Student> people = new ArrayList<Student>();
private int passing = 0;
private int failing = 0;
private int top = Integer.MIN_VALUE;
private int sum = 0;
public void add( Student student ) {
people.add( student );
if(student.getMark() >= 40){
passing++;
}
else {
failing++;
}
sum += student.getMark();
if(student.getMark() > top) {
top = student.getMark();
}
}
public int pass() {
return passing;
}
public int fail() {
return failing;
}
public int top() {
return top;
}
public double average() {
return sum / people.size();
}
}
Thanks for any help.
Update: BinaryJudy, I did what you said but I get a 'NoSuchMethod' error for the top name, this is what I changed my code to:
import java.util.*;
public class Course {
private ArrayList<Student> people = new ArrayList<Student>();
private int passing = 0;
private int failing = 0;
private int top = Integer.MIN_VALUE;
private int sum = 0;
private String topName;
public void add( Student student ) {
people.add( student );
if(student.getMark() >= 40){
passing++;
}
else {
failing++;
}
sum += student.getMark();
if(student.getMark() > top) {
top = student.getMark();
}
if(student.getMark() > top) {
top = student.getMark();
topName = student.getName();
}
}
public int pass() {
return passing;
}
public int fail() {
return failing;
}
public String top() {
return topName;
}
public double average() {
return sum / people.size();
}
}
Any idea why? :)
You have already found the student with the top mark. Update the top name with the name of the student when the top mark is found. Finding the top mark results in also finding the name.
String topName;
if(student.getMark() > top) {
top = student.getMark();
topName = student.getName();
}
Note that you're storing a bunch of students who I assume each have a mark for the course. All you need to do is cycle through that Arraylist, and find out who has the highest mark, and return that student.
Something like this may work for you:
public String topStu(ArrayList<Student> list) { // take in any list of students
int topStudentScore = 0; // default value
Student topStudent = null;
for (student x : list) { // cycle through all students in the list
if (x.getMark() > topStudentScore) { // if the score is higher than the current listed score
topStudentScore = x.getMark(); // update the top score
topStudent = x; // update top student
}
}
return topStudent.getName(); // return his name
}
You can easily write this to be a function for a specific course - you can remove the parameter, and directly access the private ArrayList if you want to.
Alternatively, you can write the above function to be a static function that takes any list of students from any course.
If a student is unique in the people list and insert order has no importance, then you can change
ArrayList<Student> people = ...;
By
// Java7 and before
SortedSet<Student> people = new TreeSet<>(new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return s2.getMark()-s1.getMark(); // sorted by decreasing mark
}
});
// Java8
SortedSet<Student> people
= new TreeSet<>(Comparator.comparingInt(Student::getMark).reversed());
Then finding the top student is matter of getting the first from the people set:
Student top = people.first();
As a bonus, you can compute easily the ranking for all student. Adding new student will put them at the right ranking.
Note: Be aware that modifying a student mark after insertion will not change automatically its ranking and should be handled through a sequence of :
Student s = ...;
people.remove(s);
s.setMark(42);
people.add(s);
public class Classroom
{
Student[] students;
int numStudentsAdded;
public Classroom(int numStudents)
{
students = new Student[numStudents];
numStudentsAdded = 0;
}
public Student getTopStudent()
{
int y = 0;
//have to use numStudentsAdded
for ( int i = 0 ; i < numStudentsAdded ; i++)
{
if (students[y].getAverageScore() < students[i].getAverageScore())
{
y = i;
}
}
return students[y] ;
}
public void addStudent(Student s)
{
students[numStudentsAdded] = s;
numStudentsAdded++;
}
public void printStudents()
{
for(int i = 0; i < numStudentsAdded; i++)
{
System.out.println(students[i]);
}
}
}