JL9
JL9

Reputation: 543

Using a Comparable to sort ArrayList

Trying to use a Comparable, I'm fairly new to programming and have never sorted an ArrayList. I've looked at some other examples on stack overflow and looked at the Java Doc but it's rather confusing, I'm unsure how to apply it to my program

Essentially I have two classes, a Personality class and a PersonalityList class. The PersonalityList class includes an array of Personality called personalities, which stores numerous personality objects in the Array List.

I need to sort it by the number of votes each Personality has. The method top(int topValue) should return a new array of length topValue, with Personality objects with the highest votes.

I understand I need to use some Comparable in my Personality class, but not to sure on how to do this.

This is my PersonalityList class so far:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collections;

public class PersonalityList
{
    private ArrayList<Personality> personalities; //Create ArrayList of Personality, called personalities.
    private ArrayList<Personality> sortedPersonalities;

    /**
     * Constructor for objects of class PersonalityList
     */
    public PersonalityList()
    {
      personalities = new ArrayList<Personality>(); //Initialise personalities ArrayList.
      sortedPersonalities = new ArrayList<Personality>();
    }

    /**
     * Adds a personality to the ArrayList of Personality, called personalities. 
     */
    public void addPersonality(Personality personality)
    {
       personalities.add(personality);
    }

    /**
     * Returns the number of Personality objects in the ArrayList
     */
    public int getSize()
    {
       return personalities.size(); 
    }

    /**
     * Lists the details of all the Personality objects stored in the ArrayList
     */
    public void list()
    {
       System.out.println("Personality List");

       for(Personality personality : personalities) { //Iterates through each personality in ArrayList
           System.out.println(personality.getDetails()); 
       }

       System.out.println();
    }

     /**
     * Adds one vote to the personality which matches the name entered into the method
     */
    public void voteFor(String name)
    {
         boolean nameFound = false; //Boolean variable to identify if the personality has been found
         int index = 0;

         while (index < personalities.size() && !nameFound) {
             Personality personality = personalities.get(index);
             String compName = personality.getName();

             if (compName.equals(name)) { //Adds a vote if the name is found
                 personality.increaseVotes(1);
                 nameFound = true;
             } 

             index++;
         }

         if (nameFound == false) { //Error message if name not found
             System.out.println(name + " could not be found.");
         }
    }

    /**
     * Removes personalities if they have less votes than the parameter value
     */
    public void shortlist(int minimumVotes) 
    {
        Iterator<Personality> it = personalities.iterator();

        while(it.hasNext()) {
            Personality personality = it.next();
            int currentP = personality.getVotes();

            if (currentP < minimumVotes) { 
                 it.remove();
            }
        }
    }



    /**
     * 
     */
    public Personality top(int topValue)
    {
        int index = 0;
        int listSize = personalities.size();

        if (topValue > listSize) {
            topValue = listSize;
        }

        if(listSize > 0) {

            //Coppies the ArrayList personalities to the sortedPersonalities ArrayList
            while(index < topValue) {
                Personality sortedPersonality = personalities.get(index);
                sortedPersonalities.add(sortedPersonality);
                System.out.println(sortedPersonality.getDetails());
                index++;
            }

            Collections.sort(sortedPersonalities, Collections.reverseOrder(new Personality.votesComparator()));
            System.out.println("Sorted by Votes");
            System.out.println("\t" + people);
        } 
        else {
            System.out.println("No personalities are currently in the Array List");
        }

        return sortedPersonalities ;
    }
}

Thanks in advance.

Upvotes: 3

Views: 852

Answers (3)

Madushan Perera
Madushan Perera

Reputation: 2598

Or you can easily perform comparison between object using lambda expressions like below :

Assume that we have a list of Person with their ages;

       List<Person> peopleList =new ArrayList<Person>();
        peopleList.add(new Person("Ann", 23));
        peopleList.add(new Person("Sam", 22));
        peopleList.add(new Person("John", 20));
        peopleList.add(new Person("Watson", 23));
        peopleList.add(new Person("Samuels", 31));
        peopleList.add(new Person("Peter",41));
        peopleList.add(new Person("Harry", 28));
        peopleList.add(new Person("Carter", 19));
        peopleList.add(new Person("Lilly", 26));
        peopleList.add(new Person("Kumar", 12));
        peopleList.add(new Person("Insaf", 51));

We can compare these people using their ages with Comparator interface

Comparator<Person> personComparatorByAgeUsingStream =(Person b1,Person b2)->{return ((Integer)b1.getAge()).compareTo((Integer)b2.getAge());};   

Then we can sort these people into a List :

List<Person> streamSort= peopleList
                        .stream()
            .sorted(personComparatorByAgeUsingStream).collect(Collectors.toList());

 streamSort.forEach(x->{System.out.println(x.getName()+" is "+x.getAge()+" years old.");});

Upvotes: 1

Grim
Grim

Reputation: 2040

A list can contain a element twice. In this case, who would be the first and who the second? The answer is vague so they decide to not have a list sorted via a comparator.

Maybe you are looking for the TreeSet (who have a natural support of comperable)? A Set can not contain an element multiple times.

You may say: Hey, i realy often have collections without the need of duplicates but i always use lists!. Yes, this is a widely-spread mistake.

Please use Set to let the world know: no duplicates.

Upvotes: 0

camickr
camickr

Reputation: 324197

Here is my attempt to show a complete example of creating a Comparator for a custom Object:

/*
**  Use the Collections API to sort a List for you.
**
**  When your class has a "natural" sort order you can implement
**  the Comparable interface.
**
**  You can use an alternate sort order when you implement
**  a Comparator for your class.
*/
import java.util.*;

public class Person implements Comparable<Person>
{
    String name;
    int age;

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

    public String getName()
    {
        return name;
    }

    public int getAge()
    {
        return age;
    }

    public String toString()
    {
        return name + " : " + age;
    }

    /*
    **  Implement the natural order for this class
    */
    public int compareTo(Person p)
    {
        return getName().compareTo(p.getName());
    }

    static class AgeComparator implements Comparator<Person>
    {
        public int compare(Person p1, Person p2)
        {
            return p1.getAge() - p2.getAge();
        }
    }

    public static void main(String[] args)
    {
        List<Person> people = new ArrayList<Person>();
        people.add( new Person("Homer", 38) );
        people.add( new Person("Marge", 35) );
        people.add( new Person("Bart", 15) );
        people.add( new Person("Lisa", 13) );

        // Sort by natural order

        Collections.sort(people);
        System.out.println("Sort by Natural order");
        System.out.println("\t" + people);

        // Sort by reverse natural order

        Collections.sort(people, Collections.reverseOrder());
        System.out.println("Sort by reverse natural order");
        System.out.println("\t" + people);

        //  Use a Comparator to sort by age

        Collections.sort(people, new Person.AgeComparator());
        System.out.println("Sort using Age Comparator");
        System.out.println("\t" + people);

        //  Use a Comparator to sort by descending age

        Collections.sort(people, Collections.reverseOrder(new Person.AgeComparator()));
        System.out.println("Sort using Reverse Age Comparator");
        System.out.println("\t" + people);
    }
}

Upvotes: 1

Related Questions