Comparing objects inside an Array for Sorting - java

I have been trying to compare objects in an Array by one if its properties so that I can sort the objects in the Array into a descending order. Here is the sample code: The array is Candidate[][]
System.out.println("How many positions for this election? > ");
numberOfPositions = sc.nextInt();
Candidate Candidate[][] = new Candidate[numberOfPositions][];
PoliticalParty Parties[][] = new PoliticalParty[numberOfPositions][];
for(int i=0;i<numberOfPositions;i++){
String name;
String politicalParty;
System.out.println("Enter position name > ");
position = sc.next();
System.out.println("How many seats? > ");
numberOfSeats = sc.nextInt();
System.out.println("How many candidates? > ");
numberOfCandidates = sc.nextInt();
Candidate[i] = new Candidate[numberOfCandidates+1];
Candidate[i].sort(votes); //<--------------------------This is what im trying//
Wherein (votes) is an int derived from a text file using this code:
System.out.println("Enter file name > ");
filename = sc.next();
try {
filescan = new Scanner(new File(filename));
} catch (FileNotFoundException ex) {
//Logger.getLogger(Election.class.getName()).log(Level.SEVERE, null, ex);
}
String L = System.lineSeparator();
filescan.useDelimiter(L);
while (filescan.hasNext()) {
numberOfVoters++;
line = filescan.next();
for(int x=0,j=0;j<line.length();j++){
switch(line.charAt(j)){
case ',':
x++;
break;
case ' ':
break;
default:
int y = line.charAt(j)-48;
//Integer.parseInt(line.charAt(j).toString());
Candidate[x][y].addVote();
break;
}
}
Wherein (vote) is encapsulated in another Class:
public class Candidate{
int votes = 0;
String politicalParty;
public Candidate(String name, String politicalParty) {
super(name);
this.politicalParty = politicalParty;
}
public void addVote() {
this.votes++;
//return votes;
}
public int getVotes() {
return votes;
}
#Override
public String getName() {
return getName();
}
public void displayFields(){
System.out.println(this.getName() + " (" + getPoliticalParty() + ") - " + votes);
}
public String getPoliticalParty() {
return politicalParty;
}
public void setPoliticalParty(String politicalParty) {
this.politicalParty = politicalParty;
}
}

Arrays have a premade sort method. The Javadoc for Arrays.sort(Object[] a) mentions a "natural ordering". The Comparable interface exists to provide the natural order.
Step 1
Apply the interface to your class.
public class Candidate implements Comparable<Candidate> {
Step 2
Implement the compareTo(Candidate c) {} method in your class.
Read the Javadoc for compareTo() contract. In general, it must return a positive, zero, or negative number if this.property is greater than, equal to, or less than c.property, respectively. property is the field upon which you are comparing.
Tip: If property is a String, you can simply reuse String's compareTo()
return this.property.compareto(c.property);
Tip: If property is an integer (like votes), you can cleverly create a positive, zero, or negative number by taking the difference.
return this.votes - c.votes;
Step 3
Sort your array.
Now that your object is comparable, call Collections.sort(list) if you have a Collection or Arrays.sort(list) you have an Array of objects.

I recommend you to use an ArrayList to store the elements to be sorted and then you'll have 2 options: make your items Comparable (interface) or create a Comparator (interface):
public class Candidate implements Comparable<Candidate> {
...
public int compareTo(Candidate c) {
... //compare here the attributes of this and c
}
}

Quick question, short answer: java.util.Arrays.sort()

Why your variable starts from capital letter? It should be like all variables from small.
You should use collections for storing custom data types, then you can easy sort it using Collections.sort(List<T> list, Comparator<? super T> c) and define your own Comparator whatever you want.

Related

Move an element up in the list using Comparator

I have an ArrayList in Java :
{"PatMic", "PatientDoc", "Phram", "Patnet", "PatientA"}
All the elements have a number assigned : PatMic = 20, PatientDoc = 30, Phram = 40, Patnet = 50, PatientA = 60.
And my current Comparator :
Comparator<String> comparator = new Comparator<String>() {
#Override
public int compare(final String o1, final String o2) {
final int numbr1 = getElementNumber(); //Returns element's number in a list
final int numbr2 = getElementNumber();
if (numbr1 > numbr2 ) {
return 1;
} else if (numbr1 < numbr2 ) {
return -1;
}
return 0;
}
};
Collections.sort(strings, comparator);
I do not want to change the assigned numbers to each element but would want to move the element PatientA in between PatMic and PatientDoc so the modified list should look like :
{"PatMic", "PatientA" "PatientDoc", "Phram", "Patnet"}
Could someone please suggest how to achieve this? I tried many ways to modify the existing Comparator logic but in vain. Thank you.
You are trying to sort based on some inherent value associated with a String. Therefore, sorting on a String itself is probably not correct. What you probably want to use is either a custom object (implement equals, hashCode and the interface Comparable), or an enum type. This will allow you to change the internal state of these objects explicitly, which will manifest itself naturally when using a Comparator. For example, using a class:
class MyClass implements Comparable
{
private String name;
private int value;
//Constructor
public MyClass(String s, int v)
{
name = s;
value = v;
}
//Getters and setters
//Implement comparing method
}
Then you can use these objects in place of your Strings:
//...
MyClass patMic = new MyClass("PatMic", 20);
// So on..
First, you should give you comparator sufficient knowledge about what it should do. I mean you should have some data available to comparator that says something like "okay, sort them all by associated number except this one - place it right here". "Right here" could be anything that points exact position, I gonna choose "before that element".
So here we go
public void sortWithException(List<String> data, final Map<String, Integer> numbers, final String element, final String next) {
Collections.sort(data, new Comparator<String>() {
#Override
public int compare(String first, String second) {
if (first.equals(element) || second.equals(element)) { //the exception
Integer nextNumber = numbers.get(next);
Integer firstNumber = numbers.get(first);
Integer secondNumber = numbers.get(second);
if (first.equals(element)) {
if (next == null) // placing the exception after ANY element
return 1;
return secondNumber >= nextNumber ? -1 : 1; //placing the element before next and after all next's predecessors
} else { // second.equals(element)
if (next == null)
return -1;
return firstNumber >= nextNumber ? 1 : -1;
}
} else { //normal sort
return numbers.get(first) - numbers.get(second);
}
}
});
}
and call it like sortWithException(data, numbers, "PatientA", "PatientDoc")
Note that i used Map for associated numbers, you should probably use your own method to get those numbers.

Sorting an array list with a delimiter

I have been stuck on this problem for so long and i have no idea what to do.
Basically i have a text file with people names then student number then prize money like this:
Green%3243%1000
Kevin%7657%400
Frank%345%10000
Bob%5435%5000
Stefan%31231%1000
Javis%4532%100
IronMan%5435%2000
Lamp%534%3000
What i want to be able to do is sort the array based on the last number.
I tried this abomination (Don't bother reading it its garbage):
boolean flag = true;
String temp;
int temp1;
int temp2;
while (flag){
flag = false;
for(int j=0; j < list.size() -1; j++ ){
System.out.println(list.get(j));
Scanner s = new Scanner(list.get(j)).useDelimiter("%");
s.next();
s.next();
temp1 = s.nextInt();
Scanner s2 = new Scanner(list.get(j+1)).useDelimiter("%");
s2.next();
s2.next();
temp2 = s2.nextInt();
if (temp1 < temp2){
temp = list.get(j);
list.add(j, list.get(j+1));
list.add(j+1,temp);
flag = true;
}
}
}
But its just infinitely looping. My though while making it was just patching array lists into a bubble sort.
If anyone has any ideas and is willing to share them it will be greatly appreciated.
Java is an object-oriented language, so I'll just use objects:
Create a Student object with the three values you want to store (and a toString() method to print them separated by "%":
public class Student {
private final String name;
private final int number;
private final int prizeMoney;
public Student(final String name, final int number, final int prizeMoney) {
this.name = name;
this.number = number;
this.prizeMoney = prizeMoney;
}
#Override
public String toString() {
return name+"%"+number+"%"+prizeMoney;
}
public int getPrizeMoney() {
return prizeMoney;
}
}
Read your lines as Student objects, and store them in a List:
final Scanner scan = new Scanner(new File("/path/to/StudentsList"));
final List<Student> students = new ArrayList<Student>();
while (scan.hasNextLine()) {
final Scanner line = new Scanner(scan.nextLine());
line.useDelimiter("%");
students.add(new Student(line.next(), line.nextInt(), line.nextInt()));
line.close();
}
scan.close();
Order the List with a custom Comparator, and print it:
students.sort(new Comparator<Student>() {
#Override
public int compare(final Student s1, final Student s2) {
return s1.getPrizeMoney()-s2.getPrizeMoney();
}
});
for (final Student student: students)
System.out.println(student);
Output:
Javis%4532%100
Kevin%7657%400
Green%3243%1000
Stefan%31231%1000
IronMan%5435%2000
Lamp%534%3000
Bob%5435%5000
Frank%345%10000
Here's something for you to get head started.
Create a map for prize money => line as key/value pair
Read each line in the file, parse it and put key/value pair in the above map
Once your map is ready, convert the keys entry set into the collections like list
Sort the collections, using Collections.sort()
Iterate over the created map, and for each value in the collection get the corresponding value from the map.
Hope this helps you to get the workflow.
Id consider creating a 3d array here 8x8x8 from right to left in the array is row, col, and in so [0][0][1] is block one or kevin [0][1][1] is 7657 [1][1][1] is 400. I like this way because not only does it give each 'item' an array it allows you to keep it organized and easily accessable

compareTo method for ordering integers

I'm having a difficult time creating a compareTo() method for my program. My program reads 5 pairs of String/Integers from the commandline. They will represent names and ages for a Person object.
For instance my commandline arguments are: Asia 19 Java 20 Html 25 CSS 18 Ruby 10
My goal is to display them in a dialog box rearranged from smallest to biggest number.
*The problem I need help with is with my compareTo() method. I'm kinda of stuck at this point, as I just don't think I understand the concept of using this method. If someone can give me a informative explanation that would be awesome!
My code:
// To display dialog box(s)
import javax.swing.JOptionPane;
//An interface used to compare two objects.
import java.lang.Comparable;
public class searchSort{
public static void main(String[] args){
if (args.length != 10){
System.out.println("Please enter 5 String/Intger pairs " +
"on the commandline");
}
else{
int age1 = new Integer(0);
int age2 = new Integer(0);
int age3 = new Integer(0);
int age4 = new Integer(0);
int age5 = new Integer(0);
try{
age1 = Integer.parseInt(args[1]);
age2 = Integer.parseInt(args[3]);
age3 = Integer.parseInt(args[5]);
age4 = Integer.parseInt(args[7]);
age5 = Integer.parseInt(args[9]);
}
catch (NumberFormatException exception) {
System.out.println("Error: Commandline arguments 2,4,6,8,10 must be a positive integer.");
System.exit(0); // end program
}
Person[] arr = new Person[5];
arr[0] = new Person(args[0], age1);
arr[1] = new Person(args[2], age2);
arr[2] = new Person(args[4], age3);
arr[3] = new Person(args[6], age4);
arr[4] = new Person(args[8], age5);
JOptionPane.showMessageDialog(null, arr[0]+ "\n" +arr[1]+ "\n"+arr[2]+ "\n"+
arr[3] + "\n" + arr[4]);
//
}
}
}
class Person implements Comparable{
// Data Fields
protected String name;
protected int age;
// Constructor
public Person(String n1, int a1){
name = n1;
age = a1;
}
//toString() method
public String toString(){
String output = name + " is " + age + " years old.";
return output;
}
//getAge() method
public int getAge(){
return age;
}
// compareTo() method
public int compareTo(Object object) throws ClassCastException{
int person1 = this.getAge();
int person2 = object.getAge();
int result = this.getAge() - object.getAge();
return result;
}
}
Your code won't compile, because you're using an Object as a Person. You need to cast it:
public int compareTo(Object object) throws ClassCastException{
return age - ((Person)object).age;
}
And you only need one line, and you can access fields directly.
The contract for the compareTo(Object obj) method demands that you return:
n < 0 if this is to be considered less than obj
0 if this is equal to obj
n > 0 if this is greater than obj
This way you can define sorting behavior for your class.
Arrays.sort(people);
Note that you can sort your objects backwards by just inverting the sign of the return value.
As a side note, some sorting methods allow you to pass a Comparator along with the collection you want to sort, which enables you to define a different sort criterion other than the default one.
Arrays.sort(people, new Comparator<Person>() { ... });
What the Comparable enables is for you to sort Person objects when they're in a container object like a List or an Array.
I suggest looking at the Arrays and Collections classes for how to do this.

How to sort three arrays in java?

I have three arrays in my proggramme Surname, Forename and result and need to create a sort array
Surname: Chris Forename: Charleton: Result: 54
Surname: Annett: forename: Lyle: result 67
If I wanted to sort it by alphabetical of last name, i need all the fields to move, instead of just the surname. This is the bubble sort code i'm working off
int swap;
boolean swapflag = true;
//outer loop
while (swapflag == true)
{
swapflag = false;
//inner loop
for (int index=0; index < (nums.length - 1); index++)
{
//swap routine
if (nums[index]> nums[index + 1])
{ //swap routine
swap = nums[index];
nums[index] = nums[index + 1];
nums[index + 1] = swap;
swapflag = true;
}
}//end inner
}//end outer
System.out.println ("\nArray Contents after sorting"
+ "\n*************");
for (int index=0; index < nums.length; index ++)
{
System.out.println("Array element "
+ index + ": " + nums[index]);
}
}
}
` package projStudent;
import java.util.Scanner;
public class UnitResults
{
//delcare Scanner as keyb
static Scanner keyb = new Scanner (System.in);
//declare fields
static String studentForename [];
static String studentSurname [];
static int [] studentResult;
static int pointer;
//constructor
UnitResults(int sizeofclass)
{//start of constructor
studentForename = new String [sizeofclass];
studentSurname = new String [sizeofclass];
studentResult = new int [sizeofclass];
pointer = 0;
}//end of constructor
public boolean add(String studentForename[], String studentSurname[],
int studentResult[])
{//start of add method
if (pointer == studentResult.length )
{//start of if statement
System.out.println("Sorry Array is full");
return false;
studentResult[pointer] = studentResult[];
pointer ++;
}//end of if statement
}//end of add method
public boolean delete(int element)
{//start of delete method
element = element - 1;
if ((element >= 0) && ( element < pointer))
{//start of if statement
for(int index = (element + 1); index < pointer; index++)
{//start of for statement
studentResult[index - 1] = studentResult[index];
}//end of for statement
pointer--;
return true;
}//end of if statement
else
{//start of else statement
return false;
}//end of else statement
}//end of delete method
public String find()
{//start of display
String strOutput="";
strOutput = strOutput + "Students";
if (pointer==0)
{//start of if statement
strOutput = strOutput + "There are no records in this Array";
return strOutput;
}//end of if statement
for (int index=0; index < pointer; index++)
{//start of for method
strOutput = strOutput + "Student Name" + studentSurname[index] + studentForename +
"Student Result" + studentResult +"\n";
}//end of for method
return strOutput;
}//display
public int sort (int UnitResults)
{//start of sort
int sort;
boolean swapflag = true;
while (swapflag == true)
{//start of while loop
swapflag = false;
for (int index=0; index < (UnitResults - 1); index++)
{
if (studentResult[index]> studentResult[index + 1])
{ //swap routine
sort = studentResult[index];
studentResult[index] = studentResult[index + 1];
studentResult[index + 1] = sort;
swapflag = true;
}
}
}//end of while loop
}//end of sort
}`
Unfortunately, your post is confusing as you don't include some things, like just what is the current array you are sorting. Still, if I understand your question correctly...
Regardless of the language, your strategy would involve changes to how you swap the elements. If your array consists of composite data, then simply assigning in a swap is fine. If your data is scattered, then your swap needs to swap each variable. You can always just sort the indices of the array into another array, then use that array to indirectly reference the first, for sorted access.
I would suggest you use an List for this purpose.
First create an object. For example "Person" containing members for "Forname","Surename","Result". Then fill the list with these objects, implement the Interface Compareable and use the Collection.sort() methode.
class Person implements Comparable<Person>
{
private String forname;
private String surname;
private int rating;
public Person(String forename, String surname, int rating)
{
this.forname = forename;
this.surname = surname;
this.rating = rating
}
public int compareTo(Person p) {
if(p.rating == this.rating)
return 0;
else if(p.rating < this.rating)
return -1;
return 1;
}
}
class Test{
public static void main(String[] args){
List<Person> personList = new ArrayList<Person>();
Person p1 = new Person("John","Smith",10);
Person p2 = new Person("Max","Muster",20);
Person p3 = new Person("Sarah","Clark",15);
personList.add(p1);
personList.add(p2);
personList.add(p3);
personList.sort();
}
}
There are a number of features of the Java programming languages that can help you resolve the problem that you are having, the first of which is inclusion of appropriate data structures and methods with which to manipulate objects within those data structures.
First and foremost, I'd recommend using a java class to represent a single person entity... think about it, when you look up a person's information, you don't consult three separate books, or computer screens, or what have you, when all that information can be organized into one place. For your person above, for example, you could use something like this:
public class Person implements Comparable<Person> {
public String firstName;
public String lastName;
public int result;
public Person(String fn, String ln, int r) {
firstName = fn;
lastName = ln;
result = r;
}
public int compareTo(Person otherPerson) {
return lastName.compareTo(otherPerson.lastName);
}
}
This will give you an object that will store all of your person information, and by default will be easily sortable by last name (you can change this behavior with a comparator, which I won't cover here.)
Now instead of having three different arrays of first names, last names, and results, you can have a single array of Persons. There ARE actually sorting mechanisms within the java language for arrays already, which you can research and use if you choose, but if you'd like to use your own sort, you would just need to replace your swap conditional with something like this:
if(persons[index].compareTo(persons[index+1]) > 0) {
...
}
i just want ask you
why instead creating class student ie
class Student{
private String studentForename;
private String studentSurname;
private int studentResult;
//setters and getters
}
and put them in some collection ie List
you are putting them into 3 different arrays?
do you realize, if you have them nicely in the list, you can sort them just by using Collections.sort() ?
Can't understand properly the question: are you looking for a way to manually implement a sorting algorithm (bubble, quick or whatever) or you would like to simply sort them the best you can? Generally speaking you should never implement your own sort 'cause Java provides itself a very efficient lot... or is this an exercise? Probably :)
Best way I can imagine is, provided the 3 arrays in their original form are linked by index, create a surname/index map, load it form surname array, sort the Map.Entry by key and then you will have the array indexes sorted the way you wanted. Check here for more details: how to sort Map values by key in Java
PS The solutions provided by the others are correct and preferrable if you are NOT doing an exercise :) Better deal with a structured object than with 3 separated data.

I can't figure out comparator

I'm trying to sort an arraylist but I can't wrap my head around the comparator. I don't understand how to define sortable fields from my arraylist which is created from a text file. Furthermore I'm unsure of the comparator logic. It seems to me like create a set of comparator functions, and then later invoke them. Is this true?
So far my code looks like this:
public class coord implements Comparator<Sort> {
private int index;
private int index2;
private double dista;
}
public class Sort {
List<Sort> coords = new ArrayList<Sort>();
public static void main(String[] args) throws Exception {
ArrayList dist = new ArrayList();
File file = new File("2.txt");
FileWriter writer = new FileWriter("2c.txt");
try {
Scanner scanner = new Scanner(file).useDelimiter("\\s+");
while (scanner.hasNextLine())
{
int index = scanner.nextInt();
int index2 = scanner.nextInt();
double dista = scanner.nextDouble();
System.out.println(index + " " + index2 + " " + dista);
}
}
}
public class EmpSort {
static final Comparator<coord> SENIORITY_ORDER =
new Comparator<coord>() {
public int compare(coord e1, coord e2) {
return e2.index().compareTo(e1.index());
}
};
static final Collection<coord> coords = ;
public static void main(String[] args) {
List<Sorted>e = new ArrayList<Sorted>(coords);
Collections.sort(e, SENIORITY_ORDER);
System.out.println(e);
I appreciate any help anyone can give.
Comparator logic is simple. When you sort an array of elements you have two choices - sort using the Comparable on each element (assuming there is one) or supply a Comparator. If your array contains complex elements or there are different sort criteria then the latter choice is probably what you need to use.
Each time the comparator is called you must say if element 1 is "less than" element 2 in which case return a negative number, element 1 is "greater than" element 3 in which case return a positive number. Otherwise if elements are equal return 0. You may also do reference and null comparison before comparing values so that null elements are logically "less than" non-null elements and so on.
If elements are "equal" then you may wish to sort by a secondary field and then a third field and keep going until the sort order is unambiguous.
A simple comparator for a class Complex which has fields a & b and we want to sort on a:
class Complex {
public String a = "";
public String b = "";
}
//...
Collections.sort(someList, new Comparator<Complex>() {
public int compare(Complex e1, Complex e2) {
if (e1 == e2) {
// Refs could be null or equal
return 0;
}
if (e1 == null && e2 != null) {
return -1;
}
if (e2 == null && e1 != null) {
return 1;
}
if (e1.a == e2.a) {
return 0;
}
if (e1.a == null && e2.a != null) {
return -1;
}
if (e1.a != null && e2.a == null) {
return 1;
}
// Just use the Comparable on the fields
return e1.a.compareTo(e2.a);
}
});

Categories