Java - How to implement functions in a heap-based priority queue - java

For a programming assignment, I have been working on creating a program that reads an input file and sorts the data inside using a self-made max heap priority queue. The data file has lines that either read "insert [a name] [a number]", or "remove". For this priority queue, we need to make a function for inserting and removing objects. Each object in the queue contains the name as a string, and the priority as a integer. I have to implement this heap based on an array with a size of 255.
My question is, I'm having difficulty implementing my insert and remove functions to work as specified. I'll provide 1) how they need to work, 2) pseudocode I've made, and 3) the actual Java code I've implemented. Both of my functions do not work exactly as I intend for them to, so I could use some direction from more experienced programmers.
1) insert(name, priority): this function should take a name of type string and a priority of type integer, and inserts them into the priority queue.
remove(): this function should remove the object with the highest priority value and return the name string from the object.
2) As background, I have three classes for this program: First, the "main" class containing implementation for reading the file and using the functions. Second, the "name" class, which creates the name object containing the name string and priority int , a constructor, and a compareTo method for comparing the priority values of two objects. Third, the "priorityqueue" class, contains the insert and remove functions. Now, here is the pseudocode I made for those two functions:
insert:
Check if the array is full (when num = 255), throw if true
Create the object from the input file with a name string and priority int
Insert the object at num
Use a while loop to swap the two objects at insertion
Update num (num++)
remove:
Save the first object
Move the last object to the first
Update num (num--)
Use a while loop to determine the larger child and return it.
3) Here is the code I have so far. I'll provide my name and priority queue classes, in case my name class is what's giving me trouble.
Priority Queue class:
public class PriorityQueue
{
int num; //amount of things in array
int idx; //index of current name object
Name[] names = new Name[255];
public void insert(String name, int priority)
{
while (num != 255)
{
Name addName = new Name(name, priority);
names[num] = addName;
num++;
while(idx != 0 || names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp;
idx = (idx-1)/2;
}
}
}
public Name remove()
{
Name temp2 = names[0];
//Save first element
names[0] = names[idx];
//Move last element to first
num--;
while(idx < Math.max(2*idx+1,2*idx+2))
{
if(names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp3 = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp3;
}
}
return temp2;
}
}
Name class:
public class Name implements Comparable
{
String name;
int priority;
public Name(String n, int i)
{
name = n;
priority = i;
}
public boolean CompareTo(Name obj)
{
if(priority < obj.priority)
{
return false;
}
else if(priority > obj.priority)
{
return true;
}
return true;
}
}
I appreciate any help. Thanks!

Several problems. First, in your insert method:
public void insert(String name, int priority)
{
while (num != 255)
{
Name addName = new Name(name, priority);
names[num] = addName;
num++;
while(idx != 0 || names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp;
idx = (idx-1)/2;
}
}
}
The while (num != 255) shouldn't be there. You should check to see if num == 255, and throw an exception if it is.
Then, you need to initialize idx. That is:
Name addName = new Name(name, priority);
names[num] = addName;
idx = num;
num++;
And your while condition should use && rather than ||. Otherwise you'll do the swap every time idx is not equal to 0.
In your remove method:
public Name remove()
{
Name temp2 = names[0];
//Save first element
names[0] = names[idx];
//Move last element to first
num--;
while(idx < Math.max(2*idx+1,2*idx+2))
{
if(names[idx].CompareTo(names[(idx-1)/2]) > 0)
{
Name temp3 = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp3;
}
}
return temp2;
}
You don't want names[idx] there, because you don't know what idx is. You want:
names[0] = names[num-1]; // get last item in the heap
Your while condition here is goofy. Math.max(2*idx+1,2*idx+2) will always return 2*idx+2, unless idx is negative. And, again, you haven't even initialized idx. What you want here is:
idx = 0;
while (idx < num)
Now, what you're trying to do is see if names[idx] is smaller than either of its children. And, if so, select the largest of the two children to swap it with. So:
while (idx < num)
{
int largestChild = idx*2+1;
if (largestChild >= num) break; // idx is at a leaf level
if (largestChild+1 < num)
{
// compare the two children
if (names[largestChild].compareTo(names[largestChild+1]) < 0)
{
largestChild = largestChild+1;
}
}
if (names[idx] < names[largestChild])
{
// swap, moving the item down
temp = names[idx];
names[idx] = names[largestChild];
names[largestChild] = temp;
idx = largestChild;
}
else
{
// item is in the proper place
break;
}
}
I would suggest making idx a method-scoped variable in both methods. There's no need for it to be a global, and making it local to the methods forces you to initialize it before you use it, rather than potentially (as in your existing code) using a stale value.
I think you need to change your Name class's CompareTo function. The Comparable compareTo function must return:
a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
So you should have:
public boolean CompareTo(Name obj)
{
if(priority < obj.priority)
{
return -1;
}
if (priority > obj.priority)
{
return 1;
}
return 0;
}

