简体   繁体   中英

Abstract Data Types, sorting objects by specific variable in a list

Alright here we go.

I made an ADT in form of a sortedArrayList, which has an add method looking like this:

public boolean addToArray(T i)
    {


            int insertPlace = 0;

                for(int j=0;j<size;j++)
                { 

                    if(i.compareTo(sortedArray[j])<0)
                    {
                        insertPlace =j;
                        j = size;
                    }
                }
                if(size>0)
                {


                        for(int w=size-1; w>=insertPlace;w--)
                        {
                                sortedArray[size]=sortedArray[w];
                        }
                        sortedArray[insertPlace]=i;
                }
                else
                {
                    sortedArray[0]=i;
                }
                size++;



        return true;    


}

Now, this works wonders for my sorted ADT when the input is Strings. However, instead of strings, I want to add objects to the list in shape of Persons, an object containing 4 variables(String Country, String name, int age, int CPR). I want the Person objects to be sorted in the list by age.

Here is the Person class with the compareTo method for sorting.

public class Person implements Comparable<Person>
{
    int cpr=200193;
    int age=21;
    String name="John Doe";
    String Country="Uzbekistan";


    public Person() {
        this.cpr=cpr;
        this.age=age;
    }
    public Person(String name, String Country,int cpr,int age) 
    {
        this.cpr=cpr;
        this.age=age;
        this.name=name;
        this.Country=Country;
    }


    @Override
    public String toString()
    {
        return "Person [Country= " + Country + ", Name:" + name + ", Cpr: "+cpr+ ", age: "+age+"]";
    }

    public int compareTo(Person p)
    {
        int before=-1;
        int after=1;
        int middle=0;


        if(this.age!=p.age)
        {
            if(this.age>p.age) 
            {
                return before;
            } 

            if(this.age<p.age)
            {
                return after;
            }
        }
        return middle;
    }

Now, the problem is that the objects get sorted, since do not appear in the same order I call them to the list. I just can't figure out how they are sorted and how to make the objects sorted by age in the list.

EDIT

p1.addToArray(new Person());
p1.addToArray(new Person("Pete","Germany",111111,86));
p1.addToArray(new Person("John","Denmark",123456,75));
p1.addToArray(new Person("Michael Jackson", "America",112345,49));

Output:

Item: Person [Country= America, Name:Michael Jackson, Cpr: 112345, age: 49]
Item: Person [Country= Uzbekistan, Name:John Doe, Cpr: 200193, age: 21]
Item: Person [Country= Germany, Name:Pete, Cpr: 111111, age: 86]
Item: Person [Country= Denmark, Name:John, Cpr: 123456, age: 75]

I don't think your sorting function works:

My test:

static void test() {
    addToArray("Zello");
    addToArray("Boby");
    addToArray("Amy");
    addToArray("Coco");
    addToArray("Boris");
    for(int i = 0; i < size; i++) {
        System.out.println(sortedArray[i]);
    }
}

Output:

Amy
Boris
Boby
Zello
Coco

Here is a different and more efficient way to do it.

Use Arrays.binarySearch() to find the proper insertion position. Mind you, this function returns:

  • the index of the value if it already exists.
  • the -(insertPosition - 1) if the value doesn't exist.

I assume based on your code that the size variable represents the index of the last element in the array. That means you probably initialize it to -1 when the array is empty.

Furthermore, I think you don't allow duplicates and that each Person will be unique so my solution returns false when you try to insert a duplicate.

Of course, make sure you resize the array after certain criterium is matched (usually when array is half full).

public boolean addToArray(T item) {

    if (item == null) {
        return false;
    } else if (size == -1) {
        size++;
        sortedArray[size] = item;
        return true;
    } else {

        // find the correct insertion point using Binary Search
        int insertionPoint = Arrays
                .binarySearch(sortedArray, 0, size+1, item);

        if (insertionPoint >= 0) {
            // duplicate value
            return false;
        }

        // set the insertionPoint to proper value
        insertionPoint = (-(insertionPoint) - 1);

        // shift elements to the right of insertionPoint
        for (int i = size + 1; i > insertionPoint; i--) {
            sortedArray[i] = sortedArray[i - 1];
        }

        // insert at insertionPoint
        sortedArray[insertionPoint] = item;

        // update size
        size++;

        return true; //success
    }
}

Also, you can further simplify your compareTo( ) method in the Person object.

public int compareTo(Person p) {
    if(p != null) {
            return p.age - this.age;
    } else throw new NullPointerException();
}

Right now, sorting is descending. If you want to make it ascending, change:

return p.age - this.age;

To:

return this.age - p.age;

Here is a full running example

Example Output (with ascending sort):

Person [Country= Uzbekistan, Name:John Doe, Cpr: 200193, age: 21]
Person [Country= America, Name:Michael Jackson, Cpr: 112345, age: 49]
Person [Country= Denmark, Name:John, Cpr: 123456, age: 75]
Person [Country= Germany, Name:Pete, Cpr: 111111, age: 86]

To sort your ArrayList you can use the class collections where you need to sort it import java.util.Collections; Collections.sort(yourArrayList); import java.util.Collections; Collections.sort(yourArrayList);

The method sort need the method compareTo in the class Person that you already have implemented.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM