There is a list of 200 students names and exam results.
My task is: "Create a constructor method for this list and put them in descending order with for statement".
I've done the first part. I can print out the list also. But I have no idea how to put them in descending order using for statement. Can anyone show me how to do that?
Current code:
package training;
public class ExamResult {
String studentName;
String examName;
int points;
String date;
ExamResult(String studentName, String examName, String date,int points) {
this.studentName=studentName;
this.examName=examName;
this.points=points;
this.date=date;
}
public void display() {
System.out.println(studentName + " " + examName + " " + date + " " + points);
}
}
package training;
public class DisplayExamResults {
public static void main (String args[]) {
ExamResult one=new ExamResult("Ryan Pena","Sociology","21/06/2016",16);
ExamResult two=new ExamResult("Portia Hamilton","Sociology","21/06/2016",34);
ExamResult three=new ExamResult("Ryan Pena","Sociology","21/06/2016",35);
one.display();
two.display();
three.display();
}
}
So, Daniel! This is going to be long because you are new to Java and I will try to explain everything. You can always read more about a lot of things here but I will explain just enough for this problem.
When you want to sort objects of a class, in your case, class ExamResult, you cannot just use a for loop on one of the fields and finish sorting. In order to achieve your desired sorting, you will need to use an interface called Comparable. This interface lets you write your own sorting criteria based on the structure of your class.
We will proceed step by step.
Step 1: Implement the Comparable interface in the ExamResult class
Since you want to sort objects of the ExamResult class, this is where you will implement the interface. By that, we mean, you will write how you want to sort your objects. We want to sort based on the student names. And for sorting, we will need to compare objects to see which one is greater than the other.
Here, we will use a term called overriding which basically means that we will override the comparison function which was declared in the Comparable interface.
Our definition below takes as input an object of the class ExamResult and compares its student name with that of the current object - this. On comparison, it returns an integer:
0, if the names are equal
>0, if the other object's student name is greater than the current one
<0, if the other object's student name is lesser than the current one
package training;
public class ExamResult implements Comparable<ExamResult> {
/* your previous code remains here as is*/
// this function returns the name of the student
public String getStudentName() { return studentName; }
#Override
// write your sorting criteria
public int compareTo(ExamResult other) {
String name1 = this.getStudentName();
String name2 = other.getStudentName();
return name1.compareTo(name2);
}
}
Step 2: Construct a list of ExamResult objects in DisplayExamResults class
Now that we have finished defining how to compare objects, we need a list of those objects on which we will run the for loop and perform the comparison.
We can do that in the DisplayExamResults class like so:
// Create a list of results on which you will run your for loop
List<ExamResult> resultList = new ArrayList<>();
resultList.add(one);
resultList.add(two);
resultList.add(three);
Here, the List interface lets you define a list of objects of any user defined class like yours. So you create a list and add the ExamResult objects to it.
Step 3: Sort using the for loop
This is the final step, where you perform the actual sorting in the DisplayExamResults class. We will first sort in ascending order and then reverse the list.
You start with a left (i) and a right (j) pointer. i is set to 0 because it starts at the beginning of the list and j is set at the end of the list.
As you keep comparing, if the object on the left is smaller than the one on the right, you just move on, i.e. increment i. Similarly, if the object on the right is greater than that on the left, just move on by decrementing j.
But, if the order is not like that, then you swap them. Which is what we do in the if statement. You can see that we are using the compareTo() function that we had defined above.
// Loop over that list to sort the objects
for (int i = 0; i < resultList.size(); i++) {
for (int j = resultList.size() - 1; j > i; j--) {
if (resultList.get(i).compareTo(resultList.get(j)) > 0) {
ExamResult temp = resultList.get(i);
resultList.set(i, resultList.get(j));
resultList.set(j, temp);
}
}
}
// For descending order
Collections.reverse(resultList);
// Display the results after sorting is over
for (ExamResult r : resultList) {
r.display();
}
Phew! Now, we put all that code together to get the following two files.
package training;
public class ExamResult implements Comparable<ExamResult> {
String studentName;
String examName;
int points;
String date;
ExamResult(String studentName, String examName, String date,int points) {
this.studentName=studentName;
this.examName=examName;
this.points=points;
this.date=date;
}
public void display() {
System.out.println(studentName + " " + examName + " " + date + " " + points);
}
// this function returns the name of the student
public String getStudentName() { return studentName; }
#Override
// write your sorting criteria
public int compareTo(ExamResult other) {
String name1 = this.getStudentName();
String name2 = other.getStudentName();
return name1.compareTo(name2);
}
}
And
package training;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DisplayExamResults {
public static void main (String args[]) {
ExamResult one = new ExamResult("Ryan Pena","Sociology","21/06/2016",16);
ExamResult two = new ExamResult("Portia Hamilton","Sociology","21/06/2016",34);
ExamResult three = new ExamResult("Ryan Pena","Sociology","21/06/2016",35);
one.display();
two.display();
three.display();
System.out.println("\n");
// Create a list of results on which you will run your for loop
List<ExamResult> resultList = new ArrayList<>();
resultList.add(one);
resultList.add(two);
resultList.add(three);
// Loop over that list to sort the objects
for (int i = 0; i < resultList.size(); i++) {
for (int j = resultList.size() - 1; j > i; j--) {
if (resultList.get(i).compareTo(resultList.get(j)) > 0) {
ExamResult temp = resultList.get(i);
resultList.set(i, resultList.get(j));
resultList.set(j, temp);
}
}
}
// For descending order
Collections.reverse(resultList);
// Display the results after sorting is over
for (ExamResult r : resultList) {
r.display();
}
}
}
I tried to explain the bits in there. Please read more and understand better. Hope it helps.
If the names are as a String Array or a List:
Using standard Java libraries:
String[] students = {"Aaron", "Jonas", "Bob", "Karl"};
Arrays.sort(students);
List<String> temp = new ArrayList<>(Arrays.asList(students));
Collections.reverse(temp);
temp.toArray(students);
OR
Using Bubblesort and chars to compare the strings:
String[] students = {"Aaron", "Jonas", "Bob", "Karl"};
char[] temp1;
char[] temp2;
int length;
for(int i = 0; i < students.length; i++){
temp1 = students[i].toLowerCase().toCharArray();
for(int n = i+1; n < students.length; n++){
temp2 = students[n].toLowerCase().toCharArray();
if(temp1.length > temp2.length)
length = temp2.length;
else
length = temp1.length;
for(int c = 0; c < length; c++){
if(temp1[c] < temp2[c]){
String temp = students[i];
students[i] = students[n];
students[n] = temp;
temp1 = students[i].toLowerCase().toCharArray();
break;
}
else if(temp1[c] > temp2[c])
break;
}
}
}
Related
I'm trying to create a FileIO where random numbers are placed into a .txt file and outputted, sorted in another .txt file. I have a bubble sort code that can sort numbers & I have another code that makes a .txt file. I'm just not sure how I'd implement these 2 together.
Here's my fileIO code:
public static void main(String[] args) {
File file = new File("test.txt");
//Writes name and age to the file
try {
PrintWriter output = new PrintWriter(file);
output.println("Rober");
output.println(27);
output.close();
} catch (IOException ex) {
System.out.printf("ERROR: %s\n", ex);
}
//Reads from the file
try {
Scanner input = new Scanner(file);
String name = input.nextLine();
int age = input.nextInt();
System.out.printf("Name: %s Age %d\n", name, age);
} catch (FileNotFoundException ex) {
System.out.printf("ERROR: %s\n", ex);
}
}
And here is my bubble sort code:
public static void main(String[] args) {
Random num = new Random();
//Creating an array for 10 integers
int [] number = new int [10];
System.out.print("Random Numbers:");
/*Display the unsorted numbers in a random order.
These numbers range from 0 to 100
*/
for (int d = 0 ; d<number.length ; d++){
/* We add a "+1" to the nextInt(100) here because then the numbers
will only range from 0 to 99.
*/
int RandomG = num.nextInt(100)+1;
number[d] = RandomG;
System.out.print(" " +RandomG);
}
//Display the sorted numbers
System.out.print("\nSorted Numbers:"+Arrays.toString(BubbleSortAsceMethod(number)));
}
public static int [] BubbleSortAsceMethod(int[] number){
int placeholder;
for(int i = 0 ; i < number.length-1 ; i++){
for ( int x = 1 ; x < number.length-i ; x++){
/*If the first number in the sequence is greater than the second
number, than save the first number of sequence in placeholder
and place the second number in the first numbers position, and
put the placeholder in the second numbers position (SWAP).
*/
/*
Since this is saying that when the first term is bigger than the
2nd term, the sequence will increase. If we flip the relational
operator, the sequence will decrease.
*/
if ( number[x-1] < number[x]){
placeholder = number[x-1];
number[x-1] = number[x];
number[x] = placeholder;
}
}
}
return number;
}
I'm kinda new to all this java stuff so please go a bit easy on me! Any help at all is appreciated :)
As the data contained in the file will consist of a pair of values: The name (String) and the age (int), you will need to retain their relationship. The best way of doing this would be to create a Class to represent the data. Eventually you want to sort the data on age using your BubbleSort method. While practically this would not be your first choice to sort data, I assume that this is a requirement. The BubbleSort method you have sorts an int[] by comparing each entry against it's immediate neighbor. With int being primitive, you can directly compare each element using the < operator.
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.age = age;
this.name = name;
}
public String getName() { return name; }
public int getAge() { return age; }
#Override
public String toString() {
return name + System.lineSeperator() + age;
}
#Override
public int compareTo(Person person) {
return this.age - person.age;
}
}
You may want to implement the Comparable interface to compare Objects; in which the interface must be implemented by Overriding the compareTo(Person person) method. You can impose sorting on age by returning the difference in age. This is not the only way you can impose the order you want; you may wish to compare directly using the getAge() of each Object or create a Comparator object.
Using the Comparable interface does allow you to make your BubbleSort class more generic, however (though the array must be of Objects that implement the interface; hence no primitive types).
public class BubbleSort {
public static <T extends Comparable> T[] BubbleSortAsceMethod(T[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int x = 1; x < array.length - i; x++) {
if (comparator.compare(array[x - 1], array[x]) < 0) {
T placeholder = array[x - 1];
array[x - 1] = array[x];
array[x] = placeholder;
}
}
}
return array;
}
}
You will notice that this sort method has some slight differences from your original, namely the BubbleSortAsceMethod method signature with the introduction of generic type parameters. Once again, this is completely optional, though this does give you the flexibility to use this method in the future for other arrays of Classes that extend the Comparable interface.
If you don't want to use generics or the Comparable interface, you will need to change the method signature and if statement.
You're method signature should instead look like public static Person[] BubbleSortAsceMethod(Person[] array) and the if statement if (array[x-1].getAge() < array[x].getAge())
This can give you an illustration of it working, though this does not consider the file io which should be simple to implement from what you have done already.
static Random random = new Random();
public static void main (String args[]) {
int size = 100;
Person[] peopleArray = new Person[size];
for (int i = 0; i < size; i++) {
String name = generateName(random.nextInt(4) + 4);
int age = random.nextInt(100);
peopleArray[i] = new Person(name, age);
}
peopleArray = BubbleSort.BubbleSortAsceMethod(peopleArray);
}
Note that this conforms, at least as much as possible, to the code you have implemented this far. If the BubbleSort and use of arrays are not critical, data structures that implement the List interface, such as ArrayList, can allow you to implement this much cleaner. This does not use the BubbleSort method at all.
public static void main (String args[]) {
int size = 100;
ArrayList<Person> people = new ArrayList<>();
for (int i = 0; i < size; i++) {
String name = generateName(random.nextInt(4) + 4);
int age = random.nextInt(100);
people.add(new Person(name, age));
}
peopleList.sort(Person::compareTo);
//or, if you don't want to implement comparable
peopleList.sort(Comparator.comparing(Person::getAge));
}
Appendix:
Used for illustrative purposes: Generates a name of a set length (randomly).
static char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
public static String generateName(int length) {
if (length > 0) {
return alphabet[random.nextInt(alphabet.length)] + generateName(length - 1);
}
return "";
}
I am attempting to print out a hashset taking in records from a database which are currently stored in two seperate ArrayLists. When I attempt to print out the HashSet the following error shows.
This is your HashSet[nyu.Sorting#378bf509, nyu.Sorting#7b23ec81, nyu.Sorting#15aeb7ab, nyu.Sorting#27d6c5e0, nyu.Sorting#7ef20235, nyu.Sorting#4f3f5b24, nyu.Sorting#6acbcfc0, nyu.Sorting#2d98a335, nyu.Sorting#5fd0d5ae, nyu.Sorting#16b98e56]
And this is my code:
public static HashSet<Sorting> t() {
Sorting s = new Sorting();
int TimeNeededOne = 75;
int TimeNeededTwo = 75;
int assignedTimeOne = 0;
int assignedTimeTwo = 0;
HashSet<Sorting> c = new HashSet<Sorting>();
for(int i=0; i<=i1.size()-1; i++)
{
if((assignedTimeOne < TimeNeededOne) && !(assignedTimeOne+ i1.get(i).getLengthMins() > offensiveTimeInMins) )
{
c.add(i1.get(i));
assignedTimeOne += i1.get(i).getLengthMins();
}
}
for(int i=0; i<=i2.size()-1; i++)
{
if((assignedTimeTwo < TimeNeededTwo) && !(assignedTimeTwo + i2.get(i).getLengthMins() > TimeNeededTwo) )
{
c.add(i2.get(i));
assignedTimeTwo += i2.get(i).getLengthMins();
}
}
System.out.println("Training programme :" + c.size());
System.out.println("This is your training programme" + c.toString());
return c;
}
The c.size is there to confirm that ten entries are made which is correct however the formatting of the records from the hashset obviously contains a problem. Any help with this issue would be greatly appreciated.
Thanks.
One way of doing this would be to override the toString() method of your Sorting class to print its contents:
public class Sorting {
...
#Override
public String toString() {
// Return a String that represents this object
return "...";
}
}
You need override toString() method in the Sorting class, for example:
class Sorting {
...
#Override
public String toString() {
// a string representation of Sorting object
}
}
java.util.Iterator runs through the whole collection and for each element invokes a toString() method. The data recorded in the java.lang.StringBuilder, which returns of its string representation at the end.
I would like to use my own sorting method instead of Collections.sort so that I can tinker around with my program to understand other sorts, generics, and ArrayLists better.
I have an employee class that has an employee number member. I know how to make an ArrayList of Employee objects, but could you explain how I could print and sort them? I started off by sorting a regular array and wanted to do the same with an ArrayList of Employee objects (the employee number). I'm having trouble understanding how to print ArrayLists of objects and sorting them.
package dataStructures;
import java.util.ArrayList;
import java.util.Arrays;
public class SortPractice {
public static void main(String[] args) {
int[] nums = {5,4,3,2,1};
System.out.println(Arrays.toString(nums));
BubbleSort1(nums);
ArrayList<Employee> empList = new ArrayList<Employee>();
for (int i=0; i<10; i++) {
empList.add(new Employee(10-i));
}
BubbleSort(empList); //This method doesn't work. I need help here.
}
public static void BubbleSort (int[] A) { //I included this because I know it works.
int temp = 0;
int firstLoopCount = 0;
int SecLoopCount = 0;
for (int i=0; i< A.length-1; i++) {
firstLoopCount++;
System.out.println(Arrays.toString(A) + i + " << First Loop interation");
for (int j=0; j<A.length-1; j++) {
if (A[j] > A[j+1]) {
temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
}
SecLoopCount++;
System.out.println(Arrays.toString(A) + j + " << Second Loop Interation");
}
}
System.out.println((firstLoopCount+SecLoopCount));
}
public static void BubbleSort (ArrayList<Employee> empList) { //I tried to use the same
int temp = 0; //approach just with the List
int firstLoopCount = 0;
int SecLoopCount = 0;
for (int i=0; i<empList.size()-1; i++) {
firstLoopCount++;
System.out.println(Arrays.toString(empList) + i + " << First Loop interation");
for (int j=0; j<empList.size()-1; j++) {
if (empList.get(j) > empList.get(j+1)) { //I get errors here in Eclipse and
temp = A[j]; //up above when I use toString
A[j] = A[j+1];
A[j+1] = temp;
}
SecLoopCount++;
System.out.println(Arrays.toString(A) + j + " << Second Loop Interation");
}
}
System.out.println((firstLoopCount+SecLoopCount));
}
Here is the employee class. It has other getters and setters but I didn't include them.
package dataStructures;
public class Employee {
private int empNum;
private String firstName;
private String LastName;
private String email;
public Employee(int empNum) {
this.empNum = empNum;
}
public String toString(){
return " "+ empNum + ",";
}
public Employee() {
}
public int getEmpNum() {
return empNum;
}
public void setEmpNum(int empNum) {
this.empNum = empNum;
}
Accessing an array is different from accessing an ArrayList. This is because these two objects are fundamentally different.
Let's focus on this line of code:
System.out.println(Arrays.toString(empList) + i + " << First Loop interation");
You're going to want to bookmark the Java 7 API so that you can reference what it is these methods actually take as arguments. Believe me, it will save you lots of time in the long run.
Specifically, the code is invalid because toString does not accept a parameter of type ArrayList. You can just straight-up print an ArrayList, as it has a reasonable toString method, whereas an array doesn't (which is why you use Arrays#toString):
System.out.println(empList.toString() + i + " << First Loop interation");
Let's look at this if block next:
if (empList.get(j) > empList.get(j + 1)) { //I get errors here in Eclipse and
temp = A[j]; //up above when I use toString
A[j] = A[j + 1];
A[j + 1] = temp;
}
I'll be blunt, you're going to get errors in any reasonable IDE with that code. The reason: you index into arrays with brackets, but you use get for an ArrayList.
The first fix is that you can't compare those two instances with >. What you'd wind up doing instead is retrieving the field you want to compare it with instead.
if(empList.get(j).getEmpNum() > empList.get(j+1).getEmpNum()) {
// more code
}
Here's the relevant Javadoc for ArrayList. You're going to need it.
Let's focus on the inner part of the if. The operation you're doing there is called a swap. You're taking an element from one location and overwriting it with another. Since arrays don't shift elements down, you have to capture the original value before you overwrite it.
To put it in English:
Take original value
Place new value in original value's original array location
Place original value in new value's original array location
You shouldn't have to do that with an ArrayList, as it can add the element in a specific spot.
In English, it should be as simple as:
Insert new value in original value's spot
Delete new value's occurrence in the list
In Java, it might read like this:
if(empList.get(j).getEmpNum() > empList.get(j + 1).getEmpNum()) {
empList.add(j, empList.get(j + 1));
empList.remove(j + 1);
}
One problem I noticed is in this line -
empList.get(j) > empList.get(j+1)
You are comparing 2 objects, i.e. 2 employee objects, this is usually not used other than for primitive types (e.g. Integer).
What you probably want to compare is the employee IDs which I assume is in your Employee.java file (please post this file so we can take a look). Here's an example of what you could do for this line -
empList.get(j).getEmployeeId() > empList.get(j+1).getEmployeeId()
Edit: sorry read the question wrong, not using Collections.sort()
Here is an example. In this case, your class has to provide a method that overrides the compareTo method in the Comparable interface. The specification is that it should return an integer greater than 0 if the calling object is greater, or an integer less than 0 if the caller is less, return 0 otherwise.
public class Employee implements Comparable {
//Rest of your class code here
public void getID() {
//return some value associated with the ID
}
//override this method
public int compareTo(Employee other) {
//code to compare two Employees
// Maybe something like the following
if (this.getID() > other.getID()) {
return 1;
} else if (this.getID() < other.getID()) {
return -1;
} else {
return 0;
}
}
}
This is the final answer with the help of #Makoto
public static void BubbleSort (ArrayList<Employee> empList) {
for (int i=0; i<empList.size()-1; i++) {
for (int j=0; j<4; j++) {
if (empList.get(j).getEmpNum() > empList.get(j+1).getEmpNum()) {
empList.add(j, empList.get(j + 1)); //This line inserts the smaller value
empList.remove(j+2); //into the first index and pushes the
} //indices down 1. So I need to remove
//j+2 not j+1.
/*When I use the debugger to step into toString() it says source not found.
I don't get it but it works.*/
System.out.println(empList.toString() + j + " << Second Loop Interation");
}
System.out.println(empList.toString() + i + " << First Loop interation");
}
}
For my assignment, I have to create both a method to sort integers and Strings stored in an object class. Keep in mind, I HAD TO USE CASTS. I wanted to use generics, but my teacher INSISTS on me using 1.4.2 (which don't have generics). I can sort time, and for the alphabetical sort, I used my method to sort time and added a compareTo. I played with it a bit, but when I output it, it gives me everything I inputted in the order I inputted it. Not in alphabetical.
Here's the class I created to store input:
public class showInfo
{
String name;
String day;
int time;
}
The following is the method to sort by name!
//method to sort and display info
public static void sortName(){
for(int i = 0; i < show.size() - 1; i++) {
for(int j = 0; j < show.size() - 1; j++){
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(i+1)).name) > 0){
showInfo temp = new showInfo();
temp.name = ((showInfo)show.get(j)).name;
temp.day = ((showInfo)show.get(j)).day;
temp.time = ((showInfo)show.get(j)).time;
((showInfo)show.get(j)).time = ((showInfo)show.get(i)).time;
((showInfo)show.get(j)).day = ((showInfo)show.get(i)).day;
((showInfo)show.get(j)).name = ((showInfo)show.get(i)).name;
((showInfo)show.get(i)).time = temp.time;
((showInfo)show.get(i)).day = temp.day;
((showInfo)show.get(i)).name = temp.name;
}
}
}
Any help would be great! Thanks in advance. :)
(PS. I'm aware I need to change "showInfo" to "ShowInfo", but I'll do it when I'm finished.)
One problem with your code is that you are comparing show.get(i) with show.get(i+1) but then swapping show.get(i) with show.get(j). You should be comparing to show.get(j). Also, the inner loop should go to j < show.size() rather than show.size() - 1. Finally, you can start the inner loop at i + 1 instead of at 0.
Once you determine that you need to swap, you can do much better by simply swapping references in the list, rather than swapping each field:
showInfo tmp = (showInfo)show.get(i);
show.set(i, show.get(j));
show.set(j, tmp);
I assume show is a List and you have to sort by name.
First, make showInfo implement Comparable:
public class showInfo implements Comparable
{
String name;
String day;
int time;
public int compareTo(Object o)
{
showInfo other = (showInfo) o;
return name.compareTo(other.name);
}
}
Then, use `Collections.sort()' on the list:
Collections.sort(show);
You can do something like this....
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class myComparator implements Comparator {
public int compare(Object o1, Object o2) {
return ((o1.toString().charAt(0) > o2.toString().charAt(0)) ? 1 : (o1
.toString().charAt(0) == o2.toString().charAt(0)) ? 0 : -1);
}
}
public class Sample {
/**
* #param args
*/
public static void main(String[] args) {
List l = new ArrayList();
l.add("hello");
l.add("abc");
l.add("World");
l.add("hi");
System.out.println("Before sorting");
for (Object i : l) {
System.out.println(i.toString());
}
Collections.sort(l, new myComparator());
System.out.println("After sorting");
for (Object i : l) {
System.out.println(i.toString());
}
}
}
You are incorrectly using i here :
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(i+1)).name) > 0){
I believe the second i should be j to achieve bubble sort
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(j+1)).name) > 0){
Not sure if this is what you look for, it uses casting insteads of generics, anyway, i hope this will help
pastebin
I am trying to go through a list of names with amounts.
One array has the name of the person , the other has the amount the person gave i.e. john, 55 sally 40 john 33 sarah 55.
My objective is to total the like names and print out the name of the person and the total amount that was given.
John gave twice so he should total 88. But I am getting the total right but my program is printing the name twice. So john 88 is printing twice... I know its likely because I put it in the first for loop its iterating the entire length of the array.
But I am unsure how to solve this?
import java.util.*;
public class chapterfive {
public static void main (String[]args) {
Scanner in = new Scanner (System.in);
String[]names = new String[4];
int[] scores = new int[4];
for (int i = 0; i<names.length; i++) {
names[i] = in.next();
scores[i] = in.nextInt();
}
int amount = 0;
String firstname = "";
for (int i = 0; i < names.length; i++) {
for (int j=0; j < names.length; j++) {
if (names[j].equals(names[i]))
amount += scores[j];
}
System.out.println(names[i] + " " + amount);
amount = 0;
}
}
}
You can see that they have a relationship like Name -> Score , so if you think more abstract this is a dictionary with Key (Name) and Value (Score) , so you can use another data-structure like a Map or you can use an array and make a class Person , have the arrayOrderer and when you add a new person check if that person exist in the array..
Example :
Map <String , Integer> people = new HashMap<>();
for (int i=0; i<lengthYouWant; i++)
{
String name=in.next();
int score=in.nextInt();
if(people.contains(name)){
score= people.get(name)+score;
}
people.put(name,score);
}
Should be using a Map to simplify things, rather than keeping track of two arrays. But heres a fix that may work (haven't tested it)
String firstname = "";
for (int i = 0; i < names.length; i++) {
int amount = 0;
boolean skip = false;
for (int j=0; j < names.length; j++) {
//need to skip because we have already processed it
if(names[j].equals(names[i]) && i > j) {
skip = true;
break;
}
else if (names[j].equals(names[i])) {
amount += scores[j];
}
}
if(!skip) {
System.out.println(names[i] + " " + amount);
}
}
If you make an array or list of the Person class you can implement Comparable and add a method to help in sorting.
Java is an object-oriented language, which means, among other things, that you can make your own data structures. Using parallel arrays is error prone, and it separates data you want to keep together. So, what do you need to organize this?
First is a way of storing a name and an amount. Call it Donation.
class Donation {
private final String name;
private final int amount;
public Donation(String name, String amount) {
this.name = name;
this.amount = amount;
// EXERCISE: Add error checking.
}
public String getName() { return name; }
public int getAmount() { return amount; }
public String toString() {
return "Name: " + name +", amount: " + amount;
}
}
Notice that this class's variables are final; they can't be changed once set. They are set in the constructor, and there are get methods and a toString method that replaces what you have in your System.out.println statement.
Next, you need a way of storing the data. Don't use arrays. Lists are more flexible.
private static List<Donation> donations = new ArrayList<Donation>();
// and in main:
while (true) {
String name = null;
int amount = 0;
if (in.hasNext()) {
name = in.next();
} else {
break;
}
if (in.hasNextInt()) {
amount = in.nextInt();
} else {
break;
}
donations.add(new Donation(name, amount));
} See -- no 4s.
Next, you need to consolidate the repeated donations. I mean, some people give to their church every Sunday. We'll use the appropriate structure, a Map.
// Also in main:
Map<String, Integer> totals = new HashMap<>();
for(Donation d: donations) {
String name = d.getName();
int amount = d.getAmount();
if (!totals.containsKey(name)) {
totals.put(name, 0);
}
int currentDonation = totals.get(name);
totals.put(name, currentDonation + amount);
}
And then finally, you iterate through the map and print each entry.
for ( Map.Entry<String, Integer> entry: totals.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
And now, another exercise and strategy: stop doing everything in main. Give your ChapterFive class instance variables and methods. Then, write tests for these. Try to find improvements to what I suggested. Then, see if there are libraries that can help you.