Related

Bubble Sort objects

I need to sort my grocery inventory by name by using bubble sort.
Apparently, my code is not sorting the list by name.
BTW, the data stored inventory comes from a file input.
Here is my code.
public void sortInventoryByName() {
//TODO: use bubble sort and compareTo
int n = inventory.size();
GroceryItem temp;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (inventory.get(j).compareTo(inventory.get(j + 1)) > 0) {
temp = inventory.get(i);
inventory.set(i, inventory.get(i + 1));
inventory.set(i + 1, temp);
}
}
}
}
Here is my compareTo method from my superclass (GroceryItem)
#Override
public int compareTo(Object o) {
if(getClass() != o.getClass()) {
throw new IllegalArgumentException();
}
else {
GroceryItem other = (GroceryItem) o;
return (this.name.compareTo(other.name));
}
}
Looks like you have some mismatch for comparing the right values.
There are two ways of implementing a bubble sort algorithm with two for loops.
Below made the first loop incremented barrier variable and second is decrementing index.
Thus with every iteration of the outer loop, the lowest value will be moved to the first place (like the smallest bubble will be moved first). The next iteration will skip this first element. And it will last till the list full list will be over.
Your example shows opposite behaviour -> with every iteration for the outer loop the highest element in a list is moved to the end.
It isn't so important how exactly do you want to iterate the inner for loop. The final sorted result is our aim.
Code snippet:
public void sortInventoryByName() {
int n = inventory.size();
for (int barrier = 0; barrier < n - 1; barrier++) {
for (int index = n - 2; index >= barrier; index--) {
if (inventory.get(index).compareTo(inventory.get(index + 1)) > 0) {
GroceryItem temp = inventory.get(index);
inventory.set(index, inventory.get(index + 1));
inventory.set(index + 1, temp);
}
}
}
}
Your implementation of compareTo() should work fine. So, inventory list should be sorted correctly.
A few notices according to your code:
you don't need to declare temp variable outside of loops. It is just a temporary variable for swapping two values. Inline declaration and usage will be enough.
would suggest adding more meaningful names for loop variables instead of just i and j. It increases code readability and understanding in the future
else block is redundant at compareTo()
#Override
public int compareTo(Object o) {
if (getClass() != o.getClass()) {
throw new IllegalArgumentException();
}
GroceryItem other = (GroceryItem) o;
return this.name.compareTo(other.name);
}
I filled in the missing parts of your code. You should read How do I ask a good question and also the link to How to create a Minimal, Reproducible Example.
The below code is the GroceryItem class which only contains a single member, i.e. name, which is the name of the grocery item. Since your question only deals with manipulating this member, I did not try to guess what other data the class needs.
Explanations after the code.
import java.util.ArrayList;
import java.util.List;
public class GroceryItem implements Comparable<GroceryItem> {
private String name;
public GroceryItem(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override // java.lang.Comparable
public int compareTo(GroceryItem other) {
if (other == null) {
return 1;
}
else {
String otherName = other.getName();
if (name == null) {
if (otherName == null) {
return 0;
}
else {
return -1;
}
}
else {
if (otherName == null) {
return 1;
}
else {
return name.compareTo(otherName);
}
}
}
}
#Override // java.lang.Object
public boolean equals(Object other) {
boolean equal = false;
if (other instanceof GroceryItem) {
GroceryItem otherItem = (GroceryItem) other;
if (name == null) {
equal = otherItem.getName() == null;
}
else {
equal = name.equals(otherItem.getName());
}
}
return equal;
}
#Override // java.lang.Object
public int hashCode() {
return name == null ? 0 : name.hashCode();
}
#Override // java.lang.Object
public String toString() {
return name;
}
public static void main(String[] args) {
List<GroceryItem> inventory = new ArrayList<>();
inventory.add(new GroceryItem("apple"));
inventory.add(new GroceryItem("pear"));
inventory.add(new GroceryItem("banana"));
inventory.add(new GroceryItem("orange"));
inventory.add(new GroceryItem("beetroot"));
inventory.add(new GroceryItem("onion"));
inventory.add(new GroceryItem("lettuce"));
inventory.add(new GroceryItem("carrot"));
inventory.add(new GroceryItem("guava"));
inventory.add(new GroceryItem("lychee"));
inventory.add(new GroceryItem("kiwi"));
int n = inventory.size();
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (inventory.get(j).compareTo(inventory.get(j+1)) > 0) {
// swap inventory[j+1] and inventory[j]
GroceryItem temp = inventory.get(j);
inventory.set(j, inventory.get(j+1));
inventory.set(j+1, temp);
}
}
}
System.out.println();
}
}
The above code creates a List of GroceryItem objects that contains eleven elements. After populating the List, the bubble sort is performed in the two, nested for loops. Finally the sorted List is printed.
Note that class GroceryItem also implements method toString() so as to make the output human-readable when printing an instance of GroceryItem.
If, in future, you need to use GroceryItem as the key for a java.util.HashMap, then GroceryItem will need to override method hashCode() and if a class overrides method hashCode() then it should also override method equals(). Hence that is why the above code includes those overridden methods. Note that none of those methods – equals(), hashCode() and toString() – are required for the bubble sort.
The oputput when running the above code is:
[apple, banana, beetroot, carrot, guava, kiwi, lettuce, lychee, onion, orange, pear]

