This site requires JavaScript, please enable it in your browser!
Greenfoot back
Asiantree
Asiantree wrote ...

2017/4/28

Help with sorting an array of objects

1
2
Asiantree Asiantree

2017/4/28

#
Hello. I am in need of assistance for sorting an array of objects. I have two variables called "BallInfo infos" which holds the objects inside an array of BallInfo, and a another variable called "numOfInfos" that keeps track of the actual amount of objects inside the array:
1
2
infos = new BallInfo[43];
        numOfInfos = 0;
So I am unsure why I am getting a NullPointerException for the following code below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void sortByTotal()
    {
        boolean notSorted = true;
        while (notSorted)
        {
            notSorted = false;
            for (int index=0; index<numOfInfos; index++)
            {
                if (infos[index].getTotal() < infos[index+1].getTotal()) //I get the error on this line of code
                {
                    swap(index, index+1);
                    notSorted = true;
                }
            }
        }
    }
danpost danpost

2017/4/29

#
The only thing that would cause a NullPointerExcception on that line is if 'infos' is not referencing an array or if an element you are trying to access does not refer to any BallInfo object. I would guess the second case is actually what is happening (especially considering that the BallInfo object in the last element containing a reference cannot be sorted with the next element).
Asiantree Asiantree

2017/4/29

#
What do you suggest I do? I feel as though I am quite close to solving this problem but I am not quite understanding something clearly.
danpost danpost

2017/4/29

#
You cannot just set the limit of 'index' on line 7 to less than 'numOfInfos-1' because then the last element will not be sorted with the rest. The algorithm you are using is a bit slow -- you would have to iterate through the list multiple times before the sort is complete. A better way is to start with the second element, and for each element as you iterate through them, move it as far to the front as needed. Once the last element is moved up into its position, the sort is complete. It would look like this:
1
2
3
4
5
6
7
8
public void sortByTotal()
{
    for (int index=1; index<numOfInfos; index++)
    {
        int n = index;
        while (n > 0 && infos[n].getTotal() > infos[n-1].getTotal()) swap(n, --n);
    }
}
Asiantree Asiantree

2017/4/29

#
Yes, that seemed to have allowed the button toggling to work. But, as for the BallInfo objects, they have not switched themselves. Here is my buttonSub class where all of the toggling acts will be used:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ButtonSub extends ToggleButton
{
    public ButtonSub(String text1, String text2)
    {
        super(text1, text2);
    }
     
    public void handle()
    {
        World w = getWorld();
        MyWorld mw = (MyWorld) getWorld();
        mw.sortByTotal(); //by default, the BallInfo objects should be sorted by total amount spawned in
        if( "Sorting by Caught (ASC)" == getText()) //the getText method is found in the ToggleButton class and gets the current text of the button
            mw.sortByCaught(); //if the text of the button says "Sorting By Caught" then the BallInfo objects should be arranged as such, given the code above, the objects do not switch
        if( "Sorting by Total (DESC)" == getText())
            mw.sortByTotal(); //likewise for when the text says "Sorting by Total"
         
    }
}
Also, here is my "swap" method that is used inside the "sortByTotal" and "sortByCaught" methods:
1
2
3
4
5
6
private void swap (int index1, int index2)
    {
        BallInfo temp = infos[index1];
        infos[index1] = infos[index2];
        infos[index2] = temp;
    }
danpost danpost

2017/4/29

#
The swap method given only rearranges the order of elements within the array. It will have no effect on the locations of the BallInffo objects with respect to one another. However, after the array is sorted, you can use the new order to set the locations of the BallInfo objects in your world to the order they appear in the array.
Asiantree Asiantree

2017/4/29

#
Ah, right. That would make sense. Would that line(s) of code go right after "swap" is being called in the "sortByTotal" method? And would it look something like this?
1
addObject(infos[n], x value, y value)
Or something along those lines where would be the first sorted object and so on?
danpost danpost

2017/4/29

#
Asiantree wrote...
Ah, right. That would make sense. Would that line(s) of code go right after "swap" is being called in the "sortByTotal" method? And would it look something like this?
1
addObject(infos[n], x value, y value)
Or something along those lines where would be the first sorted object and so on?
The BallInfo objects are already in the world -- you just need to re-locate them in the order determined by the newly sorted array.
Asiantree Asiantree

2017/4/29

#
I don't believe Greenfoot has a relocation method. Though, I am assuming I am to make a line of code that does the relocation. So, if I am not making a new object based on the sorted array, how can I relocate an existing object that has been sorted? Will the "setLocation" method work for that task, though how do I acquire the X and Y values for each of the objects inside the array if that is the case? Perhaps something like this?
1
setLocation(infos[n].getX(), infos[n].getY());
danpost danpost

2017/4/29

#
Yes, the setLocation method is what you need to use. However, the current locations of the objects is no longer relevant as you will be given them all new locations based on the new sorted order. You would use values similar to what you used when you added them into the world.
Asiantree Asiantree

2017/4/29

#
Why do I get an error for this line of code
1
setLocation(85, Y);
saying "cannot find symbol - method setLocation(int,int)?" Also, Y = 35 and is established before the while loop and gets 12 added to it in order to line them up smoothly. Those are the same values (x and y) I have used to spawn in the unsorted BallInfo objects before toggling the button. Here is the while loop:
1
2
3
4
5
6
while (n > 0 && infos[n].getCaught() > infos[n-1].getCaught())
           {
               swap(n, --n);
               setLocation(85, Y);
               Y += 12;
           }
danpost danpost

2017/4/30

#
You could insert code to swap the positions of the swapped object at line 4; but better would be just to relocate all the BallInfo objects after the sorting of the array is complete. BTW, the error is due to you not specifying what object you wish to set the location of.
Asiantree Asiantree

2017/4/30

#
So I have figured out the problem and have fixed it. Now for the sorting of the caught amount. I am to sort the amount caught from lowest to highest, top to bottom. Would I just flip everything in the sortByTotal method to accomplish that task?
danpost danpost

2017/4/30

#
Asiantree wrote...
So I have figured out the problem and have fixed it. Now for the sorting of the caught amount. I am to sort the amount caught from lowest to highest, top to bottom. Would I just flip everything in the sortByTotal method to accomplish that task?
The only thing you need to change is the condition for swapping elements of the array.
Asiantree Asiantree

2017/4/30

#
Something like this?
1
2
3
4
5
6
7
8
9
10
for (int index=infos.length; index>numOfInfos; index--)
        {
            int n = index;
            while (n < 0 && infos[n+1].getCaught() < infos[n].getCaught())
            {
                swap(++n, n);
            }
            infos[n].setLocation(85, Y);
            Y += 12;
        }
There are more replies on the next page.
1
2