how to input values into ArrayList alphabetically

I'm given the task of adding a value into an ArrayList alphabetically (by lastname first, and firstname if lastnames are the same),I'm not allowed to sort the ArrayList once all the inputs are given. What I am suppose to do is determine the location of where the value should be each time an input is given and place it there. Example values: Inputs are {John Doe, Bryan Sully, Harry Ache, Ali Doe, Bry Dyre} , Output should be {Harry Ache, Ali Doe, John Doe, Bry Dyre, Bryan Sully}. However, in cases where there are two of the same last names, what will occur is {Harry Ache, Ali Doe, Bry Dyre, John Doe, Bryan Sully}, why?
ArrayList<Person> list = new ArrayList<Person>();
public void addPerson(Person p){
if(list.size() == 0){
list.add(p);
} else{
for(Person pp: list){
int getIndex = list.indexOf(pp);
int lOrder = p.getLastName().compareTo(pp.getLastName());
if(lOrder > 0){
list.add(getIndex + 1, p);
break;
} else if(lOrder == 0){
int fOrder = p.getFirstName().compareTo(pp.getFirstName());
if(fOrder > 0){
list.add(getIndex, p);
break;
} else {
list.add(getIndex + 1, p);
break;
}
} else {
list.add(getIndex, p);
break;
}
}
}
}
One issue with your code is that you are making an insertion after a single iteration of your loop, inserting Person p only in comparison to the first Person in the list.
Here is an improved implementation:
public void addPerson(Person person) {
if (list.isEmpty()) {
list.add(p);
} else {
// the position where you will insert the Person;
// default value is list.size(), so it can be added to the end
int position = list.size();
Person p;
for (int i = 0; i < list.size(); i++) {
p = list.get(i);
// if the comparison result is > 0, you found the first Person
// in the list that comes alphabetically after;
// Insert person before it, at position i
if (compare(p, person) > 0) {
position = i;
break; // only break now that you've found the insert position
}
}
list.add(person, position);
}
}
/**
* #return 0 if both Persons p1 & p2 have the same names,
* a positive number if p1 is lexicographically greater than p2,
* or a negative number if p1 is lexicographically less than p2
*/
private int compare(Person p1, Person p2) {
int result = p1.getLastName().compareTo(p2.getLastName());
if (result == 0) {
result = p1.getFirstName().compareTo(p2.getFirstName());
}
return result;
}
As others suggested, implementing the Comparable interface in Person if possible can also help create a cleaner implementation.
Few improvements.
You are better off if you can iterate the list using the index like
for(int i = 0; i < array.size(); i++)
You need not have to check for lastName and firstName separately. You can just compare both of them together (p.lastName + p.firstName).compareTo(pp.lastName + pp.firstName) and act upon the result. As you already have the index of the current element, you just have to check if you just insert the new item on the same index or not.
Here is a sample implementation
static void addPerson(Person person) {
for (int i = 0; i < sortedList.size(); i++) {
var existingPerson = sortedList.get(i);
var compareResult = compare(existingPerson, person);
if (compareResult > 0) {
sortedList.add(i, person);
return;
}
}
sortedList.add(person);
}
static int compare(Person p1, Person p2) {
return (p1.lastName + p1.firstName).compareTo(p2.lastName + p2.firstName);
}
The problem with your algorithm, is that you always looking at the first person in the target list, and making decisions solely on that person, notice how all your "branches" have a break statement at the end?
I understand your "reason" for adding all those break statements, those make sure the new person always gets inserted into the list, when it doesn't match, the same reason why your first check if the list is empty.
To properly implement an "insertion sort" system, you actually need to loop over all the indexes of your list.
An simple "insertion sort" algorithm looks like this:
Loop over the target list
Check if existing entry is "bigger" than the newly person
If the existing entry is bigger, we need to move that entry (all all remaining entries) up 1 spot, insert out entry, and abort
If we are done looping, and we didn't abort in the above steps, insert our entry at the end of the list.
ArrayList<Person> list = new ArrayList<Person>();
public void addPerson(Person p){
// Loop
int size = list.size();
for(int getIndex = 0; getIndex < size; getIndex++){
Person pp = list.get(getIndex);
// Compare
int compare = p.getLastName().compareTo(pp.getLastName());
if (compare > 0) {
continue;
} else if(compare == 0) {
if (p.getFirstName().compareTo(pp.getFirstName()) > 0) {
continue;
}
}
// Add in existing slot
list.add(getIndex, p);
return;
}
// Add at the end
list.add(p);
}
One hard part of this, is the fact that we have to compare on 2 things for a single person, this makes the compare logic way harder than it needs to be. This can be solved by factoring this part out to a "helper" comparator that does this logic merging for us:
Comparator<Person> compare = Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName);
// Then, inside the above loop:
...
// Compare
if (compare.compare(p, pp) > 0) {
continue;
}
...

Sort array after deleting value

how can I sort an Array after deleting one value?
e.g. {1,2,3,4,5} --> {1,2,null,4,5} --> {1,2,4,5,null}.
public boolean removeNumber(int accountNumber) {
for(int i = 0; i < Account.length; i++) {
if(Account[i].getAccountNumber() == (accountNumber)) {
Account[i] = null;
}
Since your original array is already sorted, and assuming that only one Account can have that particular accountNumber, there is no need to sort the array again. Just locate the element to remove, then shift everything after that element down one position, and null out the newly-freed element.
I've renamed the Account field to accounts to follow Java naming conventions, to make a clearer distinction between the array (accounts) and the class (Account), both for the future developers looking at the code, and for the Java compiler.
public boolean removeNumber(int accountNumber) {
for (int i = 0; i < accounts.length; i++) {
if (accounts[i].getAccountNumber() == accountNumber) {
System.arraycopy(accounts, i + 1, accounts, i, accounts.length - i - 1);
accounts[accounts.length - 1] = null;
return true; // Found and removed
}
}
return false; // Not found, so nothing removed
}
Now, if you insist on sorting the array, you can do it like this in Java 8+:
Arrays.sort(accounts, Comparator.nullsLast(Comparator.comparing(Account::getAccountNumber)));
You can follow this way to achieve this :
You need to find the accounts that have the accountNumber you're looking for
you set them to null on the array
You sort the array with a custom Comparator :
if an element is null it has to go at the end
if both are not-null you compare their accountNumber
public boolean removeNumber(int accountNumber) {
for (int i = 0; i < Account.length; i++) {
if (Account[i].getAccountNumber() == accountNumber) {
Account[i] = null;
}
}
Arrays.sort(Account, (o, p) -> {
if (o == null)
return 1;
if (p == null)
return -1;
return Integer.compare(o.getAccountNumber(), p.getAccountNumber());
});
return true;
}
Tips :
follow naming conventions : camelCasefor attriutes ==> Account[] becomes account[]
use .equals() when you are comparing object, for an int == is right

How to add an integer to a set while iterating?

I have a set of sets of integers: Set<Set<Integer>>.
I need to add integers to the set of sets as if it were a double array. So add(2,3) would have to add integer 3 to the 2nd set.
I know a set is not very suitable for this operation but it's not my call.
The commented line below clearly does not work but it shows the intention.
My question is how to add an integer to a set while iterating?
If it's necessary to identify each set, how would one do this?
#Override
public void add(int a, int b) {
if (!isValidPair(a, b)) {
throw new IllegalStateException("!isValidPair does not hold for (a,b)");
}
Iterator<Set<Integer>> it = relation.iterator();
int i = 0;
while (it.hasNext() && i <= a) {
//it.next().add(b);
i++;
}
}
One fundamental things you should be aware of, for which makes all existing answer in this question not working:
Once an object is added in a Set (similarly, as key in Map), it is not supposed to change (at least not in aspects that will change its equals() and hashCode()). The "Uniqueness" checking is done only when you add the object into the Set.
For example
Set<Set<Integer>> bigSet = new HashSet<>();
Set<Integer> v1 = new HashSet<>(Arrays.asList(1,2));
bigSet.add(v1);
System.out.println("contains " + bigSet.contains(new HashSet<>(Arrays.asList(1,2)))); // True
v1.add(3);
System.out.println("contains " + bigSet.contains(new HashSet<>(Arrays.asList(1,2)))); // False!!
System.out.println("contains " + bigSet.contains(new HashSet<>(Arrays.asList(1,2,3)))); // False!!
You can see how the set is corrupted. It contains a [1,2,3] but contains() does not work, neither for [1,2] nor [1,2,3].
Another fundamental thing is, your so-called '2nd set' may not make sense. Set implementation like HashSet maintain the values in arbitrary order.
So, with these in mind, what you may do is:
First find the n-th value, and remove it
add the value into the removed value set
re-add the value set.
Something like this (pseudo code again):
int i = 0;
Set<Integer> setToAdd = null;
for (Iterator itr = bigSet.iterator; itr.hasNext(); ++i) {
Set<Integer> s = itr.next();
if (i == inputIndex) {
// remove the set first
itr.remove();
setToAdd = s;
break;
}
}
// update the set and re-add it back
if (setToAdd != null) {
setToAdd.add(inputNumber);
bigSet.add(setToAdd);
}
Use a for-each loop and make your life easier.
public boolean add(int index, int value) {
// because a and b suck as variable names
if (index < 0 || index >= values.size()) {
return false;
}
int iter = 0;
for (Set<Integer> values : relation) {
if (iter++ == index) {
return values.add(value):
}
}
return false;
}
Now all you have to figure out is what to do if relation is unordered, as a Set or a relation are, because in that case a different Set<Integer> could match the same index each time the loop executes.
Use can use Iterators of Guava library like this :
#Override
public void add(int a, int b) {
if (!isValidPair(a, b)) {
throw new IllegalStateException("!isValidPair does not hold for (a,b)");
}
Iterators.get(relation.iterator(), a).add(b);
}
Edit : without Guava:
Iterator<Set<Integer>> iterator = relation.iterator();
for(int i = 0; i < a && iterator.hasNext(); ++i) {
iterator.next();
}
if(iterator.hasNext()) {
iterator.next().add(b);
}

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.

Categories